Lambda Layerを使うときのメモ
以前Serverless FrameworkでLambdaLayerを使ってみたがその時はLayer用にディレクトリを切って設定ファイルも関数とは別であとからARNで参照させる感じだった
- ディレクトリ構成
- プロジェクトルート
- Layer用のディレクトリ
- serverless.yml
- 関数用のディレクトリ
- app.js
- serverless.yml
ARNでの参照だとarn:aws:lambda:ap-northeast-1:111111111111:layer:modules:4といったようにバージョンまで指定しないと行けないのでLayer側の中身が変わった場合コチラも手動で編集する必要がある
Serverless Frameworkに下記のようにLayerへの参照だけ指定する方法があるのでそちらを使いたい
- before
functions:
sample:
handler: handler.run
layers:
- arn:aws:lambda:ap-northeast-1:111111111111:layer:modules:4
- after
functions:
sample:
handler: handler.run
layers:
- {Ref: HogeLambdaLayer}
また、1つのプロジェクトでLayerと関数とを1つの設定ファイルで管理したい
という経緯で今回すこし時間をとって調べてみた
なを今回はchrome-aws-lambdaをLayerに切り出す
Layerの仕様と設定
ただ関数を定義してデプロイするのと比べるとLayerの場合
/opt以下に成果物が置かれる- Lambdaが探しに行くパスが決まっている
/opt/nodejs/node_modules、/opt/nodejs/node8/node_modules(NODE_PATH)
という感じになっている
Serverless Frameworkはpathに指定したディレクトリ以下のファイルをそのまま置くようになっているので成果物用のディレクトリを作成してそれに合わせてディレクトリの中身を構成してあげれば良い
dist的なものがあるのかと思って調べてみたがなさそうだった
なのでLayerで指定するpath以下のディレクトリ構成は下記のようになる
- serverless.yml
layers:
puppeteer:
path: puppeteer_layer_dist/
$ pwd
project_name
$ tree puppeteer_layer_dist
puppeteer_layer_dist
`-- nodejs
`-- node_modules
`-- chrome-aws-lambda -> ../../../node_modules/chrome-aws-lambda/
chrome-aws-lambdaからnode_modulesへはシンボリックリンクを貼っている
mkdir -p puppeteer_layer_dist/nodejs/node_modules cd puppeteer_layer_dist/nodejs/node_modules ln -s ../../../node_modules/chrome-aws-lambda/ chrome-aws-lambda
これを行うことでローカルでの実行とデプロイしてから実行するパターンの両方に対応できる
Nodeのバージョン
node10が使えるし10にしてやったろ!と試してみたところ下記の様なエラーで実行できなかった
2019-09-15T21:41:49.495Z 9d620ee6-fe56-43a8-af91-fc95f799f7dd ERROR Invoke Error
{
"errorType": "Error",
"errorMessage": "Failed to launch chrome!\n/tmp/chromium: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory\n\n\nTROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md\n",
"stack": [
"Error: Failed to launch chrome!",
"/tmp/chromium: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory",
"",
"",
"TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md",
"",
" at onClose (/var/task/node_modules/puppeteer/lib/Launcher.js:348:14)",
" at Interface.helper.addEventListener (/var/task/node_modules/puppeteer/lib/Launcher.js:337:50)",
" at Interface.emit (events.js:203:15)",
" at Interface.EventEmitter.emit (domain.js:448:20)",
" at Interface.close (readline.js:397:8)",
" at Socket.onend (readline.js:173:10)",
" at Socket.emit (events.js:203:15)",
" at Socket.EventEmitter.emit (domain.js:448:20)",
" at endReadableNT (_stream_readable.js:1145:12)",
" at process._tickCallback (internal/process/next_tick.js:63:19)"
]
}
おそらく上記の問題に引っかかり、現段階だとchrome-aws-lambdaはnode10系だとまだ実行できない模様
このあたり不便だよなーと思いながら仕方なくnode8.10にして実行するようにした
まとめ
Serverless FrameworkでLayerを使ってPuppeteerを動かす際のメモ
- Layer用のディレクトリ構成には気をつける
nodejsが必要
- Layer用のディレクトリに対象のモジュールのシンボリックリンクを貼る
- 運用省力化
chrome-aws-lambdaはnode10だとまだ動かせない(2019-09-17時点)
Lambdaをどんどん使っていきたいと思っているもののなかなかベストプラクティス的なものがないイメージあるので指摘があれば教えていただければ嬉しいです