はじめに
私が携わっているプロジェクトでは、AWS Amplifyを活用し、ランタイムがPython 3.8のLambda functionとLayerを使用しています。
Python 3.8のサポート終了が近いため、問題を未然に防ぐためにPython 3.12へのアップグレードを決意しました。
詳細はAWSの公式ドキュメントを参照してください。
Lambda ランタイム
環境
- Amplify: 12.11.1
- Python: 3.12.2
- Pipenv: 2023.12.1
遭遇した問題
バージョンアップの過程で、以下のファイル内のruntimesやpython_versionを3.12に更新しました。
- amplify/backend/function/laynerName/parameters.json
- amplify/backend/function/laynerName/lib/python/Pipfile
ところが、上記の修正後にビルドをしても
amplify/backend/function/laynerName/lib/python/lib/
の配下にpython3.12/site-packages/
が生成されず、代わりに以前のバージョンである、python3.8/site-packages/
が生成されてしまいます。
結果として、デプロイは成功しましたが、ランタイムがPython 3.12に更新されたfunctionからはLayerのライブラリを認識できませんでした。
問題解決の試み
Amplify CLIのamplify-python-function-runtime-provider
のpackageUtils.ts中のpythonPackage()
を調査したところ、getPythonBinaryName()
で取得したPythonコマンドのバージョンに基づいてディレクトリが作成されていることがわかりました。
また、getPythonBinaryName()
はpythonとpython3が実行可能な場合、python3を優先して選択します。
export async function pythonPackage(context: any, params: PackageRequest): Promise<PackageResult> {
if (!params.lastPackageTimeStamp || params.lastBuildTimeStamp > params.lastPackageTimeStamp || params.currentHash) {
const packageHash = await context.amplify.hashDir(params.srcRoot, ['dist']);
const zipEntries: ZipEntry[] = [];
if (params.service) {
const pyBinary = getPythonBinaryName();
const pyVersion = await execWithOutputAsString(`${pyBinary} --version`);
const layerPythonPath = path.join(params.srcRoot, 'lib', 'python' + majMinPyVersion(pyVersion), 'site-packages');
const pipEnvDir = await getPipenvDir(params.srcRoot);
// copy from virtualenv to layer path to maintain layer required structure
fs.copySync(pipEnvDir, layerPythonPath, { overwrite: true });
https://github.com/aws-amplify/amplify-cli/blob/dev/packages/amplify-python-function-runtime-provider/src/util/packageUtils.ts
https://github.com/aws-amplify/amplify-cli/blob/dev/packages/amplify-python-function-runtime-provider/src/util/pyUtils.ts
これは完全に私の落ち度なのですが、Python 3.12をインストールした後、python -V
は3.12を指すことは確認していたものの、python3
のバージョンチェックを怠っていたため、古いバージョンを指していました。
解決策
python3
を正しくpython3.12を指すように修正したところ、無事期待する形でデプロイができました。
python3
が意図したバージョンを指しているか確認しましょう。
ところで、
Pipfileのpython_version
を参照してsite-packagesディレクトリを作ればいいような気がしますが、なにか理由があるのでしょうか。
また、ランタイムに複数のPythonバージョンを指定した場合などこれを起因とする問題が発生しそうですが、これについてはまだ検証していません。