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

公開日時
更新日時

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

内部ではParcelを使ってコンパイルしてくれているらしい。
aws-cdk@1.75.0でビルドシステムがparcelからesbuildに置き換わった。

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

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

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

aws-cdk@1.75.0以降の対応方法

※ aws-lambda-nodejsはEXPERIMENTALなので今後もバージョンアップで変わる可能性が高い。

esbuild Defineを利用するとビルド時に文字列を置換してくれるのでこれを利用する。

const viewerRequestLambda = new NodejsFunction(
  this,
  'SampleViewerRequest',
  {
    functionName: 'SampleLambda',
    entry: 'lambda/handlers/path',
    runtime: lambda.Runtime.NODEJS_12_X,
    timeout: cdk.Duration.seconds(30),
    bundling: {
      sourceMap: true,
      define: {
        'process.env.SAMPLE_ENV': `\\"${process.env.SAMPLE_ENV || ''}\\"`,
      },
    },
  }
)

aws-lambda-nodejsドキュメントには process.env.API_KEY: JSON.stringify('xxx-xxxx-xxx') のように指定する方法が書かれていたが↓のエラーになったのでエスケープ処理(\\")を追加した。

> error: Invalid define value (must be valid JSON syntax or a single identifier):

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

aws-cdk@1.74.0以前の対応方法

古い対応方法も一応残しておく。

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

参考


Related #aws

RDSを定期的に停止するLambdaを作る

手動起動は大変なので

AWS SESの受信メールを暗号化してs3に保存しLambdaで読み込む

jsの場合、複合処理を独自実装する必要がある

CloudWatchアラームを一時的に無効化する

AWS CLIで設定する必要がある

Alexaに気温と二酸化炭素濃度を教えてもらう

「Alexa、気温」でセンサー情報を教えてくれるようになった

CloudWatchのカスタムメトリクスを減らす

あまりチェックしないセンサー値の送信を止めた