[小ネタ] ECS サービスの初回デプロイメント時に、デプロイサーキットブレーカーが発動した場合の挙動を調べてみた

[小ネタ] ECS サービスの初回デプロイメント時に、デプロイサーキットブレーカーが発動した場合の挙動を調べてみた

Clock Icon2025.07.12

こんにちは!クラウド事業本部コンサルティング部のたかくに(@takakuni_)です。

みなさん、デプロイサーキットブレーカー使っていますでしょうか。

デプロイサーキットブレーカーを利用することで、異常なタスク数(起動に失敗するタスク数)が一定の閾値に達した時点で、自動的にロールバックが走るため、非常に便利な機能です。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/deployment-circuit-breaker.html

ここで言うロールバックとは、「以前のデプロイメントに自動的に戻る」ことを指しているのですが、以前のデプロイメントがない状態の場合どうなるのでしょうか。

※「以前のデプロイメントがない状態」とは、つまり、初回デプロイメントのことです。

今回は、初回デプロイメントが失敗し、デプロイサーキットブレーカーが発生した場合の挙動について、調べてみたいと思います。

結論

  • 初回デプロイメントが失敗し、デプロイサーキットブレーカーが発生した場合、デプロイは ROLLOUT_FAIDED 状態に遷移する
    • COMPLETED 状態にある最新のデプロイメントをロールバック先に選定するが、デプロイメントが存在しないため
  • 場合によっては、新しい ECS タスクが残り続けるため、デプロイが成功しているように見える
    • 必要に応じて、デプロイメントの失敗を通知すること

やってみる

今回は ELB のヘルスチェックに失敗して、タスク起動がこけているパターンを想定してみます。

以下のようにルートのみ、応答を返すコンテナを作ってみました。

from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

https://fastapi.tiangolo.com/ja/deployment/docker/

ALB のヘルスチェックには /health を指定します、

2025-07-12-12-00-01.png

当たり前ですが、ELB のヘルスチェックには、失敗し続けている状態です。

2025-07-12-12-00-38.png

デプロイメントを見てみる

デプロイメントを見てみます。デプロイのステータスは ロールバックに失敗 と表示されています。

サービスリビジョンは 1 と表示されており、ターゲットのみ表示されています。

2025-07-12-12-02-59.png

また、作成時刻から初回デプロイで利用したタスクは、生き続けていることがわかります。

2025-07-12-12-06-13.png

状況証拠的にまとめると、以下の状態であることがわかります。

  1. デプロイに失敗した(ELB のヘルスチェックが起因)
  2. ロールバックにも失敗した
  3. ELB のヘルスチェックは Unhealty である
  4. タスクの置き換わりは止まっている

一体、どういうことなのでしょうか。

ロールバックに失敗とは

そもそも、ロールバックに失敗 とは、どう言う状況なのでしょうか。

ドキュメントによると、 COMPLETED 状態にある最新のデプロイが見つからなかったため、ロールバックに失敗してしまったことが汲み取れます。

デプロイサーキットブレーカーは、デプロイが失敗したと判断すると、COMPLETED 状態にある最新のデプロイを探します。このデプロイをロールバックデプロイとして使用します。ロールバックが開始されると、デプロイは COMPLETED から IN_PROGRESS に変わります。つまり、デプロイは COMPLETED 状態になるまで次のロールバックの対象にはなりません。デプロイサーキットブレーカーが COMPLETED 状態のデプロイを見つけられない場合、サーキットブレーカーは新しいタスクを起動せず、デプロイは停止します。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/deployment-circuit-breaker.html

今回は初回デプロイのため、以前のデプロイメントが見つからないため、ロールバックできなかったと考えられます。

タスクの置き換わりは止まっている

続いてタスクの置き換わりが止まっている部分です。

同じ箇所に記載されている「デプロイサーキットブレーカーが COMPLETED 状態のデプロイを見つけられない場合、サーキットブレーカーは新しいタスクを起動せず、デプロイは停止します。」に該当したと考えられます。

つまり、ECS によるタスクの置き換わりがストップし、ELB のヘルスチェックに失敗しているものの、タスクが動き続けている状態となっています。

ALB の特性上、すべてのターゲットがヘルスチェックにしている場合、フェイルオープンとなるため、ブラウザからは問題なさそうに見えますが、ヘルスチェックは失敗している状況となります。

2025-07-12-12-14-16.png

ターゲットグループに異常な登録済みターゲットのみが含まれている場合、そのヘルスステータスにかかわらず、ロードバランサーはそれらすべてのターゲットにリクエストをルーティングします。つまり、有効なすべてのアベイラビリティーゾーン内で、すべてのターゲットが同時にヘルスチェックに失敗すると、ロードバランサーはオープンに失敗します。フェールオープンの効果は、ヘルスステータスにかかわらず、ロードバランシングのアルゴリズムに基づいて、有効なすべてのアベイラビリティーゾーン内のすべてのターゲットへのトラフィックを許可することです。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/target-group-health-checks.html

EventBridge の統合

上記のことから、マネコンを見ない限り、なぜか成功しているように見える現象も考えられます。

必要に応じて、EventBridge 経由で通知を飛ばすことも視野に入れておきましょう。例として次のイベントがデプロイメントの失敗時に拾えるようです。

{
   "version": "0",
   "id": "ddca6449-b258-46c0-8653-e0e3aEXAMPLE",
   "detail-type": "ECS Deployment State Change",
   "source": "aws.ecs",
   "account": "111122223333",
   "time": "2020-05-23T12:31:14Z",
   "region": "us-west-2",
   "resources": [ 
        "arn:aws:ecs:us-west-2:111122223333:service/default/servicetest"
   ],
   "detail": {
        "eventType": "ERROR", 
        "eventName": "SERVICE_DEPLOYMENT_FAILED",
        "deploymentId": "ecs-svc/123",
        "updatedAt": "2020-05-23T11:11:11Z",
        "reason": "ECS deployment circuit breaker: task failed to start."
   }
}

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_service_deployment_events.html

まとめ

以上、「ECS サービスの初回デプロイメント時に、デプロイサーキットブレーカーが発動した場合の挙動を調べてみた」でした。

小ネタですが、私自身、デプロイサーキットブレーカーの挙動で、タスクが残り続けるとは思わなかったので、いい勉強になりました。

このブログがどなたかの参考になれば幸いです。クラウド事業本部コンサルティング部のたかくに(@takakuni_)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.