web-dev-qa-db-ja.com

Lambda関数がCloudFrontに無効なリクエストまたはレスポンスを返しました

私はここの指示に従います https://medium.com/@tom.cook/Edge-lambda-cloudfront-custom-headers-3d134a2c18a2

CloudFrontが静的なS3 "hello world" HTMLファイルの前に正常に配置され、ラムダエッジを使用して追加のヘッダーを設定したいのですが、エラーが発生します。本当にイライラするのは、何が問題なのかをデバッグするためのエラーのログが見つからないことです。これはブラウザが表示するものです。

ERROR

The request could not be satisfied.

The Lambda function returned an invalid request or response to CloudFront. 
Generated by cloudfront (CloudFront)
Request ID: 2Cqex7euzH0Iigps58i9tMVxdqAaLznL2ZjwqR1sW1AZHz6x2EwfMA==

これが私の簡単なラムダのコードです:

exports.handler = (event, context, callback) => {
    console.log(event)
    callback(null, 'Hello from Lambda');
};

トリガータイプはviewer-responseとCloudFrontディストリビューションに添付されています(Cache Behavior: *、それが重要な場合)。ラムダには、Cloudwatchへの書き込みアクセス権を付与するAWSLambdaBasicExecutionRoleに対応するロールがあります。

トリガーを有効にするとすぐに、Webリクエストへの応答が「Hello world」HTMLから上記のエラーに変わるため、ラムダをトリガーしていることがわかります。しかし、ラムダダッシュボードでは、呼び出しやエラーは表示されません。 Cloudwatchにログは表示されません。 CloudFrontダッシュボードにエラーが表示されます(5xx)、ただしラムダからのものはありません。

次に、デプロイされた関数をクリックしてラムダコンソール内で関数をテストし、テストイベントを「CloudFront Modify Response Header」として構成し、Testを押すと、成功します。 Cloudwatchはテストのログとコンソール出力を表示します!しかし、まだライブ呼び出しのログには何もありません。

私の唯一の理論は、CloudFrontが実際にラムダを呼び出すことができないというパーミッションの問題です(ラムダダッシュボードに何もない理由を説明しています)。最後に、CloudFrontログ(S3内)には、502エラーとLambdaValidationErrorを含むWebリクエストが表示されますが、それが役立つかどうかはわかりません。

11
lordbyron

あなたが見ているブログ記事の例は、Lambda @ Edgeがまだプレビューされている間は有効でしたが(一般提供開始前の特定の顧客へのアクセスは制限されています)、正しくありません。サービスの開始直前に、データ構造が変更されました。

応答ヘッダーのデータ構造は、以前は次のようになっています。

headers['Strict-Transport-Security'] = "max-age=31536000; includeSubdomains; preload";
headers['Content-Security-Policy']   = "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'";
headers['X-Content-Type-Options']    = "nosniff";

新しい構造は次のようになります。

headers['strict-transport-security'] = [{
    key:   'Strict-Transport-Security', 
    value: "max-age=31536000; includeSubdomains; preload"
}];

headers['content-security-policy'] = [{
    key:   'Content-Security-Policy', 
    value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"
}];

headers['x-content-type-options'] = [{
    key:   'X-Content-Type-Options',
    value: "nosniff"
}];

外部オブジェクトのキーは、内部オブジェクトの各メンバーのkey値に相当する小文字でなければなりません。このデータ構造の変更は、HTTPヘッダーの処理方法をより正確に反映するために最も必要でした。HTTP/ 1.xでは大文字と小文字が区別されないため、JavaScriptオブジェクトではキーの大文字と小文字が区別されるためです。

コードによって返される構造が、CloudFrontがLambda @ Edgeを返すために必要とするものに準拠していない場合、実際に表示されるエラーがスローされます。ログを移動する場所がないため、ログは生成されません。このエラーは、Lambdaの外部、つまりLambdaとCloudFrontの間のインターフェース境界のCloudFront側で発生し、ユーザーがアクセスできるログは生成されません。

応答イベント構造 のドキュメントを参照してください。

9

Lambda @ EdgeおよびCloudFrontには、いくつかの一般的な「落とし穴」があります。必要がある:

  • Lambda関数の新しいバージョンを公開する
  • CloudFront Lambdaの関連付けを新しいバージョンに更新します。 arn:aws:lambda:us-east-1:572007530218:function:gofaas-WebAuthFunction:45
  • リクエスタの領域でLambda @ Edgeログを探します

そして、私が知る限り、メインのLambda関数の「コピー」から「エッジ」に分散された呼び出しに関するメトリックを表示できません。

これは、コード変更を保存し、モニタリングタブからログにジャンプする「通常の」Lambda Webコンソールフローとは異なります。

このボイラープレートアプリ を見てください Lambda @ Edge OAuth and Cookie handler のデプロイを自動化します。これを離れて設定します。

2
Noah Zoschke