AWS Batch がジョブの一括キャンセルと一括終了をサポートしたので試してみた

AWS Batch がジョブの一括キャンセルと一括終了をサポートしたので試してみた

ジョブを50件まとめてキャンセルと停止ができるようになりました。
2026.10.23

はじめに

2026 年 9 月のアップデートで、AWS Batch のジョブを 1 回の API 呼び出しで最大 50 件までキャンセル、終了できるようになりました。あわせて ListJobs が、要求を受け付けたかを示す isCancelled と isTerminated を返すようになりました。

https://aws.amazon.com/about-aws/whats-new/2026/09/aws-batch-bulk-cancellation/

なにが嬉しいのか

50 件までのジョブを 1 回でまとめてキャンセルできる!

従来のキャンセルと終了の API は、1 回の呼び出しで 1 件のジョブしか停止できません。まとめて停止したいときは list-jobs で確認した ID をループで 1 件ずつ渡していました。今回のアップデートで最大 50 件の ID を 1 回で受け付けてくれます。

benefit-a-bulk-stop

実行結果の出力内容も変わりました。従来の CancelJob と TerminateJob は、成功しても本文が空の HTTP 200 を返すだけです。新しい CancelJobs と TerminateJobs は、ジョブごとの結果を successful と errors に分けて返します。これはわかりやすい。

停止したジョブと失敗したジョブを見分けられる

キャンセルしたジョブ、終了したジョブ、コンテナが失敗したジョブは、どれも最終的に FAILED になります。これまで見分けるためのフラグは describe-jobs の詳細にしかありませんでした。今回 list-jobs の一覧にも isCancelled と isTerminated が追加されました。いちいち詳細を取らなくても一覧で見分けられます。

一括キャンセルと一括終了の API

今回追加された API は CancelJobs、TerminateJobs、TerminateServiceJobs の 3 つです。最後の 1 つは、SageMaker AI のトレーニングジョブを扱うサービスジョブ向けです。今回は前の 2 つを AWS CLI の cancel-jobs と terminate-jobs を試してみました。

項目 CancelJobs TerminateJobs
停止できるジョブの状態 SUBMITTED、PENDING、RUNNABLE SUBMITTED、PENDING、RUNNABLE、STARTING、RUNNING
停止した後の状態 FAILED FAILED
1 回で渡せる件数 50 件まで 50 件まで
reason 必須、1024 文字まで 必須、1024 文字まで
  • 一部のジョブがエラーになっても HTTP 200 が返るため、errors の確認が要る
  • 存在しないジョブ ID は successful として扱われる
  • 新しい API 専用の IAM アクションはない。既存の batch:CancelJob と batch:TerminateJob で認可される

参考:

キャンセルと終了の違いは以前の記事でジョブの状態と合わせて図解しています。

https://dev.classmethod.jp/articles/aws-batch-job-lifecycle-visual-walkthrough/

検証環境

検証環境はジョブメトリクスを試した前回の記事と同じものを使いました。構築手順自体は省略します。

https://dev.classmethod.jp/articles/aws-batch-job-cloudwatch-metrics/

cancel-jobs と terminate-jobs は AWS CLI v2 の 2.36.44 から使えます。

項目 値
リージョン 東京(ap-northeast-1)
AWS CLI 2.37.3
コンピュート環境 Fargate、最大 4 vCPU
ジョブキュー batch-metrics-demo-queue
ジョブ定義 batch-metrics-demo-success
失敗用のジョブ定義 batch-metrics-demo-fail

実行中と待機中のジョブを用意する

実行中と待機中のジョブを同時に作るため、sleep 3600 で 1 時間動き続けるジョブを用意しました。ジョブ 1 件あたり 1 vCPU、メモリ 2048 MiB です。コンピュート環境の上限は 4 vCPU なので、同時に RUNNING になるのは 4 件までです。ジョブの中身は次の override.json で指定しています。

{
  "taskProperties": [
    {
      "containers": [
        {
          "name": "main",
          "command": ["sh", "-c", "sleep 3600"],
          "resourceRequirements": [
            { "type": "VCPU", "value": "1" },
            { "type": "MEMORY", "value": "2048" }
          ]
        }
      ]
    }
  ]
}

このジョブを 8 件投入し、ID を round1-ids.txt に控えました。

for i in 01 02 03 04 05 06 07 08; do
  aws batch submit-job --region ap-northeast-1 \
    --job-name bulk-job-$i \
    --job-queue batch-metrics-demo-queue \
    --job-definition batch-metrics-demo-success \
    --ecs-properties-override file://override.json \
    --query jobId --output text
done > round1-ids.txt

投入から約 30 秒で 4 件が RUNNING になり、残りの 4 件は RUNNABLE で待ちになりました。RUNNING になったのは bulk-job-01、05、06、07 で、投入した順番というわけではありませんでした。

一括キャンセルに実行中のジョブを混ぜてもエラーにならなかった

