LoginSignup
1
0

python3.12 のLambda Layerの作成方法

Last updated at Posted at 2024-03-01

初めに

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 環境にあまり明るくない:sweat_smile:
思いついたのは 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を作成する 】
=>「多分うまく行かんだろうが...」と思ってましたが動作しました:joy:

(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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0