概要
AWS Lambda Layerにデプロイする外部ライブラリやモジュールは、Lambda実行環境のアーキテクチャと互換性が必要です。
開発環境(Mac M1/M2やIntel Mac、Windows等)で直接pip installを実行すると、ホストマシンのアーキテクチャ向けにパッケージがインストールされます。これがLambda実行環境のアーキテクチャと異なる場合、デプロイ後にImportErrorなどのランタイムエラーが発生します。
本記事では、Lambda Layerと互換性のあるライブラリを確実にビルドする2つの方法を紹介します。
2つのビルド方式
Lambda Layer用のライブラリをビルドする方式は主に2つあります。
(他にもあると思いますが、私はこの2通りで問題ないと思っています)
- クロスプラットフォーム方式:pip の
--platformオプションを使用 - Docker方式:Lambda実行環境と同じコンテナ内でビルド
基本的にはクロスプラットフォーム方式で問題ないと思いますが、以下のようなC拡張を含むパッケージはDocker方式でのインストールが必要でした。
- mysqlclient
- psycopg2
- uWSGI
これらのパッケージは、ネイティブバイナリのコンパイルが必要なため(もしくはプリビルドされたホイールが提供されていないため)、Lambda実行環境と同じOS・アーキテクチャ上でビルドする必要があります。
クロスプラットフォーム方式で取り込むとインポートエラーになりました。
1. クロスプラットフォーム方式
AWS公式ドキュメントに記載されている方法です。
↑に記載ある通り、pipの--platformオプションで、対象アーキテクチャのビルド済みホイールをダウンロードする方法になります。
arm64の場合は以下になります。
pip install \
--platform manylinux2014_aarch64 \
--target=package \
--implementation cp \
--python-version 3.x \
--only-binary=:all: --upgrade \
<package_name>
x86_64の場合は以下です。
pip install \
--platform manylinux2014_x86_64 \
--target=package \
--implementation cp \
--python-version 3.x \
--only-binary=:all: --upgrade \
<package_name>
2. Docker方式
C拡張を含むパッケージや、プリビルドホイールが存在しないパッケージは、Lambda実行環境と同じ環境でビルドしてあげると良いです。
以下の手順で正常にビルドすることができました(arm64の場合)。
①Amazon Linux 2023コンテナを起動
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 mysqlclient psycopg2 uWSGI -t /tmp/python
④ホスト環境:コンテナから python ディレクトリをコピー
docker cp build-container:/tmp/python ./packages-by-docker/python/
生成されたディレクトリをzip化し、LambdaLayerにアップロードすればOKです。
※どちらの方法でもPythonバージョンはLambda関数の設定と一致させるようにしてください