AWS SAMを使ってLambdaにLayerを設定する方法
はじめに
AWS SAMでLambdaやdynamoDBを使ったサーバーレスアプリケーションを構築しているといろいろなプロジェクトで共通で使っているコードがでてきたりします。
共通化できるものはさっさと共通化して必要なときに呼び出しができるようになると便利なのでさっそく実践してみました。
AWS LambdaにはLayer機能があり、Lambdaのコードで使いたいライブラリなどを設定する事ができます。
Layerに依存関係のあるコードやライブラリをAWS SAMのプロジェクトとしてまとめて設定する方法を調べてやってみました。
Layerに必要なライブラリをZipでまとめてS3に保存して、AWSコンソールから設定する方法はいくつか見つけましたが、AWS SAMのプロジェクトとしてまとめてdeployする方法がなかなかうまくできなかったので備忘録として書いておきます。
前提条件
AWS SAM CLIのインストールはすでに済んでいるものとして説明します。
今回の説明ではPython3.6を使っています。
ディレクトリ構成
Layerとして使いたいコードやライブラリなどを格納するディレクトリは言語ごとに決められています。
AWS Lambda ライブラリの依存関係をレイヤーに含める
pythonならpython
かpython/lib/python3.6/site-packages
に格納しておかないと下記のような参照エラーが表示されます。
Unable to import module 'app': cannot import name 'layer_code'
sam init
コマンドで作成したSAMプロジェクトにLayerを格納するディレクトリを追加します。
sam-app
├── README.md
├── app
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
├── events
│ └── event.json
├── layer // ここにLayer格納用ディレクトリを追加
│ └── python // 言語名ディレクトリ
│ └── sample
│ └── sample_layer.py // Layerとして使いたいコード
└── template.yaml
template.yamlの書き方
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: hello-world-sample-function
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.6
Layers:
- !Ref LayerSampleLayer # ポイント1
Events:
(省略)
# Layer定義
LayerSampleLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: layer-sample-layer
Description: Hello World Sample Application Resource Layer
ContentUri: layer # ポイント2
template.yamlの書き方のポイントは2つです。
-
Lambda関数定義に
Layers
の項目を追加してLayer定義を参照するように設定する -
Layer定義ではLayerのコードを格納しているフォルダパスを設定する
→正確には言語名ディレクトリの親ディレクトリを設定する
app.pyでのimport
template.yamlでLayer設定をしておくとapp.pyと同一階層にあるものとして使えるようになります。
ただ一度sam build
を行わないと設定は反映されません。
# レイヤーとして追加したファイルを参照する
from sample import sample_layer
def lambda_handler(event, context):
res = sample_layer.hello()
return res
def hello():
return "hello Layer!"