4 件ずつ RUNNING と RUNNABLE になった状態で、8 件の ID をすべて cancel-jobs に渡しました。

--jobs には ID をスペース区切りで並べ、--reason に停止理由を書きます。どちらも必須です。

aws batch cancel-jobs --region ap-northeast-1 \
  --jobs $(cat round1-ids.txt) \
  --reason "Cancel queued jobs (bulk cancellation test)"

実行中の 4 件も successful になった

実行結果の successful に 8 件すべての ID が入り、errors は空の配列でした。CLI の終了コードも 0 です。

実行結果
{
    "successful": [
        "205aa77c-2450-4fbe-9e8a-15a8c37ae162",
        "f40e3703-9eb4-42cb-9f80-5444094948a2",
        "2fd6ac50-48f9-4c00-89c7-efaa649d70cd",
        "b0b0ecfa-e882-4863-83d0-b8c5e0df9e77",
        "69915406-3af3-4671-ad63-f4e68aa7a7a0",
        "11077ca1-caf1-430c-8726-b2fb7c8f44b8",
        "c97f34ad-f831-4d66-9720-e51caa6dd468",
        "18d54428-2d69-45e4-a405-8d5c6af702f4"
    ],
    "errors": []
}

実行中の 4 件も successful に入っています。従来の CancelJob も、実行中のジョブを渡すと API としては成功するとされています。

実行中の 4 件は isCancelled が付いたけど実行中のまま

cancel-jobs の 60 秒後に、次のコマンドで状態を確認しました。

aws batch list-jobs --region ap-northeast-1 \
  --job-queue batch-metrics-demo-queue \
  --filters name=JOB_NAME,values="bulk-job-*" \
  --query 'jobSummaryList[].[jobName,status,isCancelled,isTerminated,statusReason]' \
  --output table

待機中だった 4 件は FAILED になり、statusReason に --reason の文字列が入りました。実行中の 4 件は isCancelled が True のまま RUNNING でした。

実行結果
-------------------------------------------------------------------------------------------
|                                        ListJobs                                         |
+-------------+----------+-------+-------+------------------------------------------------+
|  bulk-job-08|  FAILED  |  True |  None |  Cancel queued jobs (bulk cancellation test)   |
|  bulk-job-07|  RUNNING |  True |  None |  None                                          |
|  bulk-job-06|  RUNNING |  True |  None |  None                                          |
|  bulk-job-05|  RUNNING |  True |  None |  None                                          |
|  bulk-job-04|  FAILED  |  True |  None |  Cancel queued jobs (bulk cancellation test)   |
|  bulk-job-03|  FAILED  |  True |  None |  Cancel queued jobs (bulk cancellation test)   |
|  bulk-job-02|  FAILED  |  True |  None |  Cancel queued jobs (bulk cancellation test)   |
|  bulk-job-01|  RUNNING |  True |  None |  None                                          |
+-------------+----------+-------+-------+------------------------------------------------+

API リファレンスでも、CancelJobs は STARTING や RUNNING に進んだジョブをキャンセルしないとされています。一方で successful は、キャンセル要求を受け付けたジョブ ID の一覧と定義されています。successful に入っても、ジョブが停止したとは限りませんと覚えておきましょう。実行中のジョブも停止したいなら terminate-jobs を使ってください。

Jobs that progressed to the STARTING or RUNNING state aren't cancelled. These jobs must be terminated with the TerminateJob or TerminateJobs operation.

successful: A list of the job IDs whose cancellation request was accepted.

出典: CancelJobs

実行中と待機中のジョブを一括終了でまとめて停止してみる

ジョブ名の番号だけを変えた同じコマンドで、bulk-job-09〜12 の 4 件を追加しました。ID は round2-ids.txt に控えます。4 vCPU の上限で前回から走り続けている 4 件分で満杯のため、追加分は RUNNABLE で待ち状態です。

実行中の 4 件と待機中の 4 件、合わせて 8 件の ID を terminate-jobs に渡しました。

aws batch terminate-jobs --region ap-northeast-1 \
  --jobs $(cat running-ids.txt round2-ids.txt) \
  --reason "Terminate jobs (bulk termination test)"

実行結果は一括キャンセルと同じ形で、8 件すべてが successful に入り、errors は空でした。

実行結果
{
    "successful": [
        "205aa77c-2450-4fbe-9e8a-15a8c37ae162",
        "69915406-3af3-4671-ad63-f4e68aa7a7a0",
        "11077ca1-caf1-430c-8726-b2fb7c8f44b8",
        "c97f34ad-f831-4d66-9720-e51caa6dd468",
        "6784c0e1-64f9-41d2-92ee-ff7bd33a6492",
        "f976d6e8-3f36-4559-8ad0-b2c7386842ad",
        "e895cde8-003d-4caf-aa61-6347ff4dc3ce",
        "a2949ae0-a32e-45d6-bd99-81940018993a"
    ],
    "errors": []
}

実行中のジョブは停止するまで 1 分ほどかかった

