概要
AWS Lambdaでpycryptodomeを使ったpythonコードを動かしていたら、以下のエラーに。
Cannot load native module 'Crypto.Cipher._raw_blowfish': Not found '_raw_blowfish.cpython-312-x86_64-linux-gnu.so', Cannot load '_raw_blowfish.abi3.so': /opt/python/Crypto/Util/../Cipher/_raw_blowfish.abi3.so: invalid ELF header, Not found '_raw_blowfish.so'
原因
PyCryptodomeのインストールで利用した環境は私のホストマシンで、Mac M1です。
このエラーは、PyCryptodomeがAWS Lambdaの環境に合っていないために発生しているとのこと。
Lambda互換のLinux環境でビルドしたPyCryptodomeをデプロイする必要があります。
確かに実際にpip installでインストールされたpycryptodomeディレクトリを見てみると、エラーメッセージにあるファイル名は存在していませんでした。
これは、ホストマシンでインストールしたパッケージとLambda環境が期待するパッケージの中身が異なっているためです。Lambdaと互換性がない、ということなのですね。
関連記事
・調査を進める中で、m1 MacからビルドしたコンテナとLambda関数の命令セットアーキテクチャに差異があることが分かった。
引用元:https://iret.media/109883
It looks like your local dev environment is not compatible with the Lambda execution environment. The native libraries that PyCryptodome uses are not portable across these two environments; it matters in which env the library was pip installed.
引用元:https://stackoverflow.com/questions/54467095/module-initialization-error-cannot-load-native-module-crypto-cipher-raw-ecb
解決方法
解決策は以下を満たすようにすることと思います。
・Lambdaで使うアーキテクチャ、Pythonランタイムに合わせること(今回はAMD64, Python3.12)
・Lambdaのamazonlinux:2023と合わせること
とはいえ、普通にdockerコンテナを利用しても実行環境(ホストマシン)のアーキテクチャに依存してしまいます。
ということでdockerでplatformとAmazonLinuxを指定してインストールする方法が良さそう。
以下のような手順で可能です。
# 上記条件でdockerを起動する
docker run --platform linux/amd64 -it --name lambda-build amazonlinux:2023 bash
dnf install -y python3.12 python3.12-pip gcc
mkdir -p /tmp/python
pip3.12 install pycryptodome -t /tmp/python/
# dockerから抜ける
exit
# dockerにインストールしたパッケージをローカル環境のディレクトリにコピーする
docker cp lambda-build:/tmp/python ./pycryptodome/python/*
docker rm -f lambda-build
これでLambda互換の成果物ができました。
Lambda Layerにアップロードして動かしてみると、エラーはなくなりました。
解決!
参考
This is happening because the pycryptodome module installed on your local machine is not compatible in lambda. so there are two ways we can fix this.
- Use docker to pull amazonlinux image and install pycryptodome using pip install. then export the pycryptodome module to lambda layers.
- Start a ec2 instance, must be amazonlinux and install pycryptodome in it. then either download the module using winscp or cli to your local. Create a lambda layer package using the downloaded module and upload it to lambda layer.
make sure to follow below guidline for creating lambda layer package. Import libraries in lambda layers