CDKで作ったLambda@Edgeのコードに環境変数を渡せるようにする

CDKでaws-lambda-nodejsを使うと、Lambdaのコードをtypescriptのまま書けるようになる。

内部ではParcelを使ってコンパイルしてくれているらしい。

自分でコンパイル環境を用意する必要がないのでとても手軽ではあるが、aws-lambda-nodejsを使ってLambda@Edge用のコードを書いた際に環境変数周りの設定でハマったのでメモを残しておく。

そもそもとして、Lambda 関数の要件と制限にあるように、Lambda@Edgeでは環境変数が利用できない。

ただ、どうしてもCDK側で指定した環境変数を使いたかったので対応できるようにした。

NodejsFunctionには containerEnvironment parcelEnvironment というコンパイル時に環境変数を付与できるプロパティが用意されているのでこれを使う。(aws-cdk@1.48.0以降はparcelEnvironmentに置き換わった)

const viewerRequestLambda = new NodejsFunction(
  this,
  'SampleViewerRequest',
  {
    functionName: 'SampleLambda',
    entry: 'lambda/handlers/path',
    runtime: lambda.Runtime.NODEJS_12_X,
    timeout: cdk.Duration.seconds(30),
    parcelEnvironment: {
      NODE_ENV: 'production',
      SAMPLE_ENV: process.env.SAMPLE_ENV || '',
    },
  }
)

ただ、このままだとコンパイル後のLambda@Edgeのコードでもprocess.env.SAMPLE_ENVはそのまま出力されてしまうためうまく動作しない。

そこでLambda@Edgeのコードと同じ階層(lambda/handlers/path)に↓の.babelrcを設置する。

{
  "presets": ["@babel/preset-env", "@babel/preset-typescript"],
  "plugins": ["transform-inline-environment-variables"]
}

ライブラリをインストール。

yarn add -D @babel/preset-typescript babel-plugin-transform-inline-environment-variables

これでコンパイル時に環境変数の値をインラインで展開してくれるようになるので、Lambda@Edgeでも環境変数の値を利用できるようになる。

参考