terminate-jobs の後、10 秒おきに状態を確認しました。待機中のジョブは 10 秒後にはすべて FAILED になりました。実行中のジョブが FAILED になったのは 1 分以上たってからです。

待機中の bulk-job-12 と実行中の bulk-job-07 に絞った抜粋です。列はジョブ名、状態、isCancelled、isTerminated です。

実行結果(抜粋)
2026-10-21T00:19:12Z
bulk-job-12	RUNNABLE	None	True
bulk-job-07	RUNNING	True	True
2026-10-21T00:19:22Z
bulk-job-12	FAILED	None	True
bulk-job-07	RUNNING	True	True
2026-10-21T00:20:15Z
bulk-job-12	FAILED	None	True
bulk-job-07	RUNNING	True	True
2026-10-21T00:20:26Z
bulk-job-12	FAILED	None	True
bulk-job-07	FAILED	True	True

待機中から停止したジョブには isTerminated が付いた

API リファレンスでは、TerminateJobs は STARTING より前のジョブを「キャンセルする」と説明されています。

Jobs that are in the STARTING or RUNNING state are terminated, which causes them to transition to FAILED. Jobs that have not progressed to the STARTING state are cancelled.

出典: TerminateJobs

ところが、待機中から停止した bulk-job-09〜12 に付いたのは isCancelled ではなく isTerminated でした。先ほどの出力の bulk-job-12 も None、True です。一括終了で停止したジョブは、待機中でも終了として扱われました。

isCancelled と isTerminated がどういう条件で付くのか調べた

比較用に、exit 1 で失敗するジョブ bulk-fail-1 も最初に 1 件流しています。13 件すべてが FAILED になった後、次のコマンドで確認しました。

aws batch list-jobs --region ap-northeast-1 \
  --job-queue batch-metrics-demo-queue \
  --filters name=JOB_NAME,values="bulk-*" \
  --query 'jobSummaryList[].{name:jobName,status:status,isCancelled:isCancelled,isTerminated:isTerminated,reason:statusReason}' \
  --output table

停止方法ごとに、付いたフラグは次のとおりでした。終了コードは describe-jobs で確認しています。

ジョブ 停止方法 停止時の状態 isCancelled isTerminated 終了コード
bulk-fail-1 停止していない(exit 1 で失敗) なし なし なし 1
bulk-job-02、03、04、08 一括キャンセル RUNNABLE true なし 試行なし
bulk-job-09〜12 一括終了 RUNNABLE なし true 試行なし
bulk-job-01、05、06、07 一括キャンセルの後に一括終了 RUNNING true true 137

isCancelled は cancel-jobs を、isTerminated は terminate-jobs を受け付けたジョブに付きました。ジョブが実行中か待機中かは関係ありません。一括キャンセルでは停止しなかった実行中のジョブにも、isCancelled が付いています。

CloudWatch のメトリクスでは両方のフラグが付いたジョブはどうなるのか?

両方のフラグが付いたジョブは、JobsCancelled と JobsTerminated の両方でカウントされていました。

ライフサイクルイベントメトリクスで JobsCancelled と JobsTerminated が 09:15 の区間でどちらも 4 になっている

ダッシュボードで JobsMovedToFailed、JobsTerminated、JobsCancelled の 3 つのグラフが表示されている

停止した 12 件が、どちらのメトリクスに数えられたかをまとめると次のとおりです。

停止したジョブ 件数 数えられたメトリクス
待機中に一括キャンセルしたジョブ 4 JobsCancelled
待機中に一括終了したジョブ 4 JobsTerminated
実行中に一括キャンセルし、その後に一括終了したジョブ 4 JobsCancelled と JobsTerminated の両方

最後の 4 件が両方に数えられたため、2 つを足すと 16 件になり、停止した 12 件より多くなりました。

公式ドキュメントでは、JobsCancelled は実行開始前にキャンセルされたジョブを数えるとされています。今回は、実行中にキャンセル要求を受けたジョブも数えられました。

Emitted when a job enters the FAILED state as the result of a cancel request (before the job started running).

出典: Using CloudWatch Metrics with AWS Batch

停止した件数を知りたいときは、メトリクスを頼りにしないで list-jobs で FAILED のジョブを数えるほうが確実です。

まとめ

AWS Batch の一括キャンセルと一括終了を AWS CLI で試しました。一括キャンセルに実行中のジョブを混ぜると、successful になり isCancelled も付きましたが、ジョブは実行中のままでした。一括終了では待機中と実行中のジョブをまとめて停止できます。isCancelled は cancel-jobs を、isTerminated は terminate-jobs を受け付けたジョブに付きました。両方が付いたジョブは、CloudWatch のメトリクスで二重に数えられました。

おわりに

list-jobs の結果を 1 件ずつ停止させるループをせずに 50 件ずつの呼び出しで済むようになりました。利便性はよくなりましたね。間違ってジョブを大量に流したときは特に。

参考

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事