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

AWSのコスト異常検出を設定する

意図しない課金を防ぐためにとりあえず設定しておくと良さそう

AWS SESでメールを受信してGmailに転送する

独自ドメインメールの送受信ができるようになった

MFA必須のスイッチロールアカウントでaws cliを使う

switch role用のprofileを追加する

CloudWatch Eventsで日本時刻(JST)の月初に実行したい

Lオプションの存在を知った

Lambdaでaws cli configureを設定できるようにする

AWS_CONFIG_FILE=/tmp/.aws/configを設定した

direnvでMFA必須のスイッチロールアカウントのAWS_ACCESS_KEY_IDを設定する

direnv allowを実行する際にMFA認証コードを入力するようにした