AWS Glue での Python 仮想環境の使用
AWS Glue 5.0 以降では、Python 仮想環境 (venv) で ETL ジョブを実行できます。仮想環境を使用することで、ジョブ実行からランタイム依存関係の解決を切り離し、各実行で同じパッケージが使用されることを保証し、アップストリームパッケージの変更による障害を防止します。
AWS Glue は、仮想環境を使用する 2 つの方法をサポートしています。
-
サービス生成仮想環境 – AWS Glue 6.0 以降で使用できます。
--python-virtual-env-storage-prefixパラメータを追加すると、AWS Glue が仮想環境を構築し、後続ジョブの実行のために その仮想環境をAmazon S3 にキャッシュします。ローカルビルドは不要です。 -
手動構築の仮想環境 – AWS Glue 5.0 以降で使用できます。仮想環境をローカルマシンまたは CI/CD パイプラインで構築し、Amazon S3 にアップロードして、
--python-virtual-envパラメータで参照します。
このトピックでは、--additional-python-modules を使用するジョブをいずれかの方法に移行する手順について説明します。その他の Python 依存関係管理方法については、「AWS Glue での Python ライブラリの使用」を参照してください。
--additional-python-modules との主な違い
次の表は、--additional-python-modules と手動構築の仮想環境を比較したものです。
機能 |
|
|
|---|---|---|
ベースコンテナライブラリ (boto3、numpy、pandas、その他) |
自動的に利用可能 |
利用不可。必要なパッケージをすべて venv に含める必要があります。 |
依存関係の解決 |
実行時に発生 |
マシンのビルド時に発生 |
ランタイム分離 |
一部。パッケージはベースライブラリの上にインストールされます。 |
全部。Python 環境を完全に置き換えます。 |
重要
--python-virtual-env に移行するときは、ジョブに必要な Python パッケージをすべて仮想環境に含める必要があります。これには、AWS Glue ベースコンテナで過去に利用できていた boto3、numpy、pandas などのパッケージが含まれます。これらのパッケージは暗黙的に利用できなくなりました。
アプローチの選択
次の表を参照して、ジョブに適したアプローチを決定してください。
シナリオ |
(推奨されるアプローチ) |
|---|---|
PIPパッケージが少なく、ビルドオーバーヘッドを最小限に抑えたいシンプルなジョブ |
サービス生成 venv ( |
複雑な依存関係ツリー、完全な再現性、または venv を構築する CI/CD パイプライン |
手動で構築された venv ( |
変更を最小限に抑えた |
サービス生成 venv ( |
カスタムパッケージを含むプライベート PyPI インデックス |
どちらのアプローチでも可。サービス生成 venv には AWS Glue 6.0 以降が必要で、--python-modules-installer-option と連動する。 |
Amazon S3 キャッシュを使用したサービス生成の仮想環境の使用
AWS Glue 6.0 以降では、--python-virtual-env-storage-prefix パラメータを使用して AWS Glue に仮想環境を構築させ、それを Amazon S3 にキャッシュさせることができます。このアプローチは、--additional-python-modules のシンプルさと、キャッシュされた仮想環境のパフォーマンス上の利点を組み合わせたものです。
仕組み
--python-virtual-env-storage-prefix を指定すると、AWS Glue は以下を実行します。
-
初回実行時 (キャッシュミス) – AWS Glue は、numpy、pandas、pyarrow などのコンテナパッケージを継承する
--system-site-packagesを使用して仮想環境を作成します。AWSGlue は次に、--additional-python-modules から pip を使用してパッケージをインストールし、仮想環境を.tar.gzファイルとしてパッケージ化し、後で再利用できるように Amazon S3 プレフィックスにアップロードします。 -
後の実行時 (キャッシュヒット) – AWS Glue はキャッシュされた
.tar.gzファイルを Amazon S3 からダウンロードし、抽出して、仮想環境を使用するように Spark ドライバーとエグゼキュターを設定します。pip のインストールは行われません。
手動構築の仮想環境との違い
次の表は、サービス生成の仮想環境と手動構築のアプローチを比較したものです。
機能 |
サービス生成 venv |
手動構築 venv |
|---|---|---|
構築の責任 |
AWS Glue が venv を自動で構築 |
Docker で venv を構築 |
コンテナパッケージ |
|
すべてのパッケージを明示的に含める必要あり |
初回実行のレイテンシー |
pip のインストール、パッケージング、Amazon S3 アップロードにかかる時間が追加される |
なし (venv が事前に構築されているため) |
2 回目以降の実行のレイテンシー |
Amazon S3 のダウンロードと抽出にかかる時間が追加される |
Amazon S3 のダウンロードと抽出にかかる時間が追加される |
決定論 |
パッケージバージョンの固定が推奨される |
バージョンはビルド時にロックされるため、完全に決定論的 |
PyPI アクセス |
初回実行時に必要 |
venv はオフラインで構築されるため不要 |
サービス生成仮想環境の設定
--python-virtual-env-storage-prefix パラメータは、AWS Glue が構築した仮想環境を s3:// 形式で保存する Amazon S3 の場所を指定します。AWSGlue は、最初のジョブ実行時にこのプレフィックスで仮想環境をキャッシュし、後の実行時に再利用します。path/
サービス生成仮想環境を有効にするには、--python-virtual-env-storage-prefix パラメータをジョブに追加し、既存の --additional-python-modules パラメータを保持します。
"--additional-python-modules": "requests==2.32.3,scikit-learn==1.5.0" "--python-virtual-env-storage-prefix": "s3://amzn-s3-demo-bucket/venv-cache/"
また、次のオプションパラメータを使用することもできます。
-
--python-virtual-env-version– キャッシュされた仮想環境のバージョン識別子。この値を変更してキャッシュを無効にし、AWS Glue に仮想環境の再構築を強制します。値は文字列であるため、増分番号、日付、ビルド識別子など、ワークフローに適したバージョニングスキームを使用できます。デフォルト値は0です。 -
--python-modules-installer-option –
--no-depsや--index-urlなどのオプションを pip に渡します。
既存のジョブのキャッシュを有効にするには、ストレージプレフィックスパラメータを追加します。AWS Glue が仮想環境を構築してアップロードするため、初回実行には時間がかかりますが、以降の実行ではキャッシュされた仮想環境が使用され、pip 解決は実行されません。
# Before "--additional-python-modules": "requests==2.32.3" # After "--additional-python-modules": "requests==2.32.3" "--python-virtual-env-storage-prefix": "s3://amzn-s3-demo-bucket/venv-cache/"
AWS Glue による仮想環境のキャッシュ方法
AWS Glue はジョブ設定をキーとしてキャッシュを管理します。設定には、--additional-python-modules のモジュール、--python-modules-installer-option の値、AWS Glue のバージョン、--python-virtual-env-version の値が含まれます。
設定が変更されない場合、キャッシュヒットが発生します。これらの値のいずれかを変更すると、AWS Glue は新しい仮想環境を構築し、新しいキャッシュエントリを作成します。
AWS Glue は、キャッシュされた各仮想環境をストレージプレフィックスの個別のキーに保存します。同じモジュールとインストーラオプションを使用するジョブは、同じキャッシュエントリを共有します。
制限事項
-
AWS Glue 6.0 以降が必要。
-
初回実行では、依存関係を解決するために PyPI またはプライベートインデックスへのアクセスが必要です。
-
numpy や pandas などのコンテナパッケージは継承されますが、バージョン固定は行われません。ジョブでコンテナパッケージの正確なバージョンが必要な場合は、代わりに
--python-virtual-envを使用します。 -
キャッシュは設定によってキー付けされます。モジュールまたはバージョンを変更すると新しいキャッシュエントリが作成され、それ以前のエントリは削除するまで Amazon S3 に残ります。
独自の仮想環境の構築
AWS Glue 5.0 以降では、仮想環境を自分で構築し、--python-virtual-env パラメータで参照することができます。このアプローチは、完全な再現性、コンテナパッケージの正確なバージョン、または CI/CD パイプラインで実行されるビルドが必要な場合に使用します。
前提条件
作業を開始する前に、以下の準備が整っていることを確認します。
-
Docker
を Docker ウェブサイトからダウンロードし、ローカルマシンにインストールすることで、AWS Glue 互換環境で仮想環境を構築できます。 -
パッケージ化された仮想環境をアップロードするための Amazon S3 バケット
-
Amazon S3 へのアップロードおよび AWS Glue ジョブパラメータの更新に必要なアクセス許可が設定された AWS CLI
各 AWS Glue バージョンの Python バージョンとプラットフォームの互換性の詳細については、「付録 B: AWS Glue 環境の詳細」を参照してください。
手順 1: 要件ファイルを作成する
仮想環境のパッケージを定義する要件ファイルを 2 つ作成します。
-
GitHub ウェブサイトの aws-glue-libs リポジトリから AWS Glue バージョンの
base-requirements.txtをダウンロードします。このファイルには、標準の AWS Glue コンテナが提供するパッケージの一覧が表示されます。このガイド内のリストと同じものについては、「AWS Glue で提供済みの Python モジュール」を参照してください。-
AWS Glue 5.0 – GitHub ウェブサイトの base-requirements.txt
-
AWS Glue 5.1 – GitHub ウェブサイトの base-requirements.txt
-
AWS Glue 6.0 – GitHub ウェブサイトの base-requirements.txt
-
-
additional-requirements.txtを作成します。既存の--additional-python-modulesパラメータからパッケージを 1 行に 1 つずつ追加します。例えば、次のようになります。cryptography requests-oauthlib sqlalchemy
重要
ジョブで GlueContext や DynamicFrame などの AWS Glue Python ライブラリを使用している場合は、PyPI ウェブサイトの AWSGlueDataplanePython
AWS Glue のバージョン |
パッケージバージョン |
|---|---|
5.0 |
|
5.1 |
|
6.0 |
|
ステップ 2: を作成するDockerfile
ターゲットの AWS Glue バージョンの環境に合致する Dockerfile を作成します。プラットフォームと Python バージョンの詳細については、「付録 B: AWS Glue 環境の詳細」を参照してください。
AWS Glue 5.0 および 5.1 は、Amazon Linux 2023 で Python 3.11 を使用します。
FROM --platform=linux/amd64 public.ecr.aws/amazonlinux/amazonlinux:2023-minimal RUN dnf install -y python3.11 zip && \ dnf clean all WORKDIR /build
AWS Glue 6.0 は、Amazon Linux 2023 で Python 3.13 を使用します。
FROM --platform=linux/amd64 public.ecr.aws/amazonlinux/amazonlinux:2023-minimal RUN dnf install -y python3.13 zip && \ dnf clean all WORKDIR /build
ステップ 3: コンテナを構築して起動する
Docker イメージを構築します。次に、要件ファイルとジョブスクリプトがマウントされたコンテナを起動します。
docker build --platform linux/amd64 -t glue-venv-builder . docker run --platform linux/amd64 \ -v $(pwd)/base-requirements.txt:/working_dir/base-requirements.txt:ro \ -v $(pwd)/additional-requirements.txt:/working_dir/additional-requirements.txt:ro \ -v $(pwd)/my_glue_script/:/working_dir/my_glue_script/:ro \ -v $(pwd):/output \ -w /working_dir \ -it glue-venv-builder bash
このコマンドは、要件ファイルと AWS Glue ジョブスクリプトディレクトリをマウントします。次の手順では、スクリプトディレクトリをインポート分析に使用します。
手順 4: 仮の venv を構築し、必要なパッケージを検出する
コンテナ内で、AWS Glue ランタイムをミラーリングする仮の venv を構築します。次に、静的分析を使用して、ジョブに必要な最小限のパッケージセットを見つけます。
Python 3.11 を使用する AWS Glue 5.0 および 5.1 の場合は、次のコマンドを実行します。
# Create a temporary venv to reproduce the AWS Glue runtime environment python3.11 -m venv temp_venv source temp_venv/bin/activate python3.11 -m pip install --upgrade pip # Install base container libraries (mirrors what the AWS Glue container provides) python3.11 -m pip install -r base-requirements.txt # Install additional Python modules on top (mirrors how AWS Glue installs them at runtime) python3.11 -m pip install -r additional-requirements.txt # Freeze the full resolved environment pip freeze > full-requirements.txt # Install analysis tools python3.11 -m pip install pipreqs pip-tools # Use pipreqs to discover what the script actually imports # --mode no-pin outputs package names without versions pipreqs --mode no-pin --savepath discovered-requirements.txt /working_dir/my_glue_script # Remove packages provided by the Spark runtime sed -i '/pyspark/d' discovered-requirements.txt sed -i '/py4j/d' discovered-requirements.txt # Remove awsglue - install AWSGlueDataplanePython in Step 5 instead sed -i '/awsglue/d' discovered-requirements.txt # Use pip-compile to resolve the full dependency tree of the discovered packages, # constrained to the versions from the temporary venv pip-compile discovered-requirements.txt -c full-requirements.txt -o final-requirements.txt echo "=== Final requirements.txt ===" cat final-requirements.txt # Deactivate and discard the temporary venv deactivate rm -rf temp_venv
Python 3.13 を使用する AWS Glue 6.0 の場合は、次のコマンドを実行します。
# Create a temporary venv to reproduce the AWS Glue runtime environment python3.13 -m venv temp_venv source temp_venv/bin/activate python3.13 -m pip install --upgrade pip # Install base container libraries (mirrors what the AWS Glue container provides) python3.13 -m pip install -r base-requirements.txt # Install additional Python modules on top (mirrors how AWS Glue installs them at runtime) python3.13 -m pip install -r additional-requirements.txt # Freeze the full resolved environment pip freeze > full-requirements.txt # Install analysis tools python3.13 -m pip install pipreqs pip-tools # Use pipreqs to discover what the script actually imports # --mode no-pin outputs package names without versions pipreqs --mode no-pin --savepath discovered-requirements.txt /working_dir/my_glue_script # Remove packages provided by the Spark runtime sed -i '/pyspark/d' discovered-requirements.txt sed -i '/py4j/d' discovered-requirements.txt # Remove awsglue - install AWSGlueDataplanePython in Step 5 instead sed -i '/awsglue/d' discovered-requirements.txt # Use pip-compile to resolve the full dependency tree of the discovered packages, # constrained to the versions from the temporary venv pip-compile discovered-requirements.txt -c full-requirements.txt -o final-requirements.txt echo "=== Final requirements.txt ===" cat final-requirements.txt # Deactivate and discard the temporary venv deactivate rm -rf temp_venv
注記
final-requirements.txt を確認して、正しいか確かめます。ジョブが動的インポートまたは条件付きインポートを使用している場合、pipreqs がそれらを検出できない可能性があります。これらのパッケージを手動でファイルに追加します。
手順 5: 本番用の venv を構築する
ジョブに必要なパッケージのみを使用して最終的な venv を作成します。次に、それを tarball としてパッケージ化します。
Python 3.11 を使用する AWS Glue 5.0 および 5.1 の場合は、次のコマンドを実行します。
python3.11 -m venv pyspark_venv source pyspark_venv/bin/activate python3.11 -m pip install --upgrade pip python3.11 -m pip install -r final-requirements.txt # Install the AWS Glue Python library that matches your AWS Glue version (see the version # table in Step 1). Use 5.0.0 for AWS Glue 5.0, or 5.1.0 for AWS Glue 5.1. python3.11 -m pip install AWSGlueDataplanePython==5.0.0python3.11 -m pip install venv-pack venv-pack -f -o pyspark_venv.tar.gz cp pyspark_venv.tar.gz /output/ exit
Python 3.13 を使用する AWS Glue 6.0 の場合は、次のコマンドを実行します。
python3.13 -m venv pyspark_venv source pyspark_venv/bin/activate python3.13 -m pip install --upgrade pip python3.13 -m pip install -r final-requirements.txt # Install the AWS Glue Python library (see version table in Step 1) python3.13 -m pip install AWSGlueDataplanePython==6.0.0 python3.13 -m pip install venv-pack venv-pack -f -o pyspark_venv.tar.gz cp pyspark_venv.tar.gz /output/ exit
ステップ 6: Amazon S3 にアップロードする
パッケージ化された仮想環境を Amazon S3 バケットにアップロードします。
aws s3 cp pyspark_venv.tar.gz s3://amzn-s3-demo-bucket/path/pyspark_venv.tar.gz
手順 7: ジョブパラメータを更新する
AWS Glue ジョブ設定を更新して、--additional-python-modules の代わりに --python-virtual-env を使用します。
--additional-python-modules パラメータを削除し、アップロードした tarball を指す --python-virtual-env パラメータを追加します。
# Before "--additional-python-modules": "cryptography" # After (remove --additional-python-modules entirely) "--python-virtual-env": "s3://amzn-s3-demo-bucket/path/pyspark_venv.tar.gz"
Kiro を使用した移行自動化
自動化されたアプローチを利用したい場合は、Kiro ウェブサイトで入手可能な Kiro
仕組み
AWS Glue ジョブを --additional-python-modules から --python-virtual-env に移行するように Kiro に要求すると、Kiro は以下を実行します。
-
リクエストから AWS Glue バージョン、
--additional-python-modulesの値、ジョブスクリプトを抽出します。 -
AWS Glue ドキュメントから AWS Glue バージョンのベースコンテナモジュールリストを取得します。
-
base-requirements.txt、additional-requirements.txt、Dockerfile、ビルドスクリプトを含むビルドアーティファクトを作業ディレクトリ内に作成します。 -
AWS Glue 互換環境の Docker イメージを構築します。
-
非インタラクティブコンテナで検出とパッケージングのワークフローを実行します。
-
pyspark_venv.tar.gzを生成し、Amazon S3 における送信先の入力を求め、tarball をアップロードします。 -
更新されたジョブパラメータを表示します。
リクエスト例
AWS Glue バージョン、追加の Python モジュール、ジョブスクリプトを指定します。例えば、次のようになります。
I have a Glue 5.1 job with the following: --additional-python-modules: ephem, awscli Glue job script: import awscli import ephem Help me migrate to using --python-virtual-env.
Kiro スキルの取得
venv-migration スキルファイルは、このガイドではなく aws-glue-libs リポジトリに保持されます。スキルファイルとインストール手順については、GitHub ウェブサイトの venv-migration skill
制限事項
-
Kiro を実行するには、コマンドライン環境で Docker が利用可能である必要があります。
-
スクリプトソースに表示されない動的インポートと条件付きインポートは、自動的には検出されません。生成された
final-requirements.txtファイルを確認し、不足しているパッケージを手動で追加します。 -
ジョブで
--index-urlを使用してプライベート pip インデックスを使用する場合は、Docker コンテナ内のそのインデックスへのネットワークアクセスを設定する必要があります。 -
ビルド中の pip の競合には、手動での解決が必要になる場合があります。詳細については、「トラブルシューティング」を参照してください。
トラブルシューティング
以下のセクションを使用して、AWS Glue で Python 仮想環境を使用する際の一般的な問題を解決します。
pip バージョンの競合の解決
pip バージョンの競合とは、2 つのパッケージに対して、同一の依存関係の非互換バージョンが必要になることを意味します。競合を見つけて修正するには、以下の手順を実行します。
-
pip エラー出力を読み込みます。解決に完全に失敗した場合、この出力には競合する各要件とそれを導入したパッケージが示されます。
-
何もインストールせずに pip の解決内容をプレビューします。次の例のように、インストールコマンドに
--dry-run --report install-report.jsonを追加します。pip install -r additional-requirements.txt --dry-run --report install-report.json -
install-report.jsonを検査します。このレポートには pip が選択したすべてのパッケージの一覧が表示されるので、サイレントダウングレードを確認できます。 -
重要でないパッケージのバージョン固定を緩和するか、制約を削除します。
ModuleNotFoundError の解決
このエラーは、仮想環境に必要なパッケージが含まれていないことを示します。一般的な原因は以下の通りです。
-
ジョブに必要なベースコンテナライブラリを含めていなかった。手動構築の仮想環境は AWS Glue コンテナからパッケージを継承しません。
-
静的分析中に pipreqs が検出できなかった動的インポートをジョブが使用している。
-
ジョブにはエグゼキュターノードへの PySpark 依存関係が必要です。
この問題を解決するには、不足しているパッケージを追加して仮想環境を再構築します。手順は、ジョブが使用しているアプローチによって異なります。
-
手動構築 venv – パッケージを
final-requirements.txtに追加し、仮想環境を再構築して再度アップロードします。 -
サービス生成 venv – パッケージを
--additional-python-modulesに追加します。新しいモジュールリストはキャッシュキーを変更するため、AWS Glue は次のジョブ実行時に新しい仮想環境を構築します。
venv tarball サイズの縮小
パッケージ化された仮想環境が大きすぎる場合は、次の方法でサイズを縮小します。
-
テストフレームワークや開発ツールなど、スクリプトがインポートしない不要なパッケージを削除します。
-
推移的な依存関係を手動で制御するパッケージには、
pip install --no-depsを使用します。 -
スクリプトが直接インポートするパッケージのみを含めて、pip-compile に必要最小限の推移的依存関係を解決させます。
プラットフォーム互換性エラーの解決
これらのエラーは、venv のパッケージが別のオペレーティングシステムまたはアーキテクチャ用に構築された場合に発生します。これらのエラーを回避する方法は以下の通りです。
-
常に
--platform linux/amd64フラグを使用して Docker コンテナ内に仮想環境を構築します。 -
ホイールプラットフォームタグがターゲットの AWS Glue バージョンと一致しているか確認します。例えば、AWS Glue 5.0 および 5.1 には、
manylinux2014_x86_64または互換性のあるプラットフォームタグが必要です。 -
Docker がない macOS または Windows に直接仮想環境を構築しないでください。