• Top
  • Search
  • About
  • Privacy Policy
#

概要

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

それでは、今日はここまで。

参考サイト