株式会社オプトの仙台開発拠点でエンジニアをしている @hiroshist です
はじめに
【AWS re:Invent 2018 Serverless re:Cap】に参加し、AWS Lambda Layersを利用することでLambda関数で利用する共有ライブラリを管理できるようになったという事で試してみたいと思いましたので、
今回はNode.jsでLambda関数を作る際に利用しているServerless FrameworkでLambda Layersを作成して見たいと思います。
開発環境
- Windows10
- Visual Studio Code
- Node.js
インストール
折角なので、Serverless Frameworkをインストールする所から始めます
$ npm install -g serverless
$ serverless --version
1.35.0
バージョンを確認すると今回は1.35.0がインストールされました。
サービスを作成
以下のコマンドを実行するとAWS Node.js用のテンプレートがmy-layersというフォルダ配下に作成されます
$ serverless create --template aws-nodejs --path my-layers
Serverless: Successfully generated boilerplate for template: "aws-nodejs"
テンプレートとして以下の3ファイルが作成されている状態になります
.gitignore
handler.js
serverless.yml
モジュールを作成
Lamdba関数で利用する日付を返すモジュールtermを作成します
layer-dir # yamlで指定
nodejs
node_modules
term
index.js
PATHについて
layersのPATHについては言語ごとに指定されているものがあるので詳細は以下のドキュメントを参考にしてみてください。
configuration-layers-path
コード
今回はシンプルに昨日の日付を返す関数を作成します
exports.yesterday = function () {
var now = new Date();
return new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1)
};
yaml
serverless.ymlを更新します
layers:
hello:
path: layer-dir # 上記のモジュール作成時のPATHで指定した名称
name: ${self:provider.stage}-MyLayerName
詳しい書き方は公式サイトを参考にしてみてください。
AWS - Layers
DEPLOY
deployコマンドを実行し、リモートに展開します。
「AWS Lambda - Layers」一覧に今回作成したdev-MyLayerNameが追加されている事が確認できます。
[パッケージのダウンロード]ボタンから今回作成したモジュールをzipでダウンロードする事もできます。
$ serverless deploy
Lamdbaでモジュールを呼び出してみる
handler.js
const term = require('term');
module.exports.hello = async (event, context) => {
return term.yesterday();
}
serverless.yml
functions:
hello:
handler: handler.hello
layers:
- {バージョン ARN}
バージョンARNは
arn:aws:lambda:{region}:{account_id}:layer:${self:provider.stage}-MyLayerName:{version}
のような形になっています。
詳しい書き方は公式サイトを参考にしてみてください。
AWS - Layers
DEPLOY
最後にLambda関数もdeployコマンドを実行し、リモートに展開します。
実行するとLayersに作成したモジュールが呼び出されているが確認できると思います。
さいごに
今回Layersを利用してみた感想です
- よく使うモジュールなどを一括管理でき、共有できるのは便利
- ただし、モジュールをLayersにする事でローカル等の環境をどうするのか課題(個人的はまだ解決策が見えていない)
- 自動的に依存関係は解決して欲しい
- Layers側のバージョン管理が煩雑かも
- deployするたびにバージョンはインクリメントされる
- 頻繁に更新するようなモジュールはLayersで管理すると、呼び出し側の組み込みに工夫が必要そう