---
title: "AWS GlueでETLジョブを動かす手順｜PySparkスクリプトとDPU課金の設計"
url: "https://www.issoh.co.jp/tech/details/17472/"
published: 2026-09-07
updated: 2026-10-19
categories: ["AWS"]
publisher: "株式会社一創"
---

# AWS GlueでETLジョブを動かす手順｜PySparkスクリプトとDPU課金の設計

AWS Glueの解説は「サーバーレスのデータ統合サービス」で終わるものが多く、いざジョブを作るとIAMロールの権限不足とS3パスの指定でつまずきます。この記事はS3とIAMの準備からクローラー登録、PySparkスクリプト、AWS CLIでの起動、DPU課金の実額計算までを一本の手順につなぎました。版番号は2026年9月7日時点の公式ドキュメントの値のみを使用。定義と機能一覧そのものは[AWS Glueとは？機能・料金・使い方とWorkflowsの仕組みまで徹底解説](https://www.issoh.co.jp/tech/details/7251/)で扱っています。

## まとめ｜Glue 6.0でジョブを動かす前に決める4項目と課金の目安

先に結論です。Glueでジョブを組む前に決めるのは、①ジョブ種別（Spark／Python shell／Ray）、②Glueバージョン、③ワーカータイプと台数、④タイムアウト値の4つ。これが固まれば残りはスクリプトとCLIの作業になります。

費用の桁も先に。標準実行は1 DPU-時間あたり0.44 USD、Flex実行なら0.29 USD。G.2Xを4台（8 DPU）で30分回すジョブは 8 × 0.5 × 0.44 ＝ 1.76 USD、日次30回で月約53 USDです。

版番号の注意点はひとつ。バージョン未指定のジョブはGlue 5.1になり、Glue 6.0はSpark 4.1.1・Python 3.13へ上がる一方でEMRFSが外れました。既存スクリプトを直接6.0へ載せ替えると落ちる箇所があるため、移行は最終章の二段構えで進めてください。

## Glueジョブ3種の違いとGlue 6.0で変わるランタイム版番号の確認

Glueのジョブは3種類あり、選び間違えると後から書き直しになります。

### Sparkジョブ・Python shell・Rayの使い分けと課金単位の差

Sparkジョブはジョブコマンド `glueetl` で動く分散処理型で、数十GB規模のファイル群を結合・変換する用途に向きます。ストリーミングは `gluestreaming`、単一プロセスの軽量処理は `pythonshell` と、公式の[Sparkジョブのプロパティ定義](https://docs.aws.amazon.com/glue/latest/dg/add-job.html)でコマンド名まで分かれています。判断の目安はデータ量。数百MB程度でSQLとAPI呼び出しだけならPython shell、パーティションをまたぐ集計が入るならSparkジョブです。

課金単位の差も見落とせません。Sparkジョブはワーカー台数×DPUの秒単位課金なので、台数を増やして実行時間が縮んでも総額が減らない場面がある。ETL工程そのものの設計は[ETLとは？仕組み・ELTとの違い・ツール選定から導入判断まで解説](https://www.issoh.co.jp/column/details/13364/)で扱っています。

### Glue 6.0とGlue 5.1のSpark版差と旧版EOL後に使える版

2026年9月7日時点で公式の[AWS Glueバージョン一覧](https://docs.aws.amazon.com/glue/latest/dg/release-notes.html)に載るランタイムは次のとおり。Glue 6.0はSpark 4.1.1・Python 3.13・Scala 2.13.17・Java 17で、Iceberg 1.11.0／Hudi 1.1.1／Delta Lake 4.2.0を同梱。Glue 5.1はSpark 3.5.6・Python 3.11で、こちらが**バージョン未指定で作成したジョブの既定値**です。6.0ではEMRFSが削除されS3AがS3への唯一のコネクタになり、AWS SDK for Java もv2のみ。v1のクラスを参照するカスタムJARはここで落ちます。

旧版の扱いも確定済みです。[バージョンサポートポリシー](https://docs.aws.amazon.com/glue/latest/dg/glue-version-support-policy.html)ではGlue 0.9・1.0・2.0のEnd of Lifeが2026年4月1日と明記され、到達後は新規ジョブの作成もジョブ実行の開始も不可になりました。Python shellのPythonShell 3.6はEnd of Supportが2026年3月31日。新規に組むなら5.1か6.0の二択です。

## S3のデータ配置とIAMロールをジョブ実行前に用意する準備手順

Glueで最初に詰まるのはスクリプトではなく権限とパスです。

### AWSGlueServiceRoleとS3バケットポリシーの最小権限の書き方

ジョブに渡すIAMロールは、Glueサービスが引き受けられる信頼関係、対象S3プレフィックスへの読み書き、Data Catalogの操作権限の3点セットで考えます。Data Catalogをメタストアとして使う設定を有効にするなら `glue:CreateDatabase` が必要で、この権限が無いと既定データベースの作成に失敗します。

権限の絞り方はバケット単位ではなくプレフィックス単位。`raw` 配下は読み取りのみ、`curated` 配下は書き込みまで、一時ディレクトリは削除まで、という3段構えにすれば生データの上書き事故を仕組みで防げます。テーブル単位・列単位まで制御する段階では権限管理を別レイヤに出す判断になり、その選択肢は[AWS Lake Formationとは？データレイクの権限管理・使い方・料金と実装判断を解説](https://www.issoh.co.jp/tech/details/15517/)で扱いました。

### 入力S3プレフィックスの日付分割とパーティション設計の判断基準

入力側のS3レイアウトが、後のクエリコストを決めます。日次で届くファイルなら `dt=2026-09-01` のようにキー名を含めたディレクトリで区切ってください。日付なしのフラット配置にすると、クローラーが毎回全件をスキャンし、ジョブ側のフィルタでもプルーニングが効きません。

もうひとつの軸はファイルサイズ。1ファイル数KBのJSONが何万件も並ぶ構造は、Sparkのタスク起動オーバーヘッドで実行時間が伸びます。変換後の出力は128MB前後のParquetにまとめる方向で `partitionBy` の粒度を決めるのが目安。レイク側から整えるなら[データレイクとは？データウェアハウス・レイクハウスとの違いを実装視点で解説](https://www.issoh.co.jp/tech/details/13388/)をご覧ください。

## クローラーでS3のスキーマをData Catalogへ登録する設定手順

スクリプトを書く前に、クローラーでテーブル定義を作ります。

### クローラーの実行間隔とテーブル更新動作の指定方法で詰まる箇所

クローラーはS3プレフィックスを走査してスキーマを推論し、Data Catalogにテーブルを作ります。誤りやすいのは更新動作。既存テーブルに「スキーマを更新する」を選ぶと、ある日届いた壊れたファイルの型推論結果でカラム型が上書きされ、翌日のジョブが型不一致で落ちます。本番の日次バッチでは、パーティション追加のみ許可してスキーマ変更は無視する設定が安全です。

実行間隔はパーティションが増える頻度に合わせます。1日1回の取り込みなら1日1回で足り、5分おきの設定はDPU課金だけを増やす結果に。クローラーの料金はETLジョブと同じ1 DPU-時間あたり0.44 USDで、[AWS Glueの料金ページ](https://aws.amazon.com/jp/glue/pricing/)に秒単位課金として示されています。パーティション追加をジョブ側の `enableUpdateCatalog` で済ませられるなら、クローラーは初回だけに使う運用も可能です。

### Data Catalogの無料枠100万オブジェクトとパーティション数の上限設計

Data Catalogは規模が小さいうちは実質無料です。公式料金ページの記載では、ストレージは最初の100万オブジェクトまで、リクエストは毎月100万回までが無料枠で、超過分は10万オブジェクトあたり月0.01 USD。ただし5分刻みのパーティションを1年分作ると10万件を超え、クエリ実行時のパーティション取得が遅くなります。作ったテーブルにクエリを投げて確かめるなら、同じData Catalogを参照する[Amazon Athena（アテナ）とは？使い方・クエリの書き方・料金・Redshiftとの違いを解説](https://www.issoh.co.jp/tech/details/4865/)の手順が最短です。

## PySparkスクリプトの骨組みと引数受け渡しを書き切る実装手順

Glueのスクリプトには決まった骨組みがあり、覚えれば毎回同じ形で書けます。

### getResolvedOptionsで引数を受けるスクリプトの最小構成

ジョブパラメータはキー名に `--` を付けて渡し、スクリプト側では `getResolvedOptions` で受け取ります。入出力パスを引数化すれば、開発用と本番でスクリプトを分ける必要がなくなる。次は、S3のJSONを読み、条件で絞り、日付パーティション付きのParquetとして書き出す最小構成です。

```
import sys
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

args = getResolvedOptions(sys.argv, ["JOB_NAME", "src_path", "dst_path"])

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args["JOB_NAME"], args)

src = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": [args["src_path"]], "recurse": True},
    format="json",
)

df = src.toDF().filter("status = 'paid'")
df.write.mode("append").partitionBy("dt").parquet(args["dst_path"])

job.commit()
```

末尾の `job.commit` を忘れると、ジョブブックマークが進まず次回実行で同じファイルを再処理します。ローカルで動作を確かめるなら、awslabsが公開する[aws-glue-libs](https://github.com/awslabs/aws-glue-libs)を使ってください。Glue 5.0はglue-5.0、5.1はglue-5.1、6.0はmainブランチという対応です。

### DynamicFrameとDataFrameの選択基準と相互変換の書き方

GlueにはSparkのDataFrameに加えてDynamicFrameがあり、どちらを使うか毎回問われます。判断基準は「スキーマが揺れるか」の一点。フィールドが日によって増減し同じキーに文字列と数値が混在するデータでは、スキーマを固定しないDynamicFrameが有利で、`ResolveChoice` による型の解決や `Relationalize` によるネスト展開が使えます。

スキーマが安定しているなら、DataFrameに変換してSpark SQLで書くほうが読みやすく、既存のSpark資産も持ち込めます。上のように `toDF` で変換し、書き込み直前に `DynamicFrame.fromDF` で戻す使い方が実務では多い。両者を混ぜると後任がデバッグできないため、片方に寄せてください。

### datalake-formats指定でIcebergテーブルへ書き込む設定

更新と削除が入るテーブルにするならIcebergを使います。ジョブパラメータ `datalake-formats` に `iceberg` を指定するだけでフレームワークが有効になり、追加のコネクタ導入は不要。指定方法は[AWS GlueでIcebergフレームワークを使う](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-format-iceberg.html)に記載があります。カタログをData Catalogへ向ける設定は、次の `conf` をジョブパラメータへ渡します。

```
--datalake-formats iceberg

--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
--conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog
--conf spark.sql.catalog.glue_catalog.warehouse=s3://example-bucket/iceberg/
--conf spark.sql.catalog.glue_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog
--conf spark.sql.catalog.glue_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO
```

同梱されるIcebergの版はGlueバージョンに紐づきます。Glue 5.1はIceberg 1.10.0でフォーマットバージョン3.0、Glue 6.0はIceberg 1.11.0でVARIANT型や削除ベクター、行系譜の追跡まで入りました。フォーマットバージョンを上げたテーブルは古いGlueのジョブから読めなくなるため、上げる順序に注意。Pythonライブラリを足すなら `additional-python-modules`、pip3へオプションを渡すなら `python-modules-installer-option` と、いずれも[ジョブパラメータの一覧](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html)にまとまっています。

## AWS CLIでジョブを作成して実行し失敗を切り分ける操作手順

GUIで作ると設定が手元に残りません。CLIなら定義が構成管理の対象になります。

### create-jobとstart-job-runでジョブを登録して起動する流れ

スクリプトをS3に置いたら、ジョブ定義を作って起動します。次の2コマンドで、Glue 6.0・G.2X×4台・タイムアウト60分のジョブが登録され、日付パーティションを引数で差し替えて実行できます。

```
aws glue create-job \
  --name orders-etl \
  --role AWSGlueServiceRole-orders \
  --glue-version 6.0 \
  --worker-type G.2X \
  --number-of-workers 4 \
  --timeout 60 \
  --command '{"Name":"glueetl","PythonVersion":"3","ScriptLocation":"s3://example-bucket/scripts/orders_etl.py"}' \
  --default-arguments '{"--job-language":"python","--TempDir":"s3://example-bucket/tmp/","--datalake-formats":"iceberg","--enable-continuous-cloudwatch-log":"true","--job-bookmark-option":"job-bookmark-enable","--src_path":"s3://example-bucket/raw/orders/","--dst_path":"s3://example-bucket/curated/orders/"}'

aws glue start-job-run \
  --job-name orders-etl \
  --arguments '{"--src_path":"s3://example-bucket/raw/orders/dt=2026-09-01/"}'
```

押さえる点は2つ。`default-arguments` が定義側の既定値、`arguments` が実行時の上書きです。もうひとつは同時実行数の既定値が1という仕様で、前回の実行が終わる前に起動するとエラーが返る。日次バッチが前日分を引きずるなら、ジョブ実行のキューイングを有効にして即時失敗を順番待ちに変える判断も取れます。

### 継続ログとSpark UIで実行時エラーの原因を絞り込む確認手順

上の定義には `enable-continuous-cloudwatch-log` を入れてあります。この指定が無いとログはジョブ完了後にしか見えず、10分走って落ちるジョブの原因追跡が遅れる。継続ログを有効にすれば、ドライバとエグゼキュータのストリームがリアルタイムに流れます。

切り分けは、CloudWatch Logsのドライバログで例外クラス名を確認してから3方向に振り分けます。権限系（AccessDenied）ならIAMロールとバケットポリシー、型系（AnalysisException）ならスキーマとクローラーの更新動作、メモリ系（OutOfMemory）ならワーカータイプとパーティション偏り。実行計画まで見るならSpark UIを有効にします。タイムアウトで止まったジョブは再試行の対象外という仕様があるため、`--timeout` と再試行回数はセットで決めてください。

## ワーカータイプ別のDPU換算とFlex実行で費用を抑える判断基準

Glueの費用はワーカータイプ×台数×時間で決まります。

### G.1XからG.16Xまでのワーカー仕様とDPU課金額の対応表

1 DPUは4 vCPUと16 GBメモリに相当し、ワーカータイプごとにDPU数が決まっています。次の表は公式ジョブプロパティの仕様と料金ページの単価0.44 USD／DPU-時間を掛けた、ワーカー1台あたりの1時間換算額です。

| ワーカータイプ | DPU      | vCPU・メモリ       | 1台1時間の換算額 |
| ------- | -------- | -------------- | --------- |
| G.025X  | 0.25 DPU | 2 vCPU・4 GB    | 0.11 USD  |
| G.1X    | 1 DPU    | 4 vCPU・16 GB   | 0.44 USD  |
| G.2X    | 2 DPU    | 8 vCPU・32 GB   | 0.88 USD  |
| G.4X    | 4 DPU    | 16 vCPU・64 GB  | 1.76 USD  |
| G.8X    | 8 DPU    | 32 vCPU・128 GB | 3.52 USD  |
| G.12X   | 12 DPU   | 48 vCPU・192 GB | 5.28 USD  |
| G.16X   | 16 DPU   | 64 vCPU・256 GB | 7.04 USD  |

ディスク容量も異なり、G.1Xは94 GB（空き約44 GB）、G.2Xは138 GB（空き約78 GB）。シャッフルの大きいジョブでディスクを使い切ると落ちるため、台数ではなくタイプを上げる判断が要ります。G.025Xは3.0系以降のストリーミング専用でバッチには選べません。G.12X・G.16XとR系は起動待ち時間が長いと公式に注記されています。

### タイムアウト既定値480分の変更点とFlex実行の適用可否条件

タイムアウトの既定値はGlueバージョンで変わりました。公式のジョブプロパティ定義では、空欄時の既定はGlue 4.0以前が2,880分、Glue 5.0以降が480分で、上限はいずれも7日（10,080分）です。4.0系の設定をそのまま5.0以降へ移すと、48時間まで許していたジョブが8時間で止まる計算になる。逆に暴走ジョブの課金が48時間分積み上がる事故は起きにくくなりました。

費用を落とす手段としてはFlex実行が効きます。単価は0.29 USD／DPU-時間で標準の0.44 USDから約34%安くなり、課金もワーカーが動いた時間の合計で計算される仕組み。ただしGlue 3.0以降かつG.1XまたはG.2Xのみという適用条件があり、G.12X・G.16XとR系は非対応です。開始時刻が保証されないため、後続のBI更新が時刻で待つ本番パイプラインでは使いません。ノーコードでデータ準備だけを済ませたい工程なら、課金単位が異なる[AWS Glue DataBrewとは？ノーコードのデータ準備の仕組み・料金・Glue Studioとの使い分けを実装視点で解説](https://www.issoh.co.jp/tech/details/15782/)のほうが安く上がります。

## Glueを採用しない条件とLambda・Step Functionsとの境界

Glueは万能ではなく、選ぶと割高になる領域がはっきりしています。

### 小規模バッチでGlueが割高になる損益分岐とLambdaへの寄せ方

結論として、**1回の処理が数百MB以下で完結し実行時間が5分未満のバッチに、GlueのSparkジョブは選びません**。最小構成のG.1X×2台でも2 DPUが立ち上がり、Sparkのクラスタ起動に1分前後を取られます。同じ処理をLambdaでPandasやDuckDBで回せば、メモリ1,024 MBで30秒なら1回あたり0.0005 USD程度に収まり、桁が2つ違う。

Glueに寄せる判断が正しくなるのは、単一プロセスのメモリに載らないデータ量になったとき、複数テーブルの結合が入ったとき、スキーマの揺れをResolveChoiceで吸収したいときの3条件です。どれにも当てはまらないならGlueは過剰。依存関係と再試行の制御が課題なら、それは[AWS Step Functionsとは？ステートマシンの仕組み・料金と2種のワークフロー・採用判断を実装者目線で解説](https://www.issoh.co.jp/tech/details/15429/)で扱う領域です。Glue Workflowsで足りるかは、Glue以外のサービスを挟むかで切り分けます。挟むならStep Functionsです。

どこからDWHへ渡すかの線引きは、データ量と更新頻度、運用人数で変わります。設計から実装・運用まで相談したい場合は、[データ分析基盤構築・MLOps構築支援](https://www.issoh.co.jp/service/ai/data-platform/)で構成案づくりから対応しています。

### Glue 4.0以前から6.0へ移す作業とFGAC非互換への対処

移行で最も踏むのはLake Formation連携の非互換です。公式リリースノートには、Glue 4.0以前で使えたGlueContextベース（DynamicFrame経由）のテーブルレベルアクセス制御がGlue 5.0以降では非サポートと明記され、Sparkネイティブのきめ細かなアクセス制御（FGAC）へ移す必要があります。権限まわりを含むジョブでは、スクリプトの書き換えとLake Formation側の設定変更が同時に発生する点に注意してください。

手順は、まず4.0のジョブを5.1で動かして差分を潰し、そのうえで6.0へ上げる二段構えです。6.0はSpark 4.1.1へメジャー版が上がり、EMRFS削除とAWS SDK for Java v1の除去が重なるため、5.1を経由せず一気に上げると切り分けができません。非互換点は[AWS Glue for Sparkジョブをバージョン6.0へ移行する](https://docs.aws.amazon.com/glue/latest/dg/migrating-version-60.html)に整理されています。Python shellジョブはGlueVersionの指定が挙動に影響しないと公式に書かれており、Python 3対応の確認だけで済みます。

## よくある質問

問い合わせの多い5点です。回答は2026年9月7日時点の公式ドキュメントに基づきます。

### AWS Glueのバージョンを指定しないとどうなりますか？

バージョンを指定せずに作成したジョブは、Glue 5.1が適用されます。ランタイムはSpark 3.5.6・Python 3.11・Scala 2.12.18・Java 17。既存スクリプトがPython 3.10以前の書き方に依存している場合や、Spark 3.3系の挙動を前提にしている場合、意図せず新しい版で動くことになります。CLIやIaCでジョブを作るなら `--glue-version` を明示してください。

### Glue 2.0のジョブはまだ動きますか？

動きません。バージョンサポートポリシーでは、Glue 0.9・1.0・2.0のEnd of Lifeは2026年4月1日で、到達後は新規ジョブや対話型セッションの作成ができず、実行中のジョブも停止され、SDKとAPIからバージョン自体が削除されます。2026年9月時点で運用継続という選択肢はありません。3.0系以降へ移し、新規は5.1か6.0で組んでください。

### DPU課金は実際いくらになりますか？

標準実行のSparkジョブとクローラーは1 DPU-時間あたり0.44 USDで、課金は秒単位です。公式料金ページの例では、6 DPUで15分実行したジョブは 6 × 0.25時間 × 0.44 USD ＝ 0.66 USDと計算されます。G.2Xを4台使うと8 DPUなので、30分のジョブで1.76 USD、日次30回で月約53 USD。Flex実行なら単価が0.29 USDに下がり、同じジョブが月約35 USDになります。

### クローラーは必ず使わないといけませんか？

必須ではありません。テーブル定義をSQLやIaCで直接作れるなら、クローラーを常設せずに済みます。ジョブ側で `enableUpdateCatalog` を有効にすればパーティション追加をジョブから登録でき、スキーマが安定した構成ではこちらのほうが事故が少ない。ただしLake Formationのセルレベルフィルタが設定されたテーブルでは、ジョブブックマークやプッシュダウン述語と同様に `enableUpdateCatalog` がサポート外になります。

### ローカルでGlueのスクリプトをテストできますか？

できます。awslabsのaws-glue-libsリポジトリが `awsglue` ライブラリとローカル実行用の実行ファイルを公開しており、Glue 5.0はglue-5.0、5.1はglue-5.1、6.0はmainブランチが対応。Mavenのcopy-dependenciesで依存JARを取得し、Sparkディストリビューション（5.x系はSpark 3.5系、6.0はSpark 4.1.1）を展開してSPARK\_HOMEを設定すれば、`gluepyspark`でシェル、`gluesparksubmit`でジョブ送信、`gluepytest`でテストを回せます。

## 関連記事

- [AWS Glueとは？機能・料金・使い方とWorkflowsの仕組みまで徹底解説](https://www.issoh.co.jp/tech/details/7251/)：定義・機能一覧・Workflowsの総論。
- [AWS Glue DataBrewとは？ノーコードのデータ準備の仕組み・料金・Glue Studioとの使い分けを実装視点で解説](https://www.issoh.co.jp/tech/details/15782/)：書かない選択肢との比較。
- [AWS Lake Formationとは？データレイクの権限管理・使い方・料金と実装判断を解説](https://www.issoh.co.jp/tech/details/15517/)：FGACと権限設計。
- [ETLとは？仕組み・ELTとの違い・ツール選定から導入判断まで解説](https://www.issoh.co.jp/column/details/13364/)：前段のETL設計。
- [データレイクとは？データウェアハウス・レイクハウスとの違いを実装視点で解説](https://www.issoh.co.jp/tech/details/13388/)：S3配置の前提。
- [Zero-ETL統合の設定手順：AuroraからRedshiftへの複製と料金・ETLが残る場面](https://www.issoh.co.jp/tech/details/18577/)：複製はZero-ETL、変換はGlueという役割分担。

---

出典: [AWS GlueでETLジョブを動かす手順｜PySparkスクリプトとDPU課金の設計](<https://www.issoh.co.jp/tech/details/17472/>)（株式会社一創）
