Lambda container images で New Relic の Lambda Layer を使う
前提
New Relic で Lambda の APM を使うには、以下ドキュメントの通り Lambda Extensions(Layer) を使う必要があります
しかし、Lambda container images では Lambda Layer の機能を使うことができません
解決策として、以下 AWS ブログに記載がある通り、Lambda Layer で動作させるスクリプトファイルを Container image 内に配置する必要があります
CDK を使って New Relic の Lambda Layer を有効にした Nodejs runtime の Lambda をデプロイする方法
ディレクトリ構成
CDK のディレクトリ構成はかなり簡略化しますが、以下のような内容になります
.
├── Lambda
│ ├── Dockerfile
│ ├── index.js
│ ├── layer
│ │ └── newrelic.zip
│ ├── node_modules
│ ├── package-lock.json
│ └── package.json
├── bin
│ └── cdk-bot.ts
├── lib
│ └── cdk-stack.ts
└── node_modules
今回は Lambda ディレクトリ配下に、Lambda で利用するスクリプトファイルと Container image 用の Dockerfile を配置します
また、layer ディレクトリを作成し、その中に New Relic の Lambda Layer で利用されるアプリケーションを zip ファイルに固めて配置しました
なお、New Relic の Lambda Layer で利用されるアプリケーションは上述の AWS ブログを参考に以下のコマンドを利用して zip ファイルにしており、New Relic の Lambda Layer の ARN は https://layers.newrelic-external.com/ のサイトにて確認します
curl $(aws lambda get-layer-version-by-arn --arn arn:aws:lambda:ap-northeast-1:451483290750:layer:NewRelicNodeJS14X:21 --query 'Content.Location' --output text) --output newrelic.zip
Lambda
Lambda はシンプルに index.js を利用します
Dockerfile
index.js や package*.json は cp でディレクトリにコピーします
また、New Relic の Lambda Layer として利用する newrelic.zip は、AWS ブログを参考にコピーして /opt ディレクトリ配下に解凍して配置します
FROM amazon/aws-lambda-nodejs:14
RUN yum install -y unzip
COPY index.js package*.json layer/newrelic.zip ./
RUN npm install
RUN mkdir -p /opt
RUN unzip newrelic.zip -d /opt
RUN rm newrelic.zip
CMD [ "newrelic-lambda-wrapper.handler" ]
なお、handler は New Relic のドキュメントに記載がある通り newrelic-lambda-wrapper.handler
とします
Update your function's handler to point to the newly attached layer in the console for your function:
~ SNIP ~
Node: newrelic-lambda-wrapper.handler (hyphens)
CDK
CDK で Lambda container images のデプロイを行うには、DockerImageFunction クラスが利用できます
fromImageAsset で Lambda 用の Dockerfile があるディレクトリを指定します
const nodejsFunction = new lambda.DockerImageFunction(this, "nodejsFunction", {
code: lambda.DockerImageCode.fromImageAsset("Lambda"),
memorySize: 128,
logRetention: logs.RetentionDays.ONE_WEEK,
environment: {
NEW_RELIC_LAMBDA_EXTENSION_ENABLED: 'true',
NEW_RELIC_LAMBDA_HANDLER: 'index.handler',
NEW_RELIC_ACCOUNT_ID: 'xxxxx'
},
});
あとはいつもどおり CDK をデプロイすれば New Relic の Lambda Layer で利用するアプリケーションが内包された Lambda container images がデプロイされます
Discussion