NumpyやPillowなどの依存を含むLambdaをServeless frameworkでデプロイする
はじめに
non-pure-Pythonの外部モジュールを含むLambda
NumpyやPillowなどの(C呼び出し等使った)non-pure-PythonなモジュールをLambda内で使う場合には,ひと手間必要で,大きく以下の2つの方法があります.
- (A) 外部モジュールをAmazon Linuxでビルドしてデプロイパッケージに直接含めるもしくはそれをLambdaレイヤーとしてデプロイして参照する.
- (B) コンテナイメージを使う.
外部モジュールをデプロイパッケージに含める場合,サイズが50MBという制限があります.(Lambdaレイヤーを使う場合には,250MB).一方のコンテナイメージでは,イメージサイズの上限が10GB以下となるため,サイズ制約が緩和されますが,ECRへのプッシュなど開発&デプロイは複雑になります.
外部モジュールをビルドする手間
状況次第ですが,サイズが250MBに収まる場合には,(A)を選択する場合が多いのかと思います.
(A)を行う場合には,Dockerなど用意したAmazon Linux環境内でpip installしてその生成物を取り出すという作業が必要ですが,Serverless frameworkを使ってLambdaをデプロイする場合には,この作業をpluginにより簡略化することができます.
この記事では,Serverless frameworkを使って,Numpy, Pillowなどnon-pure-Pythonのモジュールを含むLambda関数をデプロイする手順について書きます.
参考
- https://www.serverless.com/framework/docs/providers/aws/cli-reference/create
- https://www.serverless.com/plugins/serverless-python-requirements
- https://dev.classmethod.jp/articles/serverless-framework-lambda-numpy-scipy/
事前準備
以下をインストール/セットアップしておく.
- Serverless framework
- Docker
- AWSの認証情報
手順
1. サービスの作成
ServerlessでAWS Lambdaのサービスを作成する.
ここでは,sls-python-tutorial
というサービス名にします.
sls create --template aws-python3 --path sls-python-tutorial
sls-python-tutorial
ディレクトリに以下のファイルなどが生成される.
-
serverless.yml
: Serverlessの構成ファイル -
handler.py
: 処理の関数
2. ブラグインのインストール
NumpyやPillowのライブラリを使えるようにするため,serverless-python-requirementsというプラグインを使います.
# ディレクトリへ移動
cd sls-python-tutorial
# プラグインを追加
sls plugin install -n serverless-python-requirements
3. プラグインの設定を追加
serverless.yml
にserverless-python-requirements
用の設定を追加する.
custom:
# serverless-python-requirementsの設定
pythonRequirements:
# 依存のコンパイルにdockerを使う
dockerizePip: true
# キャッシュの設定
useDownloadCache: true
useStaticCache: true
dockerizePip
はPure-pythonではないライブラリをLinux以外のホスト(windowsやmac)からデプロイする場合は必須です.
requirements.txt
を作成
Pythonの依存をrequirements.txt
を書く.
numpy
Pillow
ライブラリを使った処理を追加(確認用)
ここでは,ライブラリを使った処理の例として,ライブラリのバージョンを取得してレスポンスに追加する.
import json
# インストールした依存をインポート
import numpy as np
import PIL.Image
import PIL
def hello(event, context):
# ライブラリのバージョンを取得
dependencies = {
"numpy": np.__version__,
"Pillow": PIL.__version__
}
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event,
"dependencies": dependencies
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
デプロイ
以下のコマンドでLambda関数をデプロイする.
# デプロイ
sls deploy --aws-profile <profile_name>
# 削除
sls remove --aws-profile <profile_name>
実行
以下のコマンドでデプロイされたLambda関数を実行する.
sls invoke -f hello
以下のように出力されれば成功
{
"statusCode": 200,
"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}, \"dependencies\": {\"numpy\": \"1.22.3\", \"Pillow\": \"9.0.1\"}}"
}
Discussion