【CDK/Python】LambdaLayerでコンテナを指定してビルドする方法
こんばんは sisii です。
年末に GoogleAnalytics をざっと見ていたら、地味に LambdaLayer の記事が結構見られていることがわかりました。 この記事、今読んでみるとかなりアップデートが必要な内容でしたので、ちょっとリメイクしようと思います。
前提
LambdaLayer
がどういうものか?というのは飛ばしてコードベースに「こんな感じで実装できるよー」という感じで書いていきます。
では 作っていきましょう 👻
まず cdk のコードです。
import pathlib
import aws_cdk as cdk
from aws_cdk import BundlingOptions, DockerImage
from aws_cdk import aws_lambda as lambda_
app = cdk.App()
stack = cdk.Stack(app, "cdk-lambda-layer-python-stack")
# LambdaLayer(これがメインです)
layer = lambda_.LayerVersion(
stack,
"layer",
code=lambda_.Code.from_asset(
str(pathlib.Path(__file__).resolve().parent.joinpath("runtime/layer")),
bundling=BundlingOptions(
image=DockerImage(image="public.ecr.aws/sam/build-python3.9:latest-x86_64"), # imageを指定してbuild する
# image=lambda_.Runtime.PYTHON_3_9.bundling_image, # これでもOK
user="root",
command=[
"bash",
"-c",
"&&".join(
[
"cp -aur . /asset-output",
"cd /asset-output/python",
"pip install -r requirements.txt -t .",
]
),
],
),
),
compatible_runtimes=[lambda_.Runtime.PYTHON_3_9],
)
# Function(LambdaLayerを利用するサンプルのFunctionです)
lambda_.Function(
stack,
"function",
code=lambda_.Code.from_asset(
str(pathlib.Path(__file__).resolve().parent.joinpath("runtime/function")),
),
runtime=lambda_.Runtime.PYTHON_3_9,
architecture=lambda_.Architecture.X86_64,
handler="index.handler",
layers=[layer],
)
app.synth()
runtime
のディレクトリ構成の説明
今回は下記な構成になっております。
- runtime
- function
- index.py
- layer
- python
- hello.py
- requirements.txt
各要素の説明です。
index.py
は動作確認用の Lambda です。
layer
が LambdaLayer を実装していくディレクトリになります。基本的にこのフォルダをzipにまとめてLambdaLayerとしてデプロイするイメージです。中身をみてみます。python
は python のコードを保存するためのディレクトリです。そのまんまですが、このディレクトリ名は AWS で決まっているので固定です。詳細は公式を参照ください。hello.py
は LambdaLayer のカスタムな関数で、requirements.txt
は LambdaLayer にインストールしたいライブラリー軍となっております。
次に各々のファイルの中身を以下のようになっております。
def greeting():
print("Hello !!")
requests==2.28.1
import hello
import requests
def handler(event, context):
print(requests.get("https://blog.i-tale.jp/").status_code)
print(hello.greeting())
return
LambdaLayer のビルド
以前の記事では専用のビルドスクリプトを作っていました。
しかしCode.from_asset
を利用すれば、そのへんすべてCDKで巻き取ってくれます。
Code.from_asset
には引数でビルドで利用したい image とビルド対象のコードが入ったディレクトリのパスと、ビルドに必要なコマンドを渡せます。
image は探したりDockerFileで自作したりする必要がありますが、公式で良い感じのものがたくさん用意されているので、それを利用すればほぼ問題ないと思います。
ビルドの仕様ですが、コンテナ中でビルド結果を/asset-output
ディレクトリ配下に保存する必要があります。cdk はそこからファイルを持ってきて1つの zip にまとめてデプロイしてくれます。
/asset-output
ディレクトリは初め空っぽなので、上記のサンプルのように、cp -aur . /asset-output
でruntime/layer
の中のコードをコピーして、cd /asset-output/python
で python のディレクトリへ移動して、pip install -r requirements.txt -t .
で必要なライブラリー軍を直下にインストール的なことをして良しなに配置してあげます。
デプロイ
下記コマンドでデプロイします。裏でコンテナをダウンロードするので結構時間かかりますのでゆっくり待ちましょう。
cdk -a "python3 app.py" deploy
デプロイが終わったら動作確認で一緒にデプロイしたLambdaを叩いて見ます。
下記な感じのログが出力されました。もうちょいprint
に情報入れればよかったですが、とりあえずLambdaLayerのパッケージが無事使えていることが確認できました。
START RequestId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Version: $LATEST
200
Hello !!
None
END RequestId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
以上!!削除コマンドはこちら!
cdk -a "python3 app.py" destroy
まとめ
今回はCDKを利用したLambdaLayerのビルドの方法を更新してみました。
Dockerを使わず(裏で使っているが意識して使わない)にCDKだけでビルド環境を作ってビルドできるので楽だなーと思います。
以上です。最後までお読みいただきありがとうございました!!