Lambdaのレイヤを使って,npm依存ライブラリをファンクションから分離する
Lambdaにはレイヤという機能があり,依存ライブラリなどのデータをファンクション自体から切り離せます.
cf. Creating and sharing Lambda layers - AWS Lambda
この機能を使って,npm依存ライブラリを分離してみました.
環境
$ sw_vers
ProductName: macOS
ProductVersion: 11.6.2
BuildVersion: 20G314
$ node --version
v14.19.0
$ npm --version
6.14.16
コード
moment.jsを使って今日の曜日を出力するファンクションを作りました.
$ npm install moment
print-dow.js
moment = require('moment');
exports.handler = async (event) => {
return {
statusCode: 200,
body: moment().format("[Today is] dddd"),
};
};
レイヤの作成
node.jsの場合,レイヤのzipを以下のような構成にすると,npm依存ライブラリのパスとして認識してくれるようになります.
layer.zip
└ nodejs/node_modules/moment
そこで,上記の構成になるようなzipを作り,レイヤを作成します.
$ mkdir nodejs
$ ln -s ../node_modules nodejs
$ zip -r layer.zip nodejs
$ aws lambda publish-layer-version \
--layer-name npm-moment-layer \
--zip-file fileb://./layer.zip \
--compatible-runtimes nodejs14.x \
--compatible-architectures "x86_64"
レイヤを使うファンクションの作成
ロールの作成
role-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
$ aws iam create-role \
--role-name print-dow-role \
--assume-role-policy-document file://./role-trust-policy.json
$ aws iam attach-role-policy \
--role-name print-dow-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
ファンクションの作成
作ったレイヤを入れて,ファンクションを作成します. ファンクションのzipには依存ライブラリを含めていません.
$ zip function.zip print-dow.js
$ aws lambda create-function \
--function-name print-dow \
--runtime nodejs14.x \
--zip-file fileb://./function.zip \
--handler print-dow.handler \
--role arn:aws:iam::<account_id>:role/print-dow-role \
--layers "arn:aws:lambda:ap-northeast-1:<account_id>:layer:npm-moment-layer:1"
ファンクションの実行
$ aws lambda invoke --function-name print-dow outfile
$ cat outfile
{"statusCode":200,"body":"Today is Sunday"}
ファンクションのzipには依存ライブラリを含んでいませんが,レイヤから依存ライブラリを使っていることが確認できました.