##問題
- ビルドする時のnpm installが重い。
##解決
- 依存モジュールはLayerとして切り出し。
- Lambda関数側は依存モジュールをdevDependenciesに入れてエディタ上はパスを通す
(ビルドするとdevDependenciesはnode_modulesに入らないから、デプロイするLambda関数が肥大化する心配はない)。 - 開発中はキャッシュオプションをつけてLayerのビルドは短縮。
sam build HelloWorldFunction -c
##Layerについて
Layerは/opt下に配置されるイメージ。
なのでパスが通っているところにライブラリが置かれれば良い。
例えば、ランタイムがNode.jsの場合は、/opt/nodejs/node_modulesとかにデフォルトでNODE_PATHが通っている。
だから、nodejs/node_modulesにライブラリを落としてLayerとしてデプロイすればよい。
ディレクトリ名がnodejsなのがポイント。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime
SAMの場合は、ローカルディレクトリをLayerとして指定すれば、よしなにビルド、デプロイしてくれる。
##使う側
普通にインポート
const { format } = require("date-fns");
exports.lambdaHandler = async (event, context) => {
try {
const d = format(new Date(2014, 1, 11), "yyyy-MM-dd");
console.log("d=" + d);
エディタ上で参照できるようにdevDependenciesに追加する。
$ npm install date-fns lodash --save-dev
##layer側
ディレクトリ名はデフォルトではnodejsとしないとだめ。
(多分NODE_PATHを自分で設定すれば別)
ライブラリを落とす。
$ mkdir nodejs
$ cd nodejs
$ npm init
$ npm install date-fns lodash
##テンプレート
Layerを定義し、Functionから参照。
ContentUriにローカルディレクトリのパスを記載。
Metadataが無いとLayerをビルドしてくれない。
Importエラーになってハマった。
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-layerversion.html
デフォでやらない理由があるんだろうか。
いろいろカスタマイズはできそう。
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/building-layers.html
MyLayer:
Type: AWS::Serverless::LayerVersion
Properties:
Description: Layer description
ContentUri: "nodejs/"
CompatibleRuntimes:
- nodejs12.x
Metadata:
BuildMethod: nodejs12.x
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs12.x
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Layers:
- !Ref MyLayer
##ビルド
Layerもビルドしている旨表示されます。
$ sam build
##ローカル実行
local Layerのイメージを作りだした。
$ sam local invoke HelloWorldFunction
Invoking app.lambdaHandler (nodejs12.x)
MyLayer is a local Layer in the template
Building image..
Layerに入っているライブラリを使えた。成功。
INFO d=2014-02-11
##キャッシュオプションでビルド
キャッシュがヒットするとこうなる。
$ sam build -c
Starting Build use cache
Valid cache found, ...
Layerは修正しないから、キャッシュがヒットするからライブラリ落とすこともなく早い。
直した関数だけCache is invalidになる。
sam build HelloWorldFunction -c
Cache is invalid, running build
...
Valid cache found, copying previously built resources from layer build
####キャッシュがヒットしない場合
node_modulesを比較するから、キャッシュがヒットしない場合は、
node_modulesをきれいにする。
$ npm prune