📃

Python Lambda レイヤーの仕組み

2024/12/27に公開

はじめに

※ Lambdaレイヤーを作成するための操作手順詳細は含みません。

Lambdaでは、関数のコードからパッケージなどを参照するため、レイヤーという仕組みを備えています。
この記事では、Pythonランタイムにおいてどのような仕組みで参照が行われているのかを記載します。

要点

Pythonのパッケージをレイヤー経由でLambda関数から参照させるためには、次の2点が満たされている必要があります。

  • レイヤーに指定するzipが、特定のディレクトリ構造となっていること
  • パッケージのWheelがAmazon Linuxおよび選択したアーキテクチャで利用可能であること

前提として、Lambda関数にレイヤーを追加するには、次の操作を行う必要があります。

  • ローカルで対象パッケージを含むzipファイルを作成
  • zipファイルをアップロードして、AWS Lambdaでレイヤーを作成
  • AWS Lambdaで関数にレイヤーを追加

このうち、zipファイルの作成には次のようなコマンドを実行します。

mkdir python
pip3 install --platform any --target ./python --python-version 3.13 --only-binary=:all: requests
zip -r layer.zip ./python

このコマンドによって、前述した2点を満たした状態でレイヤーを作成することができます。
ここからは、その仕組みを詳述していきます。

zipファイルのディレクトリ構造

こちらでは、以下の点について記載します。

  • レイヤーに指定するzipが、特定のディレクトリ構造となっていること

実行環境におけるPATHの自動追加

Lambda関数は、Amazon Linux上で実行されます。

実行環境では、レイヤーを参照するために特定のディレクトリへのパスが環境変数PATHに含まれた状態となっています。
具体的な値は実行ランタイムによって異なり、Pythonの場合は次の2種類が対象です。

  • /opt/python
  • /opt/python/lib/python3.x/site-packages3.xはバージョンにより可変)

関数にレイヤーが追加されている場合、レイヤーに対応するzipファイルが実行環境の/opt配下に展開されます。
このため、zipファイル内のディレクトリ構成が適切であれば、パッケージを関数から参照可能な場所に配置できます。

レイヤー用のzipファイル構造

PATHに含まれる値は固定となるため、レイヤー用のzipファイルはそれを前提とした構造が必要です。
冒頭に記載したレイヤー用zip作成コマンドで作られたファイルを解凍すると、次の構造となります。

python
├── bin
├── ...

最上位フォルダがpythonとなっているため、/opt配下に展開されると/opt/pythonとしてPATH経由で参照が可能となります。

最上位フォルダが異なる名前の場合、レイヤーに含まれるパッケージを関数から参照することができません。
例えば、ディレクトリ名の記述を全てtestに変更してzipファイルを作成した場合、レイヤーとして読み込んでも関数からの参照時にエラーとなります。

パッケージのWheel種別

こちらでは、以下の点について記載します。

  • パッケージのWheelがAmazon Linuxおよび選択したアーキテクチャで利用可能であること

Wheelとは

