概要

AWS Lambdaでpythonライブラリであるpulpを使っていたら以下のエラーに。

経緯と原因

Lambdaにはアーキテクチャがあって、LambdaLayerで参照するライブラリもそのアーキテクチャに合致していなければいけない場合があります。

そのため、AWSドキュメントにも記載あるように、platform指定でarm64用でビルド。

pip install --platform manylinux2014_aarch64 --target=package --implementation cp --python-version 3.x --only-binary=:all: --upgrade

この方法で生成されたpulpをLambdaにアップロードし、 いざリクエストを投げてみると...上述のエラーが発生しました。

これは「実行ファイルのフォーマットが合わない」という意味で、 異なるアーキテクチャのバイナリを実行しようとした時に出る典型的なエラーです。

今回、Lambda側はarm64で構築していました。 つまり、Lambda(arm64)環境用ではなく、x86_64(Intel/AMD)用であるためにエラーが発生、と言われています。

おかしいな、上記ドキュメント通りに作成したはずのだけど... なぜエラーになるのだろう??

ということでもう少し調べてみると、 たとえ--platform manylinux2014_aarch64を指定しても、pulpのホイール自体はpure Pythonですが、cbc(COIN-OR Branch and Cut=pulpが使用する線形計画問題ソルバー)バイナリは「x86_64(Intel/AMD)」用のまま同梱されていることが多いらしいのです。

なんと!

解決方法

ということで、以下の方法であらためてインストール。 (手順は以下記事で紹介したものと同じ。他の方法もあるかもしれませんが以下手順が慣れていたので)

# Amazon Linux 2023(ARM64)コンテナを起動
docker run --platform linux/arm64 -it --name build-container public.ecr.aws/amazonlinux/amazonlinux:2023 bash
# コンテナ内:必要なパッケージをインストール
dnf install -y python3.12 python3.12-pip gcc mariadb-connector-c-devel postgresql-devel python3.12-devel
# コンテナ内:ライブラリインストール用ディレクトリを作成
mkdir -p /tmp/python
# コンテナ内:ライブラリをインストール
pip3.12 install pulp -t /tmp/python
# ホスト環境:コンテナから python ディレクトリをコピー
docker cp build-container:/tmp/python ./packages-by-docker/python/

上記で作成されたpulpをzipにして、Lambdaで動かしてみたところ、エラーがなくなりました! cbcバイナリはAmazon Linux arm64環境でインストールされるものを使うことができたためです。

以上!