オンプレで毎晩動かしているバッチ処理をクラウドに移したい。でも、EC2を常時起動するのはコストがもったいないし、Lambdaは15分の実行時間制限があって使えない——そんな悩みを抱えたインフラエンジニアは多いはずです。
AWS Batchはそのギャップを埋めるために設計されたサービスです。Dockerコンテナとして定義したジョブを、ジョブキューに投入するだけで、AWSが自動的にコンピューティングリソースを調達・起動・解放してくれます。ジョブが走っていない時間帯はリソースが存在しないので、無駄な課金も発生しません。
この記事では、AWS Batchの基本概念・セットアップ手順・料金体系・実務Tips・よくあるトラブルまでを体系的に解説します。オンプレのcronジョブをクラウドに移行したいエンジニアを対象に、「どういう仕組みで動いているのか」を理解したうえで設計判断できるよう構成しています。
なぜAWS Batchなのか? オンプレのcronジョブとの決定的な違い
オンプレの定期バッチは、おおむね次の構成です。専用のバッチサーバーを1台(または数台)常時稼働させ、cronでスクリプトを起動し、完了したらログを確認する。シンプルですが、問題もはっきりしています。
・リソースの無駄遣い: ジョブが走っていない時間帯も、サーバーは電力とラック代を消費し続けます。
・スケールできない: 月末の大量バッチや四半期決算のピーク時に、1台では間に合わないことが多い。
・障害対応が属人化: cron失敗時の再実行や通知設定が手作業になりがち。
クラウドに移行する際、Lambdaを試したエンジニアから「時間制限の15分を超えてしまって使えなかった」という声をよく聞きます。AWS Batchはそこを補完するポジションにあります。
| 比較軸 | AWS Lambda | AWS Batch | EC2直接運用 |
|---|---|---|---|
| 実行時間の上限 | 最大15分 | 制限なし(数時間・数日も可) | 制限なし |
| コンテナの使用 | 可(Container Image対応) | 必須(Docker/OCI準拠) | 任意 |
| インフラ管理 | 不要 | ほぼ不要(Fargateタイプ選択時) | すべて自分で管理 |
| 非稼働時の課金 | ゼロ | ゼロ(EC2タイプは起動中のみ) | 常時課金 |
| 並列実行のスケール | 同時実行数の上限あり | 最大数千のジョブを並列実行可能 | 手動でインスタンス追加が必要 |
AWS Batchが特に力を発揮するのは、「数分では終わらないが、24時間常駐させるほどではない」ジョブです。たとえば夜間のデータ集計・動画エンコード・機械学習のデータ前処理・大規模なファイル変換などがこれに当たります。
AWS Batchの3つのコアコンポーネント
AWS Batchを理解するには、3つのコンポーネントを把握するのが最短ルートです。
1. ジョブ定義(Job Definition)
「このジョブをどんな環境で実行するか」を定義したテンプレートです。Dockerイメージ・vCPU/メモリのリソース量・IAMロール・環境変数・コマンドなどを指定します。ジョブ定義はバージョン管理され、古いバージョンに戻すことも容易です。
オンプレのcron設定に近い概念ですが、「どのスクリプトをどのシェルで実行するか」ではなく「どのDockerイメージのどのコマンドをどのリソースで実行するか」が記述単位になります。
2. ジョブキュー(Job Queue)
送信されたジョブが実行待ちになる場所です。ジョブキューには優先度を設定でき、複数のコンピューティング環境を関連付けられます。優先度が高いジョブキューのジョブから先にスケジューリングされます。
本番バッチと開発バッチでキューを分け、本番キューに高い優先度を設定しておくと、同時実行時に本番ジョブが優先されます。
3. コンピューティング環境(Compute Environment)
ジョブが実際に実行されるリソースプールです。2つのタイプがあります。
・Fargateタイプ: EC2インスタンスをAWSが自動管理。OSのパッチ適用・AMI管理が不要で、起動が速い(通常30秒以内)。小~中規模バッチに向く。
・EC2タイプ: AWS管理のEC2インスタンス群を使用。インスタンスタイプやスポットインスタンスを細かく制御可能。大量vCPUが必要なHPCワークロードや、コスト重視の長時間バッチに向く。
コンピューティング環境には最小・最大のvCPU数を設定します。ジョブがない時間帯は最小vCPU(通常は0)まで縮小し、ジョブ投入時に自動でスケールアップします。
基本的なセットアップ手順
ここでは、AWS CLIを使った基本的なセットアップ手順を示します。東京リージョン(ap-northeast-1)での作業を前提とします。
1. コンピューティング環境を作成する
まずFargateタイプのコンピューティング環境を作成します。
# AWS CLI(Fargateタイプのコンピューティング環境を作成) aws batch create-compute-environment \ --compute-environment-name "my-batch-fargate-env" \ --type MANAGED \ --state ENABLED \ --compute-resources '{ "type": "FARGATE", "maxvCpus": 256, "subnets": ["subnet-xxxxxxxx"], "securityGroupIds": ["sg-xxxxxxxx"] }' \ --service-role "arn:aws:iam::123456789012:role/AWSBatchServiceRole" \ --region ap-northeast-1
maxvCpus は環境全体で同時に使用できる最大vCPU数です。この値を超えてジョブが殺到した場合、超過分はキューで待機します。最初は256程度から始め、実績を見て調整するのが無難です。
2. ジョブキューを作成する
# ジョブキューを作成し、先ほどのコンピューティング環境に関連付ける aws batch create-job-queue \ --job-queue-name "my-batch-queue" \ --state ENABLED \ --priority 100 \ --compute-environment-order '[ { "order": 1, "computeEnvironment": "my-batch-fargate-env" } ]' \ --region ap-northeast-1
priority は同じコンピューティング環境を共有する複数キュー間での優先度です。数値が大きいほど優先されます。
3. ジョブ定義を登録する
# ジョブ定義を登録(Fargateタイプ) aws batch register-job-definition \ --job-definition-name "my-batch-job" \ --type container \ --platform-capabilities '["FARGATE"]' \ --container-properties '{ "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-image:latest", "command": ["python", "main.py"], "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "jobRoleArn": "arn:aws:iam::123456789012:role/BatchJobRole", "resourceRequirements": [ {"type": "VCPU", "value": "1"}, {"type": "MEMORY", "value": "2048"} ], "networkConfiguration": { "assignPublicIp": "ENABLED" }, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/aws/batch/job", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "my-batch-job" } } }' \ --region ap-northeast-1
executionRoleArn はFargateがECRからイメージを取得したりCloudWatch Logsにログを送信するためのロールです。jobRoleArn はジョブのコードがAWSサービス(S3やDynamoDB等)にアクセスするためのロールです。この2つを混同しないよう注意してください。
4. ジョブを送信・実行する
# ジョブを送信する aws batch submit-job \ --job-name "my-batch-job-20260718" \ --job-queue "my-batch-queue" \ --job-definition "my-batch-job:1" \ --region ap-northeast-1 # ジョブの状態を確認する aws batch describe-jobs \ --jobs "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \ --region ap-northeast-1
ジョブの状態は SUBMITTED → PENDING → RUNNABLE → STARTING → RUNNING → SUCCEEDED / FAILED の順に遷移します。RUNNABLE で止まっている場合、コンピューティング環境のリソースが不足しているか、VPCの設定に問題があることが多いです。
料金の仕組みとコスト感覚
AWS Batchのサービス自体に追加料金はありません。課金されるのは、ジョブが使用した実際のコンピューティングリソース(EC2またはFargate)だけです。
Fargateタイプの料金(2026年3月時点・東京リージョン)
・vCPU: $0.04048 / vCPU時間
・メモリ: $0.004445 / GB時間
例として、1 vCPU・2 GBメモリのジョブが1時間実行された場合:
0.04048 + (0.004445 × 2) = 約$0.049 / ジョブ
毎日1時間実行するとしても月額約$1.5。オンプレでバッチサーバーを維持するコストとは比較にならないほど安価です。大量のジョブを並列実行する場合は合算されますが、それでも「必要な分だけ使う」原則で大幅なコスト削減になります。
EC2タイプの料金
使用されるEC2インスタンスの料金が課金されます。スポットインスタンスを活用すると、オンデマンド比で最大90%の削減が可能です(後述のTips参照)。
応用・実務Tips
FargateタイプかEC2タイプかの選び方
迷ったらまずFargateタイプを選ぶのが現在のベストプラクティスです。OSやAMIの管理が不要で、起動も速く、セキュリティパッチの適用をAWSが担ってくれます。
EC2タイプを選ぶべき状況は次のケースです。
・GPUが必要: 機械学習の推論や動画エンコードでGPUインスタンス(g4dn, p3等)を使いたい場合。FargateはGPUに対応していません。
・大量のvCPUが必要: 1ジョブあたり16 vCPUを超えるリソースが必要な場合(Fargateの上限は16 vCPU)。
・カスタムAMIが必要: 特定のカーネルモジュールや独自ドライバが必要なジョブ。
・コスト最優先: スポットインスタンスでの大幅なコスト削減を狙う場合。
スポットインスタンスでコストを最大90%削減
EC2タイプのコンピューティング環境では、スポットインスタンスを使用できます。バッチジョブは中断・再実行が可能な処理が多く、スポット向きの代表的なワークロードです。
コンピューティング環境作成時に "type": "SPOT" と "bidPercentage": 60(オンデマンド料金の60%以下の時にのみ起動)を指定するだけで有効化できます。スポットが中断された場合、AWS Batchはジョブをキューに戻して自動再試行します。最大再試行回数はジョブ定義の attempts フィールドで指定できます。
ジョブの優先度設定で本番バッチを守る
複数のジョブキューに同じコンピューティング環境を関連付けると、優先度制御ができます。
たとえば、本番バッチ用キュー(priority: 100)と開発テスト用キュー(priority: 10)を同一のコンピューティング環境にアタッチしておくと、同時にジョブが投入された場合に本番バッチが先に処理されます。コンピューティング環境のvCPU上限に達した場合も、優先度の低いキューのジョブが待機し、本番ジョブが優先的にリソースを確保します。
EventBridgeによるスケジュール実行とS3トリガー
オンプレのcronに相当するスケジュール実行は、Amazon EventBridgeのSchedulerルールからジョブを送信することで実現できます。またS3にファイルがアップロードされたタイミングでジョブを起動するイベント駆動バッチも、EventBridgeとAWS Batchの組み合わせで自然に実装できます。
EventBridgeについてはAWS EventBridge入門でも詳しく解説しています。
ジョブ配列(Array Jobs)で並列処理を効率化
「同一の処理を1000ファイルに対して並列実行したい」といった場合、AWS BatchのArray Jobsが有効です。1回のジョブ送信で最大10万のジョブを並列起動でき、各ジョブには環境変数 AWS_BATCH_JOB_ARRAY_INDEX で0始まりのインデックスが渡されます。これを使ってS3のファイルリストのn番目を処理するように設計すると、大量の並列バッチを自然に実装できます。
CloudWatch Logsとアラートの連携
ジョブのログはデフォルトでAmazon CloudWatch Logsに送信されます。ジョブが FAILED 状態になった際にCloudWatch Alarmでアラートを上げ、Amazon SNSでメール通知する構成が標準的な運用です。
CloudWatchの設定方法はAmazon CloudWatch入門でまとめています。
よくあるトラブルと対処法
ジョブが RUNNABLE のまま動かない
最も多いトラブルです。原因は大きく3つあります。①コンピューティング環境のvCPU上限(maxvCpus)に達している、②VPCのサブネットやセキュリティグループの設定でFargateがENIを起動できていない、③Service-LinkedロールやBatchサービスロールの権限不足。マネジメントコンソールのコンピューティング環境の「Status reason」を確認すると原因が書かれています。
ECRからのイメージ取得に失敗する
FargateタイプでECRプライベートリポジトリを使う場合、executionRoleArn に AmazonECSTaskExecutionRolePolicy ポリシーが付いていること、またFargateのサブネットからECRのVPCエンドポイント(またはインターネット経由)に到達できることを確認してください。プライベートサブネットで動かす場合はECR向けのVPCエンドポイント(com.amazonaws.ap-northeast-1.ecr.api・ecr.dkr・s3)が必要です。
コンテナが OOMKilled で終了する
ジョブ定義のメモリ設定が実際の使用量より少ない場合に発生します。CloudWatch Logsでコンテナの終了コード137(OOM Kill)を確認できます。まずメモリを1.5倍~2倍に引き上げて様子を見てください。
スポットインスタンスの中断後にジョブが再開されない
EC2タイプのスポット環境でジョブ定義の attempts(最大再試行回数)が1(デフォルト)のままだと、中断後に再試行されません。スポット使用時は3程度に設定し、かつジョブのロジックを冪等にしておくことが重要です(中途で中断された処理を再実行しても問題ない設計)。
ジョブのタイムゾーンがUTCになっている
FargateコンテナのタイムゾーンはデフォルトUTCです。日本時間を前提とした処理が含まれる場合、ジョブ定義の環境変数に TZ=Asia/Tokyo を設定するか、Dockerイメージ内でタイムゾーンを設定してください。
本記事のまとめ
AWS Batchは「長時間・大量・コンテナ前提」のバッチ処理をクラウドで運用するための専用サービスです。主要なポイントを整理します。
| コンポーネント | 役割 | 設計のポイント |
|---|---|---|
| ジョブ定義 | 実行内容の定義(イメージ・リソース・コマンド) | executionRoleとjobRoleを分離する |
| ジョブキュー | ジョブの受け皿と優先制御 | 本番/開発でキューを分け優先度を設定 |
| コンピューティング環境 | 実行リソースプールの管理 | まずFargate、GPU/大量vCPUはEC2を選ぶ |
| スポット活用 | EC2コストの大幅削減 | 再試行を最低3回設定し冪等に設計する |
| EventBridge連携 | スケジュール・イベント駆動起動 | cronの代替はSchedulerルールで実現 |
オンプレのバッチサーバーを常時稼働させている構成を見直すとき、AWS Batchは最もコスト効率と運用効率を両立しやすい選択肢の一つです。まずFargate + スポットなしで試し、ジョブが安定稼働したらスポットインスタンスへの切り替えを検討する——というステップで進めると、移行リスクを最小限に抑えられます。
PR
AWS運用入門 押さえておきたいAWSの基本と運用ノウハウ(佐竹陽一・山﨑翔平ほか/SBクリエイティブ)
AWSの各サービスを日常の運用視点でまとめた一冊。AWS Batchを含むバッチ系・コンテナ系サービスの実務的な使いどころが整理されており、クラウド移行後の「どう運用するか」を体系的に学べます。
