CloudFrontでLambda@Edgeを一年間運用しまして、気づいた注意点についてお話しします。
Lambdaはus-east-1(Virginia)リージョンに作る
Lambda@EdgeとしてCloudFrontに紐づけるためにはus-east-1リージョンに作る必要があります。
ただし、us-east-1に作ったとしても各リージョンに関数の複製が作成されるため、日本からアクセスした場合にも遅くなるということはありません。
各CloudFrontイベントに対して、設定できるLambda関数は1つだけ
Lambda@Edgeを設定できるCloudFrontは下記の4つがあります
- ビューワーリクエスト
- オリジンリクエスト
- オリジンレスポンス
- ビューワーレスポンス
これについてはAWSの公式のドキュメントにわかりやすい図があります。
各イベントに設定できるLambda関数はそれぞれ1つだけですので、複数の処理を行いたい場合は、1つの関数にまとめる必要があります。
Lambda関数のエラー処理をしっかり行う
例えば、下記のようなLambda関数を作って、User-Agentに文字列を追加するとします。
exports.handler = function(event, context, callback) { var request = event.Records[0].cf.request; var user_agent = request.headers["user-agent"][0].value + " test string"; request.headers["user-agent"] = [{"key": "User-Agent", "value":user_agent}]; callback(null, request); };
その場合、User-Agentがついていないリクエストが送られた場合、request.headers[“user-agent”]がundefinedとなり、ユーザーには500エラーが返されてしまいます。
私は実際に本番運用してからそのようなケースに気づきCloudFrontのアクセスログを確認したところx-edge-result-typeの項目にLambdaErrorと記録されていました。
User-Agentはほとんどのリクエストでついているため、そのようなケースは想定していなかったのですが、HTTP/1.1のRFCではUser-Agentヘッダーは必須となっていませんでした。
そのような場合は、下記のように関数を変更することで、エラーが起きないようにすることができます。
exports.handler = function(event, context, callback) { var request = event.Records[0].cf.request; if (request.headers["user-agent"]) { var user_agent = request.headers["user-agent"][0].value + " test string"; } else { var user_agent = "test string"; } request.headers["user-agent"] = [{"key": "User-Agent", "value":user_agent}]; callback(null, request); };
Lambdaの同時実行数の制限に気をつける
AWSアカウントにつき1000が同時実行数の制限があります。こちらはサポートに申請することで上限の緩和ができます。