Lambda関数上でレイヤー経由のパッケージを利用するには、Amazon Linux上で動作するWheelがインストールされている必要があります。
WheelとはPythonのパッケージングファイルで、.whlを拡張子とします。
WheelはPythonバージョンやOSなどによって適切なファイルが異なり、動作可能な対象をインストールする必要があります。
なお、Wheelが提供されていないパッケージの場合、レイヤーは使わずコンテナ内に含めることが推奨されています。(参考

プラットフォームタグ

Wheelのファイル名は動作環境を表しており、下記の構造となっています。

{Pythonタグ}-{ABIタグ}-{プラットフォームタグ}.whl

このうちプラットフォームタグは、Wheelが動作するOSを表しています。
Amazon Linuxの場合、対応するプラットフォームタグは次のとおりです。

  • アーキテクチャがx86_64の場合、manylinux2014_x86_64
  • アーキテクチャがarm64の場合、manylinux2014_aarch64

このほかに、OSによらず動作を保証するanyも指定可能です。

たとえば、requests-2.32.3-py3-none-any.whlのプラットフォームタグはanyとなります。
プラットフォームタグを複数持っている場合もあります。(例:numpy-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

推奨されるプラットフォームタグ

manylinux2014_x86_64(またはmanylinux2014_aarch64)とanyのどちらでも動作は可能です。
ドキュメントではanyを推奨していますが、情報センター(参考1参考2)ではmanylinux2014_x86_64のWheelがインストールするコマンドが記載されており、強い推奨ではないと推測されます。

提供されているWheelの確認方法

続いて、パッケージがAmazon Linux用のWheelを提供しているか確認する方法を2つ紹介します。

PyPI

PyPIで対象パッケージのページを開き、左メニューからファイルのダウンロードを押下します。
Built Distributionに表示されているのが、パッケージのWheelの一覧です。
例えばrequestsでは、requests-2.32.3-py3-none-any.whlのみが提供されています。
一方で、numpyではanyは提供されておらず、manylinux2014用が提供されていることが分かります。

pip install

インストールテストによって、対応するWheelが存在しているか確認することも可能です。
基本形式は以下のとおりです。

pip3 install --dry-run --platform {プラットフォームタグ} --target . --python-version {Pythonバージョン} --only-binary=:all: {パッケージ名}

ここでは--dry-runを指定しているため、実際にインストールはされずコンソール上に結果が表示されます。

例えば、実行ランタイムをPython 3.13としてrequestsをインストール可能か試すコマンドは次のとおりです。

pip3 install --dry-run --platform any --target . --python-version 3.13 --only-binary=:all: requests

ログの中には、プラットフォームがanyのWheelをインストールすることが書かれています。

Collecting requests
  Using cached requests-2.32.3-py3-none-any.whl.metadata (4.6 kB)
(中略...)
Using cached requests-2.32.3-py3-none-any.whl (64 kB)

パッケージのみnumpyに変更してコマンドを実行すると、anyが存在しないためエラーとなります。

pip3 install --dry-run --platform any --target . --python-version 3.13 --only-binary=:all: numpy
ERROR: Could not find a version that satisfies the requirement numpy (from versions: none)

インストールコマンド

インストールするプラットフォームタグの確定後、コマンドに--platformを指定して実行します。
同時に--python-versionによって、関数の実行ランタイムと合致したPyhonバージョンも指定します。
(下記は冒頭のコマンドの再掲です)

pip3 install --platform any --target ./python --python-version 3.13 --only-binary=:all: requests

--platformの指定がない場合、anyよりもインストールコマンドを実行したOS用のWheelが優先的にインストールされます。
Python Packaging User Guideにおいて、特定OSのWheelよりanyが下位に設定されていることが確認できます。

例えばsqlalchemyanyと各OS用のWheelをそれぞれ提供しています。
macOS上で--platformを指定せずにインストールしたとき、ダウンロードされるのはmacOS用のWheelです。

pip3 install --dry-run --target . --python-version 3.13 --only-binary=:all: sqlalchemy
(中略...)
Downloading SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl (2.1 MB)

パッケージが動作するのはAmazon Linux上のため、WindowsやmacOSでzip作成のためのインストールをするときには、常に--platformを指定する必要があります。

こうして適切なWheelをインストールすることで、パッケージは関数の実行環境で動作可能となります。

まとめ

Pythonのパッケージをレイヤー経由でLambda関数から参照させるための要件を再掲します。

  • レイヤーに指定するzipが、特定のディレクトリ構造となっていること
  • パッケージのWheelがAmazon Linuxおよび選択したアーキテクチャで利用可能であること

これらを満たすzipファイルの作成コマンドを通じて、レイヤーを関数から読み込むことができます。

NCDCエンジニアブログ

Discussion