Lambda@EdgeをCDKで書いてみる

2 min read読了の目安(約2200字

こんにちは。Web エンジニアの Yuichiro Izumi です。

Lambda@Edge をご存知ですか?
Lambda でできるちょっとした処理を CloudFront をリクエスト時に実行できる機能です。
GA から数年経ち、最近は触れる機会も増えてきたかと思います。

https://aws.amazon.com/jp/lambda/edge/

何が課題だったか?

CloudFront で Lambda@Edge を利用したいときありますよね。
そして、それを CDK で書きたいというときもあると思います。

CloudFront の Lambda@Edge として利用する場合、利用する Lambda は、us-east-1 でリソースを作成する必要があります。

CDK の stack は、リージョンを跨いだリソースの管理ができません。
そのため、Lambda@Edge 用の Lambda のみ us-east-1 で作成し、それ以外のリソースを別リージョンで作成する必要がある場合、それを CDK で愚直に書く場合、2つの stack を作成する必要があります。

そんな時は、cloudfront.experimental.EdgeFunctionを利用すると1つの stack で綺麗に書けました。

実際は、処理の中で新しい stack を us-east-1 に作成してますが、開発者がそれを意識しないようにラップしているのがこの関数の特徴のようです。

https://docs.aws.amazon.com/cdk/api/latest/docs/aws-cloudfront-readme.html#lambdaedge

実装例

cloudfront.experimental.EdgeFunctionを利用して、stack を作成しました。
一部、lambda や cloudfront を作成する際に必要なプロパティは省略しております。
利用した CDK のバージョンは 1.95.1 でした。

/bin/infra.ts
#!/usr/bin/env node
import * as cdk from "@aws-cdk/core";
import { SampleStack } from "../lib/sample-stack";

const app = new cdk.App();

new SampleStack(app, "sample-stack", {
  env: {
    account: "xxxxxxxxxxxx",
    region: "ap-northeast-1",
  },
});
/lib/sample-stack.ts
import * as cloudfront from "@aws-cdk/aws-cloudfront";
import * as lambda from "@aws-cdk/aws-lambda";
import * as cdk from "@aws-cdk/core";

export class SampleStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    // NOTE: "src"は実際にdeployするフォルダパス
    const f = new cloudfront.experimental.EdgeFunction(this, "lambda-edge", {
      code: lambda.Code.fromAsset("src"),
      handler: "index.handler",
      runtime: lambda.Runtime.NODEJS_12_X,
    });
    new cloudfront.CloudFrontWebDistribution(this, "distribution", {
      ...
      originConfigs: [
        {
          behaviors: [
            {
              lambdaFunctionAssociations: [
                {
                  eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
                  lambdaFunction: f.currentVersion,
                },
              ],
            },
          ],
        },
      ],
    });
  }
}

最後に

いかがだったでしょうか?
これで、Lambda@Edge を利用する場合でも、CDK で記載するコードをシンプルに維持できます。

これからも、CDK に関する Tips を発信していけたらと思います。