初めに
Lambda のPython 3.12 対応につき、Layer の作成方法を調査したので備忘録的に残します
基本的にはpython3.11 の時と変わらないと思いました
- .zip形式での作成 とします
- コンテナでの作成方法は対象外
ポイント
- Python3.12 はAmazon Linux 2023で動く
- Windows環境でのLayer 作成は困難なので、Windows環境しかない人はどうにかLinux環境を構築する
作業の大まかな流れ
大まかな流れは以下の通りです:
- Lambda実行環境の確認
- (Linux 環境を入手)
- Python3.12 と必要なパッケージのインストール
- 目的の pip のパッケージをディレクトリににインストール
- レイヤーの作成
Linux 環境が無い場合は Cloud9 が手っ取り早いです
python3.11 の時はローカルのUbuntuで作成したLayerも問題なく動作しました(OSが違うにも拘らず)が、python3.12はまだ試せていません
補足
Amazon Linux 2023 は Fedoraベース
Amazon Linux2 は CentOSベース
Lambda実行環境の確認
公式が環境情報を公開していますが、念のため Lambda の実行環境を確認します
確認方法
適当なLambda関数を作成して確認します
import botocore
import boto3
import sys
def lambda_handler(event, context):
print(sys.version) # pythonのバージョン
print(boto3.__version__)
print(botocore.__version__)
2024.3.1の確認結果:
Lambda Runtime | Python | AMI | botocore | boto3 |
---|---|---|---|---|
Python3.12 | Python 3.12.1 | Amazon Linux 2023 | 1.31.72 | 1.28.72 |
Python3.11 | Python 3.11.6 | Amazon Linux 2 | 1.30.1 | 1.27.1 |
pythonのインストール
ここからはLayer を作成するLinux マシンで作業します
python のインストールは pyenv を使うと楽なようです
# pyenvをインストール
sudo git clone https://github.com/pyenv/pyenv.git /usr/bin/.pyenv
# 必要なディレクトリを作成(補足:情報元不明なため、理由が分かりませんが)
sudo mkdir /usr/bin/.pyenv/shims
sudo mkdir /usr/bin/.pyenv/versions
# 所有者の変更
sudo chown -R myuser:myuser /usr/bin/.pyenv/ # 分からなければwhoamiで確認
sudo chown -R ec2-user:ec2-user /usr/bin/.pyenv/ # ec2/cloud9 の場合
# PATH 関連の作業
echo 'export PYENV_ROOT="/usr/bin/.pyenv"' >> ~/.bash_profile
echo 'export PATH="${PYENV_ROOT}/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init --path)"' >> ~/.bash_profile
# .bash_profile を一度実行しておく
source ~/.bash_profile
バージョンを指定してpythonをインストール
# バージョンを指定してpythonをインストール
pyenv install 3.12.1
# デフォルトのpythonの変更
pyenv global 3.12.1
# 確認
python3 -V
必要パッケージのインストール
補足:仮想環境(python-venvなど) を使っても良いようです
# pip のアップデート
python3 -m pip install -U pip
# 必要パッケージのインストール ※ランタイム毎に違う
python3 -m pip install botocore==1.31.72
python3 -m pip install boto3==1.28.72
pip のパッケージをディレクトリにインストール
今回、仮に requests 用のLayerを作成するものとします
先に以下のようなディレクトリ構成にしておきます
~/
+ requests-layer-py312/
+ python/ ディレクトリ名はpythonでないとダメ
公式(ディレクトリ名):
パッケージインストール
# この例でいう requests-layer-py312 を現在地(cwd)にする
cd ~/requests-layer-py312
# -t オプションでディレクトリにインストール
python3 -m pip install \
--platform manylinux2014_x86_64 \ # --platformは必ず指定する
--implementation cp \
--only-binary=:all: \
-t ./python/ \
requests # 目的のパッケージ
公式:
レイヤーの作成
ここまで来たら簡単です
.zipファイルを作成
まずは.zip アーカイブを作成
# 本ディレクトリをzipアーカイブ(最後ドット=現在ディレクトリ)
zip -r ../requests-layer-py312.zip .
補足
- EC2などを使っているときはscpなどを使ってダウンロード
scp my-ssh-config:/home/ec2-user/requests-layer-py312.zip ~/
- Cloud9の場合はファイルエキスプローラから右クリックでダウンロード可能
レイヤーの作成
マネージメントコンソールで作業するものとします
Lambda -> ナビゲーションペイン:レイヤー -> レイヤーの作成
-> 作成した .zip ファイルをアップロード
以下、任意で(但し推奨)
- 「互換性のあるアーキテクチャ」 x86_64にチェック(もちろんx86_64の時)
- 「互換性のあるランタイム」で任意のPythonバージョンを指定
-> 作成
レイヤーの追加
Lambda -> ナビゲーションペイン:関数 -> 任意の関数を選択 -> 「コード」タブ -> 「レイヤー」セクション(コードソースの下の方)-> レイヤーの追加
レイヤーソースは「カスタムレイヤー」を選択 -> 先ほど作成したレイヤー(とバージョン)を選択
確認
最後に Lambda で動作確認をします
import json
import requests
def lambda_handler(event, context):
# urlはなんでも良いですが
res = requests.get('http://httpbin.org/ip')
return {
'statusCode': 200,
'body': json.dumps(res.text)
}
補足
自作モジュールをLayerに含めたい場合
これは全然難しい事はなく、他のpipモジュール群と一緒にpython ディレクトリに.pyファイルを作成するだけで良いようです
~/
+ requests-layer-py312/
+ python/
+ requests/ # 今回インストールした pip モジュール
... # 他にもディレクトリなどがあるとする
+ my_custom_module.py # 自作モジュール
蛇足ですが、下の「Windows での .zip化」問題があり、この事実に気が付くのに時間をかなり取られました...
Windows での .zip化について
Windows のファイルエキスプローラーから「.zipファイルに圧縮をする」を行うとディレクトリ構成が変化してしまう為、上手く Layer が作成できません
(前から思ってましたが、M〇製品にはたびたび奇妙な仕様が見受けられますね...)
【Linux環境で作ったファイルのディレクトリ構成】
requests-layer-py312/
+ python/
↓ Windows環境で.zipファイルを作成すると以下のようになってしまう!!
[ requests-layer-py312.zip ]
requests-layer-py312/
+ requests-layer-py312/
+ python/
対応方法
間抜けな方法しか思いつきませんでしたが、(Windows 環境にあまり明るくない)
思いついたのは python ディレクトリをアーカイブ化する方法
【Linux環境で作ったファイルのディレクトリ構成】
requests-layer-py312/
+ python/ ← 【これを .zip アーカイブする】
↓
すると以下のようなディレクトリ構成になる事が期待されます
[ python.zip ]
python/
+ python/
なんとも間抜けな方法ですが、動作確認できましたので、これを解決方法としたいと思います。
Amazon Linux 2 での OpenSSL 問題
簡単に言うと、Amazon Linux 2 初期状態では pyenv install 3.11.6
が失敗します
python3.11 のインストールには OpenSSL が必要です
- 厳密にはpython3.10 以降でOpenSSL 1.1.1以上が必要
資料:https://peps.python.org/pep-0644/ - 簡単に言うと openssl11 をインストールすれば良い
対策1
【 Amazon Linux 2023 で pyenv install 3.11.6
を実行してLayerを作成する 】
=>「多分うまく行かんだろうが...」と思ってましたが動作しました
(Layer関係で最初に読んだ記事に「環境を合わせろ」とありましたが、上述のように Ubuntu でも成功したし、案外何でも良いのでは?様子をみますが)
対策2
【 Amazon Linux 2 に OpenSSL を(再)インストール 】
以下でうまく行きました:
sudo yum remove -y openssl-devel
sudo yum install -y openssl11 openssl11-devel
参考:https://qiita.com/rururu_kenken/items/8c2491b41ff20fa57f20
蛇足:Amazon Linux 2 での最初の一歩でうまく行かなかったので「対策1」を発見した訳ですが、対策2で作成したLayerも上手く動作しました
Linux 環境にWSLを使う場合
Layer 作成に必要な Linux ですが、Windowsの方は WSL でも良いようです。
昔使って使いにくい印象のままでしたが、近年では VSCode の Remote Developmentで使えたり、大分使いやすくなっているようです。(WSLの使用方法は割愛)
ポイント
- Layer 作成時にEC2インスタンスの料金を払いたくない場合
- Cloud9の方が遥かに楽ではある(作業工数の削減になる)
- 以下のパッケージを補う必要がある(ディストリビューションが Debian/Ubuntu の場合)
sudo apt install build-essential libssl-dev libffi-dev liblzma-dev zlib1g-dev
bzip2-dev zip
参考資料
公式
主に作成手順
python 3.10をAWS EC2にinstall