概略
自作のPythonプログラムがAWS Lambda上で動作しないという問題が発生。
Pythonで使っているライブラリの"lxml"とlambda実行環境の問題であることが判明。
lambdaレイヤーを活用して、この問題を解決する方法を記します。
原因
原因となっているlxml。
このライブラリはc言語依存で作られているらしい。
通常、lambdaでプログラムが呼び出される際には、requirements.txtが参照されて記載されているライブラリがlambda環境へpipでインストールされる。
C言語依存のライブラリは、pipでインストールする際にコンパイルが必要。
しかし、lambda環境は実行環境なのでコンパイラが含まれていない。
そのため、該当のライブラリはインストールされない。
結果、Pythonでインストールされていないライブラリを使おうとするのでエラーとなる。
解決方法
概要
コンパイルできる環境へライブラリをインストールし、インストールされたライブラリファイルをlambdaレイヤーへ含めることで解決を図る。
lambdaレイヤーにライブラリを入れる方法
1. 環境作成
cloud9の環境を作成
cloud9を使うのはCPUアーキテクチャとOS(AmazonLinux)をlambda実行環境と一致させるため。
※ Docker環境にて、amd64とAmazonLinuxのイメージを用いる方式でも問題なさそうだが、今回は試していない。
cloud9の環境において、ディレクトリ階層の一番上でpythonディレクトリを作成。
pythonという名前で作成しておくと、レイヤーへ含めた際に/opt/pythonディレクトリに展開される。このパスは、lambdaの実行環境でパスが通っている状態になるため、別途設定する手間が省ける。
2. インストール
pythonディレクトリに移動。
pipで、インストール先をカレントディレクトリ(.)に指定して、ライブラリをインストール
cd python python3 -m pip install [ライブラリ名] -t .
lxmlだけでなく、よく使うライブラリもインストールして、同じディレクリに含めておくと良い。
3. ダウンロード
Cloud9で、pythonディレクトリを右クリックしてダウンロード
macOSだと、zip形式ではなくtar.gz形式がデフォルト設定となっている。
Cloud9の設定でユーザインターフェイスの項目を変更することで、zip形式へ変更できる。
4. アップロード
lambdaレイヤーへzipファイルをアップロードする。
注意点
cloud9は、この記事を書いている時点でPython3.7が標準インストールされている。 そのため、pip installでpython3.7系であることを示すディレクトリが作成される。 lambdaの実行環境もそのバージョンのランタイムで作る。
python3.7のCloud9にてpip installしたライブラリは、python3.7以外のランタイムでは動かない。 ディレクトリ名にPythonのバージョンを示す"37"などが入ってるので仕方ない。
また、layerに含めたライブラリは、requirments.txtには含めなくて良い。