今までLambdaをさわってきたものの、未体験だったLambda@Edgeを使ってみた話です。
2016年のre:Inventで発表されたサービスであり、新しいものではありません。
記事中では、Labda@Edgeに関する情報と、S3においた静的ファイルをCloudFrontで配信している場合に、カスタムヘッダーを付与する方法を事例として紹介してます。
Lambda@Edgeとは
クライアントからCloudFrontにアクセスしたときの、特定のタイミング(後述)でLambda関数を実行できるサービスです。
実行されるタイミング
Lambda関数が実行されるタイミングとしては、
以下の四つがあります。
タイプ | 実行のタイミング | ユースケース例 |
---|---|---|
Viewer Request | CloudFront がEnd userからリクエストを受信した後 | CloudFrontで配信しているサイトにBasic認証をかけたいとき |
Viewer Response | CloudFront がEnd userにレスポンスを転送する前 | CloudFrontで配信している場合に、カスタムヘッダーを付与したいとき |
Origin Request | CloudFront がリクエストをOriginサーバーに転送する前 | CloudFront の特定のパスでアクセスを受けた時に、そのURLを書き換えたいとき |
Origin Response | CloudFront がOriginからレスポンスを受信した後 | Originから返却されたレスポンスがエラーステータスコードで、 それを200-OK に更新したいとき |
(引用 https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-edge.html)
本記事の具体例においてはOrigin serverがS3となります。
制約
制約は結構あります(2018年3月現在)。目立ったところを記述すると
- バージニア北部をリージョンとして使う必要がある。
- 追加できるHTTPのヘッダーに制限がある。
- Lambda関数の実行時間、最大圧縮サイズに制限がある。
- 実行環境としては、Node.js 6.10しかない。
- Originイベント(CloudFrontとOriginサーバ間でのイベント)とViewイベント(End UserとCloudFront間でのイベント)で実行できるリソースの量が異なる。Originイベントのほうが制約が緩い。
- コードからのネットワーク通信不可(DB等にアクセスできない)
使ってみた
状況
S3で静的ファイルを配信している。CloudFrontフロント経由で配信しているが、カスタムヘッダーを付与したい。
これを実現するには以下のステップを踏みます。
- Lambda@Edge用のIAMロールの作成
- Lambda@Edge用のLambda関数作成
- Lambda@EdgeをCloudFrontと紐付ける
作業の前提として
- S3のバケット
- CloudFrontでの配信
の作成/設定はできているものとします。
IAMロールの作成
作成するIAMアクセス権限としては、Lambda 関数を CloudFront ディストリビューションに関連付けるために次の IAM アクセス権限が必要です。
詳細は、
の**「Lambda@Edge 用の IAM アクセス権限とロールの設定」**のセクションを参考にください。
忘れやすい注意点としては、サービスプリンシパル lambda.amazonaws.com と edgelambda.amazonaws.com が引き受けることができる IAM ロールを作成する必要があります。
実作業しては、「Edit Trust Relationship」でlambda.amazonaws.com
, edgelambda.amazonaws.com
を追加します。
Lambda関数作成
カスタムヘッダに、Content Security Policyに関する情報を追加したいとします。コードは以下のようになります。
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
const headers = response.headers;
headers['content-security-policy'] = [{
key: 'Content-Security-Policy',
value: "default-src 'self'"
}];
callback(null, response);
};
コード記述したあとは、バージョニングをする必要があります。Lambda関数の画面上部の「Actions」より「Publish New Version」をクリックすることで可能です。バージョニングしたものに関しては、「Add Triggers」よりCloudFrontが選択可能になります。
CloudFrontと紐付ける
CloudFrontを追加したあとは以下のような画面が出るので、そちらを記入していきます。DistributionにはCloudFront DistributionのIDを入れます。
記入したら、関数のSaveを忘れないようにしましょう。
CloudFrontの方の画面を確認すると、StatusがDeploy中になり、Deployされると、実際にHttp Headerに追加されていることが確認できます。
参考
AWS Lambda@Edge
CloudFront と Lambda@Edge の使用 » 関数の例 <- 自分がyく確認するURL
Amazon CloudFrontとAWS Lambda@EdgeでSPAのBasic認証をやってみる
Lambda@Edge で URLパスを書き換える
Serving custom headers from static sites on CloudFront/S3 with Lambda@Edge