LoginSignup
17
13

More than 5 years have passed since last update.

Lambda@Edgeを使えば、CloudFrontでの配信にカスタムヘッダーを付与できる話

Last updated at Posted at 2018-03-17

今まで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 に更新したいとき

cloudfront-events-that-trigger-lambda-functions.png
(引用 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を入れます。

スクリーンショット 2018-03-18 0.11.54.png

記入したら、関数の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

17
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
13