メインコンテンツへスキップ

localstackを使ったlambdaのdeployについて

· loading · loading ·
kiitosu
著者
kiitosu
画像処理やデバイスドライバ、データ基盤構築からWebバックエンドまで、多様な領域に携わってきました。地図解析や地図アプリケーションの仕組みにも経験があり、幅広い技術を活かした開発に取り組んでいます。休日は草野球とランニングを楽しんでいます。
目次

初めに
#

localstackにpython lambdaのdeployを試みた。 いろいろと詰まる部分があったので整理しておきます。

結論
#

  • lambda layer は proである必要がある(https://docs.localstack.cloud/user-guide/aws/lambda/#lambda-layers-pro)
  • インストールしたパッケージをhandlerのコードと同じディレクトリに直置きすればlayerを使わずに済む
  • pythonの依存関係をインストールする場合は実行時のインタープリタのバージョンと合わせたpipを使うこと

localstackのlambda layer
#

以下の様なコマンドでlayerのpublishができる

mkdir python
pip install -r requirements.txt -t python
zip -r my-layer.zip python
awslocal lambda publish-layer-version \
    --layer-name my-layer \
    --zip-file fileb://my-layer.zip

以下の様なコマンドでlayerを使うlambdaがdeployできる

zip -r /tmp/func.zip ./src/*
function_name=my-func
role=arn:aws:iam::000000000000:role/lambda-role
awslocal lambda create-function \
    --function-name ${function_name} \
    --runtime python3.9 \
    --handler index.handler \
    --zip-file fileb:///tmp/func.zip \
    --role ${role} \
    --architectures arm64 \
    --layers arn:aws:lambda:ap-northeast-1:000000000000:layer:my-layer:1

しかし実際にlambdaのコンテナにはいってpythonを実行するとrequirements.txtでインストールしたはずのパッケージがないというエラーが起きる。

deployの時点では成功するのが罠。 localstack proでないとlayerがつかえない。

layerを使わずにパッケージ込みのlambdaをdeployする
#

ではどうするかというと、lambdaのhandlerのコードと同じところにパッケージを展開してやり、zip化してやればよい。 具体的には以下の様なコードでdeployする。

mkdir /tmp/lambda_src
pip install -r requirements.txt -t /tmp/lambda_src
(cp ./src/* /tmp/lambda_src && cd /tmp/lambda_src && zip -r /tmp/func.zip ./*)
function_name=my-func
role=arn:aws:iam::000000000000:role/lambda-role
awslocal lambda create-function \
    --function-name ${function_name} \
    --runtime python3.9 \
    --handler index.handler \
    --zip-file fileb:///tmp/func.zip \
    --role ${role} \
    --architectures arm64 \
    --layers arn:aws:lambda:ap-northeast-1:000000000000:layer:my-layer:1

pip install -t でインストール先のディレクトリを指定。 (実際にはpipだけではダメな場合あり。次に説明) cp でhandlerのコードを同じディレクトリにコピー。 同じディレクトリに移動してzipファイル作成。

依存関係インストール時のpythonのインタプリタのバージョンを合わせる
#

前述の通りに実施しても、 “ModuleNotFoundError: No module named ‘psycopg2._psycopg’” という様なエラーが出ることがある。これはpythonのバージョンの差異による問題。

例えば、python3.9のlambdaの実行環境に対してpython3.10でpip installしてパッケージを準備すると、psycopg2/_psycopg のファイルが存在せず、import時にエラーとなる。これを回避するためには

python3.9 -m pip install … の様にpython3のバージョンを指定してpipを実行すればよい。

最後に
#

awslocal lambda create-function の処理が通ってしまったので、layerが使えるはずだと勘違いしてだいぶ時間を食ってしまいました。awslocalで新しいコマンドを実行する時は、community対応しているかどうかを最初に確認する必要がありますね。

Reply by Email

関連記事

GithubからのAWS利用時のサムプリントはもはや不要
· loading · loading
hasura nested mutatoin
· loading · loading
ORDER BY は 列毎に指定できる
· loading · loading