今から始めるLambda③「Layersを使う」
はじめに
前回の記事ではLambdaのローカルでの実行やAWS CLIからのデプロイ方法について紹介しました。
その中でnode_modulesを絡めたコードをデプロイすることにも言及しました。
今回はそのあたりを掘り下げつつ、Lambda Layersの扱い方を紹介していきたいと思います。
AWS Lambda Layersとは
公式には以下のような説明があります。
Lambda レイヤーは、追加のコードやデータを含めることができる .zip ファイルアーカイブです。
要するにLambdaの関数本体とは別に用意することができるコード、データのことです。
どういう時に使うのか
主には異なるLambda関数間で、同じ処理を使いたい場合に利用します。
例えば自作関数のfuncHogeをLambda関数であるlambdaFunc1とlambdaFunc2の両方で使いたい場合、funcHogeをLambda Layersにすることで共有することができます。
自作関数でなくとも、node_modulesの中のライブラリのように、Lambdaを横断して使いたいものがある場合はLayersに含めます。
Layersの作成
lambda-layer-sampleというディレクトリを作成し、Axiosを用いて郵便番号から住所検索を行うコードを作成します。
その際にnode_modulesやpackage.jsonなどを含めたコード群はnodejs、自作のコードはlibという階層を作ってまとめます。
mkdir lambda-layer-sample
cd lambda-layer-sample
mkdir nodejs
cd nodejs
nodejs配下でaxiosをnpm installします。
npm install axios
さらにaxiosを使って郵便番号検索を行うコードを作成します。
名前はgetAddressFromZipCode.jsとします。
注意点として、作成する階層はlib以下とします。
const axios = require("axios");
module.exports = async (zipcode) => {
try {
return await axios(`https://api.zipaddress.net/?zipcode=${zipcode}`);
} catch (e) {
throw e;
}
};
ここまでできたらZIPファイルに固めます。
注意点としては、固めるのはnodejsディレクトリごとなので、lambda-layer-sample配下で以下コマンドを実行します。
zip -r9 layer.zip .
これでlayer.zipがlambda-layer-sample直下に作成されました。
Layersのデプロイ
早速デプロイしていきます。
デプロイはpublish-layer-versionで行います。
ランタイムやレイヤー名などをオプションで指定した上で実行します。
aws lambda publish-layer-version --layer-name sample-layer --description "create layer" --zip-file fileb://layer.zip --compatible-runtimes nodejs10.x nodejs12.x nodejs14.x
レスポンスとしてJSONが返り、AWSのLambdaのコンソールから【レイヤー】を選択すると、以下のように反映されていることが分かります。

LayersをLambdaに紐づける
さっそくLayersとLambdaの紐付けを行いたいと思います。
今回はtestFunction3という名称でLambdaは作成済みとします。
中身は以下とします。
const getAddressFromZipCode = require("getAddressFromZipCode");
exports.handler = async function (event, context) {
const res = await getAddressFromZipCode(9071801);
console.log(res);
return context.logStreamName;
};
先ほど作成したgetAddressFromZipCodeをrequireしていますが、当然このLambda単体では動作しません。
先のLayersと紐づけて初めて動作するLambdaです。
LayersのARNを確認
紐付けを行うにあたってLayersのARNを確認する必要があります。
確認は以下コマンドで行います。
aws lambda list-layer-versions --layer-name sample-layer --query "LayerVersions[*].LayerVersionArn"
Layersはpublish-layer-versionを行う度にバージョンが上がっていきますが、このコマンドで全てのバージョンのARNが確認できます。
紐付け
では紐付けを行いましょう。
紐付けはlambda update-function-configurationで行います。
オプションで先のLayersのARNの値などを付けます。
aws lambda update-function-configuration --function-name testFunction3 --layers "【LayersのARN】"
確認
AWSのコンソールからtestFunction3を実行してみましょう。
紐付け前はgetAddressFromZipCodeが見つからなくて動作しなかった関数が正常に動作するようになったかと思います。
補足:なぜ/libなのか
Layersを作成した際に、自作のスクリプトをnodejs/libの中に含めました。
実はそれには意味があり、AWSにおけるLambdaとLayersの紐付け方が挙げられます。
実はLambdaと紐付けたLayersは、すべて/optというディレクトリ配下に格納されています。
AWS側で、この/opt以下の特定のパスを環境変数として持っています(以下リンク参照)。
その中にnodejs/node_modulesがあります。
ここへのパスが通っているため、Lamdaの関数からLayersで使用しているモジュールが参照できます。
さらに注目すべきはlibにもパスが通っている点です。
実運用的にはソース管理を行うかと思いますが、その際にnode_modulesはignoreされてしまうケースがほとんどです。
なので自作分のコードに関してはlibに配置した上で使用しています。
まとめ
今回はLayersとLambdaの関数の紐付けについて紹介しました。
API GatewayやDBのトリガーと絡めたり、一通りの処理をLambdaで作ると、依存するライブラリの数もそれなりに多くなります。
それらを包括的に管理する意味でもLayersは非常に便利な機能なので、ぜひマスターしておきましょう。
今回の内容が役立てば幸いです。
Discussion