概要
AWS Lambda に Python の外部モジュールを読み込む方法を解説します。
今回は Python の Numpy を例に解説を行います。
実行環境
- AWS Lambda
- Python 3.8
- numpy 1.19.2
外部モジュールを使用するときの注意事項
AWS Lambda で Python の外部モジュールを使用するとき、 Pure Pythonで書かれたモジュールであれば何も気にしなくても使用することができます。
しかし、Numpy などの C 言語に依存するモジュールの場合は、Windows や Mac でインストールしたものをデプロイしてもエラーで怒られます。
なので、こういったC 言語に依存する外部モジュールを使用する際は、Lambda の実行環境と同じものでインストールをしてやる必要があります。
もちろん、Lambda 上でインストールすることはできないので、Lambda の実行環境 と同じものを再現されている lambci/lambda
を使用することになります。
実行環境の準備
今回の手順としては、Docker で Lambda と同じ実行環境を準備して、そこでインストールした外部モジュールを実際の Lambda にデプロイして使うというものになります。
適当なディレクトリを作成し、Dockerfile
を作成します。
$ mkdir python_module_builder && $_
$ touch Dockerfile
作成した Dockerfile
に以下を記述します。
今回は、Python 3.8 のランタイムを使用するので、build-python3.8
を指定しています。
# イメージの指定
FROM lambci/lambda:build-python3.8
# インストールコマンド
ENTRYPOINT ["pip","install","-t","/opt/python"]
外部モジュールのビルド
Dockerfile
をビルド、実行します。
コマンドではコンテナ内でインストールした外部モジュールをホストでも参照するために、ボリュームオプションを指定しています。
$ docker image build -t python_module_builder .
$ docker container run --rm -v ${PWD}/python:/opt/python python_module_builder numpy
また、上記の Dockerfile
では CMD
を指定していないので、以下のようにモジュールを指定できるようになっています。
$ docker container run --rm -v ${PWD}/python:/opt/python python_module_builder <モジュール名>
コンテナを実行した後は、フォルダ構成が以下のようになります。
.
| -- python/
| | -- bin/
| | -- numpy/
| | -- numpy.libs/
| ` -- numpy-1.19.2.dist-info/
`-- Dockerfile
Lambda レイヤーにデプロイ
あとは、python ディレクトリを zip で固めてから、Lambda のレイヤーにデプロイするだけです。
zip 後は、コンソールを使ってレイヤーに追加するか、aws cli の publish-layer-version
コマンドを使ってデプロイを行います。
$ zip -rq numpy.zip python
$ aws lambda publish-layer-version \
--layer-name numpy \
--zip-file fileb://numpy.zip \
--compatible-runtimes python3.8
ちなみに、zip ファイルが大きすぎると、以下のように怒られるので、その時は S3 経由であげるようにしましょう。
An error occurred (RequestEntityTooLargeException) when calling the PublishLayerVersion operation: Request must be smaller than 69905067 bytes for the PublishLayerVersion operation
モジュールをレイヤーに追加できたら、Lambda で今回追加したレイヤーを指定するだけです。
レイヤーを指定後、以下のソースコードを実行すると Numpy が使用できるはずです。
import numpy as np
def lambda_handler(event,context):
print(np.__version__) # 1.19.2
それでは、今日はここまで。