はじめに
この連載では、AWS ECS を使ったコンテナ環境を AWS マネジメントコンソールから手作業で 構築し、そこに CI/CD を少しずつ足していきます。
想定している読者は次のような方です。
- VPCやEC2等の設定、構築をした事がある方。
- コンテナは触ったことがあるが、ECS はこれからという方。
- ECS Fargateを使用して、ECSの基礎知識を確認しておきたい方。
- 昔ECSを使ったが久しぶりのため、改めて作業方法の再確認をしたい方、復習をして知識を維持したい方。
前回について
本ブログは第3回目となります。前回(第2回へ移動する)は、CodePipelineでECRへのpushを検知し、ローリングアップデートで自動リリースしました。
本記事について
- 本記事ではALBやFargateなどの有料サービスを使用するため、費用が発生します。ALBとFargateは起動している時間に応じた課金のため、数時間で完了すれば数USドル程度ですみますが、削除し忘れて1か月放置すると40USドル程度になります。検証後は必ずリソースの削除をお願いします(手順は記事末尾に記載しています)。
- AWSマネジメントコンソールの画面構成は、随時更新されます。本記事は2026年9月時点の画面をもとにしています。項目名や配置が異なる場合は、適宜読み替えてください。
- 掲載している手順は、実際にAWS上で検証した内容です。ただし、学習しやすさを優先してセキュリティ設定を簡略化している箇所があります(タスクをパブリックサブネットに配置する、セキュリティグループで広い範囲からのアクセスを許可する、など)。そのため、検証用のAWSアカウントでの実施を推奨します。
- 本記事では、GitHubとAWSを連携させる設定(OIDCのIDプロバイダー、GitHubアプリの連携など)を行います。これらは他のプロジェクトと共有される設定のため、検証後に削除する際はご注意ください。同じアカウントやGitHub組織で他にも利用しているものがあると、そちらの連携まで止まってしまう可能性があります。削除対象かどうか分からない場合は、無理に消さずに残しておくほうが安全です(残しておいても費用は発生しません)。
- 共用アカウントや業務で使用しているアカウントで実施する場合は、組織のルールを確認したうえで設定内容を見直してから、本記事を参考にしたり、手順の実施をしてください。
テーマとゴール
いくつかテーマと、ゴールを決めて進めていきます。内容を1つのブログにすると長くなるため、複数回に分けています。
| 第何回 | テーマ | ゴール |
| 第1回 | コンテナと ECS の基礎、手動構築 | ブラウザに「Hello from Amazon ECS」 が表示される |
| 第2回 | 手動リリースと CodePipeline による自動リリース | ECR への push でローリングアップデート |
| 第3回 | ECS ネイティブ Blue/Green デプロイ | テストリスナーで確認してから本番切り替え |
| 第4回 | GitHub Actions で ECR への push を自動化 |
“git push”だけでリリースまで完了する |
| 第5回 | プライベートサブネットを使用した構成 |
プライベートサブネットとエンドポイントを利用した環境構築の検証をする |
第3回目のゴール
今回は「Blue/Greenデプロイ」を目的に進めます。新しいバージョン(Green)を本番とは別に立ち上げ、テストリスナーで確認してから本番切り替えます。
ECSネイティブ Blue/Green
2025年7月のアップデートで、ECS自身がBlue/Greenデプロイを実行できるようになりました。CodeDeploy もappspec.ymlも不要で、ECS サービスの設定を変えるだけで使えます。

- 検証したいのは以下の点です
- v4をpush すると、Green環境が立ち上がる
- テストリスナー(ポート8080)でv4を確認できる。本番(ポート80)はv3のまま
-
デプロイが一時停止して、人の承認を待つ
- 承認すると本番が一瞬でv4に切り替わる
準備
第2回までのリソースが残っている必要があります。削除した場合は、再作成してください。今回は、以下を使います。
- ALB : ecs-handson-alb (HTTP:80 リスナー)とターゲットグループecs-handson-tg-blueがあること
- ECSサービス : ecs-handson-service(ローリングアップデート、v3 稼働中)
- CodePipeline : ecs-handson-pipeline (Source → Build → Deployまでできている)
1.Blue/Greenの仕組みの確認
1-1. 使用するリソース
Blue/Green デプロイでは、ALB 側に次のリソースが増えます。
| リソース | 使用目的 |
|
ターゲットグループ × 2 |
Blue用とGreen用。デプロイのたびに役割が入れ替わる |
| 本番リスナー(:80)のルール | 利用者のトラフィックをどちらのターゲットグループに流すか |
| テストリスナー(:8080)のルール | 確認用のトラフィックをどちらに流すか |
| ECS インフラストラクチャロール |
ECSがリスナーのルールを書き換えるための IAM ロール |
ローリングアップデートでは、ECSが実行していたのは「ターゲットグループへのタスクの登録・解除」でした。Blue/Greenでは、ECSがALBのリスナールールそのものを書き換えてトラフィックを切り替えます。そのための権限を、専用のIAMロールとしてECSに渡します。
1-2. デプロイの流れ(ライフサイクルステージ)
各ステージには「ライフサイクルフック」を差し込めます。フックには 2 種類あります。
- Lambdaフック : 指定したLambda関数を呼び出す。自動テストの結果で続行・中止を判断するのに使う。
-
一時停止(PAUSE)フック : デプロイをその場で止め、人が「続行」か「ロールバック」を指示するのを待つ。
一時停止フックは2026年5月に追加された機能です。今回はPOST_TEST_TRAFFIC_SHIFTに一時停止フックを入れ、テストリスナーでGreenを自分の目で確認してから本番に切り替える流れを作ります。Lambdaを書かずに承認フローが作れることを試していきます。
ECSネイティブBlue/Greenは、決まった順序の「ステージ」を進んでいきます。主な物は、次のとおりです。
| ステージ | 状態 | Lambda フック | 一時停止フック |
| SCALE_UP | Greenのタスクを起動する。トラフィックは流れる前の段階。 | 使えない | 使えない |
| TEST_TRAFFIC_SHIFT | テストリスナーのトラフィックをGreenに向ける。 | 使える | 使えない |
| POST_TEST_TRAFFIC_SHIFT |
テスト用の切り替えが完了した直後。今回はここで一時停止する。 |
使える |
使える |
| PRE_PRODUCTION_TRAFFIC_SHIFT |
本番トラフィックを切り替える直前 |
使える |
使える |
| PRODUCTION_TRAFFIC_SHIFT | 本番リスナーのトラフィックをGreenに向ける。 | 使える | 使えない |
| BAKE_TIME | 切り替え後の様子見期間。Blueのタスクはまだ残っている。 | 使えない | 使えない |
| CLEAN_UP | Blue のタスクを停止し完了。 | 使えない | 使えない |
※ 上記は抜粋です。全11ステージの一覧は AWSのドキュメントを参照してください
表を見ると、フックを差し込めるステージは限られています。SCALE_UPやBAKE_TIMEのように「ECS が動いている最中で、途中に割り込む意味がない」ステージには何も差し込めません。
また、名前に_TRAFFIC_SHIFTが付く「移行中」のステージは Lambda フックだけが使えます。トラフィックが動いている最中なので、人の承認を待って止まるわけにはいかないためです。自動テストを走らせて続行・中止を判断する用途に限られます。
一時停止フックを置けるのは、移行と移行の「あいだ」のステージだけということになります。今回は候補が 2 つあります。
| ステージ | 止まる場所 | テストリスナーで確認できるか |
| POST_TEST_TRAFFIC_SHIFT | テスト用の切り替えが終わった直後 | できる |
| PRE_PRODUCTION_TRAFFIC_SHIFT | 本番切り替えの直前 | できる |
どちらでもテストリスナーでの確認は可能ですが、本記事ではPOST_TEST_TRAFFIC_SHIFTを選択しています。テストの準備が整った直後に止まるという位置づけがいちばん分かりやすく、止まっている間にテストリスナーでGreenを確認する、という流れが素直につながるためです。
- 参考リンク
2.Green側の作成
2-1.Green 用のターゲットグループを作る
EC2 コンソール → ターゲットグループ →「ターゲットグループの作成」
設定は第1回のecs-handson-tg-blueと名前以外すべて同じ設定にします。
| 項目 | 設定値 |
| ターゲットタイプ | IPアドレス |
| ターゲットグループ名 | ecs-handson-tg-green |
| プロトコル : ポート | HTTP : 80 |
| VPC | ecs-handson-vpc |
| ヘルスチェックパス | / |
| 正常 / 非正常のしきい値 | 2 / 2 |
| タイムアウト / 間隔 | 5秒 / 30秒 |
| 成功コード | 200 |
ターゲットは登録せずに作成します。作成後、「属性」タブで登録解除の遅延を30秒に変更してください。

2-2. ALB のセキュリティグループに 8080 を開ける
EC2 コンソール → セキュリティグループ → ecs-handson-alb-sg →「インバウンドルールを編集」→ ルールを追加
| タイプ | プロトコル | ポート | ソース |
| カスタムTCP | TCP | 8080 | マイIP (社内ネットワークやVPNの範囲を手動設定することをお勧めします。) |
テストリスナーは「リリース前の確認用」の入口なので、世界中に公開する必要はありません。ここでは自分のIPだけに絞ります。本番運用では、社内ネットワークやVPNの範囲に限定するのが一般的です。

また、タスク側のecs-handson-task-sgは変更不要です。ALBがテストリスナーで受けたリクエストも、転送先はタスクのポート80番を使用するためです。
2-3. リスナーのルールにGreenを追加
ECS ネイティブBlue/Greenでは、本番リスナーとテストリスナーのルールが、BlueとGreenの両方のターゲットグループを転送先として持っている必要があります。ECSがデプロイ時に、転送先そのものを追加してくれるわけではないためです。この準備をしないままサービスの設定に進むと、グリーンターゲットグループの選択肢が灰色になり、「選択したリスナーには、このターゲットグループにトラフィックを転送するルールがありません。」と表示されて選べません。
① テストリスナー(HTTP:8080)を作る
EC2 コンソール → ロードバランサー → ecs-handson-alb → リスナーとルール タブ → リスナーの追加ボタンを押下します。以下の設定をしたら、リスナーの追加ボタンを押下します。
| 項目 | 設定値 |
| プロトコル | HTTP |
| ポート | 8080 |
| アクションのルーティング | ターゲットグループへ転送 |
| ターゲットグループ | ecs-handson-tg-green |

②リスナーを追加したら、 ecs-handson-alb → リスナーとルール タブ → HTTP:80 → デフォルトルールを選択 → ルールを編集 → リスナーの編集画面に進んだら、以下の設定をターゲットグループの箇所でします。
| ターゲットグループ | 重み |
| ecs-handson-tg-blue | 100 |
| ecs-handson-tg-green | 0 |


③同様にgreen側のリスナーも変更します。 ecs-handson-alb → リスナーとルール タブ → HTTP:8080 → デフォルトルールを選択 → ルールを編集 → リスナーの編集画面に進んだら、以下の設定をターゲットグループの箇所でします。
| ターゲットグループ | 重み |
| ecs-handson-tg-green | 100 |
| ecs-handson-tg-blue | 0 |

2-4. ECSインフラストラクチャロールを作る
ECS が ALB のリスナールールを書き換えるための IAM ロールを作ります。
IAM コンソール → ロール →「ロールを作成」
ステップ 1:信頼されたエンティティを選択
「カスタム信頼ポリシー」を選び、以下を貼り付けます。「ECSというサービスが、このロールを引き受けてよい」という内容になります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAccessToECSForInfrastructureManagement",
"Effect": "Allow",
"Principal": {
"Service": "ecs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}

ステップ 2:許可を追加
検索欄に「AmazonECSInfrastructureRolePolicyForLoadBalancers」と入力し、チェックを入れます。AWSが用意している管理ポリシーで、ターゲットグループやリスナールールの操作に必要な権限がまとまっています。

ステップ 3:名前を付ける
以下の名前でロールを作成します。
ロール名 : ecsInfrastructureRoleForLoadBalancers
ロールを作成ボタンを押下してください。
3.サービスをBlue/Greenに切り替える
ECS ネイティブ Blue/Green の大きな利点は、サービスを作り直さずに既存のサービスの設定を変えるだけで切り替えられることが挙げられます。
ECS コンソール → クラスター : ecs-handson-cluster → サービス : ecs-handson-service →「サービスを更新」
3-1. デプロイオプション
以下のように設定を変更します。
| 項目 | 設定値 |
| デプロイ戦略 | ブルー/グリーン |
| ベイク時間 | 5分 |
- ベイク時間
- Blueリビジョンが終了する前に、BlueおよびGreenのサービスリビジョンの両方が同時に実行される分数を入力します。これにより、検証およびテストの時間を確保できます。(AWSマニュアル Amazon ECS ブルー/グリーンデプロイの作成)
- ベイク時間は、本番をグリーンに切り替えたあと、Blueのタスクを残しておく時間です。この間に問題が見つかれば、Blueにすぐ戻せます。本番では確認する時間などを考慮し、15〜60分程度に設定することが多いですが、今回の記事では待ち時間を短くするため5分にします。

3-2. デプロイライフサイクルフック
一時停止フックを追加ボタンを押下し、以下のように設定します。
| 項目 | 設定値 |
| フックのタイプ | 一時停止(Pause) |
| ライフサイクルステージ | テストトラフィック移行後(POST_TEST_TRAFFIC_SHIFT) |
| タイムアウト | 30分 |
| タイムアウト時のアクション | ロールバック |
タイムアウト時のアクションは「ロールバック」にしておきます。 承認を忘れて放置した場合に、確認されていないバージョンが勝手に本番に出ていくのを防ぐためです。「誰もOKを出さなかったものはサービスとして出さない」ようにする安全設計となります。

3-3. ロードバランシング
| 項目 | 設定値 |
| ロール | ecsInfrastructureRoleForLoadBalancers |
| ロードバランサーの種類 | Application Load Balancer |
| コンテナ | nginx 80:80 |
| ロードバランサー | ecs-handson-alb |
| リスナー | HTTP:80 |
| 本番リスナールール | 優先度: default |
| テストリスナー | HTTP:8080 |
| テストリスナールール | 優先度:default |
| ブルーターゲットグループ | ecs-handson-tg-blue |
| グリーンターゲットグループ | ecs-handson-tg-green |
グリーンターゲットグループが灰色で選べない場合は、2-3の本番リスナーのルールにGreen重み 0)が入っているか確認してください。ルールを直した後は、プルダウン右の更新ボタンを押してから選び直します。
他の項目は変更せず、「更新」を押します。
3-4. 最初の Blue/Green デプロイ確認
サービスを更新すると、すぐにデプロイが始まります。 デプロイ戦略を変えた更新そのものが、新しい設定(Blue/Green + 一時停止フック)での最初のデプロイとして実行されるためです。フックも初回から有効です。「デプロイ」タブを開くと、デプロイタイムラインが次のように進み、一時停止します。
- デプロイが開始されました
- 緑タスクのスケールアップ(ecs-handson-tg-greenに2つ登録)
- テストトラフィック移行
- 移行後チェックの実行 → 一時停止フック:アクションを待機中

画面上部に「デプロイがアクションを待機しています」という黄色いバナーが表示されます。

中身は同じイメージを使用しているため、今回は練習として続行します。タイムラインの「一時停止フック」の横、または上部バナーの「アクションを実行する」を押して続行を選択後、確認ボタンを押下してください。本番トラフィック移行 → ベイク時間(5分)→ ブルータスクの終了と進んで完了します。
3-5. リスナールールの変更確認
HTTP:80 のデフォルトルールをもう一度開いて確認してみます。2-3 で自分で設定したときは Blue 100 : Green 0 でしたが、3-4 のデプロイが完了した今は Blue 0 : Green 100 に変わっているはずです。ECS はデプロイのたびに、この重みを書き換えることでトラフィックを切り替えます。
4.Blue/Greenリリース
4-1. v4イメージをpushする
パイプラインの設定は変更せずに、CloudShellから新しいイメージをリリースします。
CloudShellを起動し、以下のコマンドを実行します。セッションが切れている場合は、変数を再設定してください。htmlファイルを変更し、v4は薄いオレンジ背景にしています。
cd ~/ecs-handson
AWS_REGION=ap-northeast-1
AWS_ACCOUNT_ID=(aws sts get-caller-identity –query Account –output text)
REPO=ecs-handson-nginx
REGISTRY={AWS_ACCOUNT_ID}.dkr.ecr.{AWS_REGION}.amazonaws.com
ECR_URI={REGISTRY}/${REPO}
aws ecr get-login-password –region ${AWS_REGION}
| docker login –username AWS –password-stdin ${REGISTRY}
sed -i -e ‘s/v3/v4/’ -e ‘s/#eaffea/#fff1e0/’ index.html
docker build -t ${REPO}:v4 .
docker tag ${REPO}:v4 ${ECR_URI}:v4
docker tag ${REPO}:v4 ${ECR_URI}:latest
docker push ${ECR_URI}:v4
docker push ${ECR_URI}:latest
4-2. Green が立ち上がるのを観察する
ブラウザでタブを開いて、各状況を確認します。
| タブ | 確認したい画面 |
| A | http://<ALBのDNS名> (本番 :80番ポートの画面) |
| B | http://<ALBのDNS名>:8080 (テスト :8080番ポートの画面) |
| C | ECS サービスの「デプロイ」タブ |
| D | CodePipelineのecs-handson-pipeline |
- タブDを見ると、パイプラインが Source → Build → Deploy と進み、Deploy が「進行中」のまま止まります。
-
タブCを見ると、デプロイのステージが SCALE_UP → と TEST_TRAFFIC_SHIFT 進むことを確認します。
- POST_TEST_TRAFFIC_SHIFTで一時停止することを確認します。
- タブAとタブBをリロードし、タブAがv3(以前のイメージ)のままで、タブBがv4(更新したイメージ)になり背景色がオレンジ色になっていることを確認します。
タブCの画面

タブDの画面

タブAとタブBの画面

4-3. 承認して本番に切り替える
ブラウザでポート番号8080番のURL画面が、v4になっていることを確認したらデプロイを続行します。
ECS サービスの「デプロイ」タブ → デプロイタイムラインの「一時停止フック」の横にある「アクションを実行する」(画面上部の黄色いバナーからも同じ操作ができます)→ 続行を選択 → 確認ボタンを押下します。
4-4. 本番の切り替えとベイク時間
続行すると、PRODUCTION_TRAFFIC_SHIFTに進みます。ブラウザでポート番号80番のURL画面をリロードすると、ある瞬間からv4の画面のみが表示されるようになりますので確認します。
デプロイはBAKE_TIMEに入ります。旧バージョンのタスクはまだ停止されていません。ロードバランサーのターゲットグループecs-handson-tg-greenを見ると、v3のタスクがhealthyのまま残っています。5 分のベイク時間が過ぎるとCLEAN_UPでv3のタスクが停止され、デプロイ完了です。
パイプラインも、ここで初めてDeployが「成功」になります。CodePipelineのDeployアクションは、一時停止やベイク時間も含めて、ECS のデプロイが完了するまで待っていることが分かります。
4-5. ターゲットグループの役割は毎回入れ替わる
本番トラフィックを受けるターゲットグループは、デプロイのたびに入れ替わっています。
| タイミング | 本番を受けているターゲットグループ |
| 第1回〜第2回(ローリングアップデート) | ecs-handson-tg-blue |
| 本ページの3-4 の初回Blue/Green後 | ecs-handson-tg-green |
| v4 デプロイ後 | ecs-handson-tg-blue |
| 次回以降のv5デプロイ後 | ecs-handson-tg-green |
ターゲットグループの名前「blue」「green」は固定の役割ではなく、デプロイのたびに交互に使用するということになります。ECSコンソールの「ブルーターゲットグループ」「グリーンターゲットグループ」という表記も、あくまでサービス設定上の呼び名にすぎません。
実運用ではこの名前「blue」「green」が混乱のもとになるので、「-a / -b 」または「 -1 / -2 」のような名前を付けるなど、運用に合わせて工夫するのも1つの手段になります。
5.ロールバック
5-1. 一時停止中にロールバックする(本番に出す前に取り消す)
CloudShellでv5のイメージをビルドし、pushします。CloudShellを起動し、以下のコマンドを実行します。セッションが切れている場合は、変数を再設定してください。
cd ~/ecs-handson
AWS_REGION=ap-northeast-1
AWS_ACCOUNT_ID=(aws sts get-caller-identity –query Account –output text)
REPO=ecs-handson-nginx
REGISTRY={AWS_ACCOUNT_ID}.dkr.ecr.{AWS_REGION}.amazonaws.com
ECR_URI={REGISTRY}/${REPO}
aws ecr get-login-password –region ${AWS_REGION}
| docker login –username AWS –password-stdin ${REGISTRY}
sed -i -e ‘s/v4/v5/’ -e ‘s/#fff1e0/#f3e8ff/’ index.html
docker build -t ${REPO}:v5 .
docker tag ${REPO}:v5 ${ECR_URI}:v5
docker tag ${REPO}:v5 ${ECR_URI}:latest
docker push ${ECR_URI}:v5
docker push ${ECR_URI}:latest
ECSのデプロイタブで、デプロイが一時停止したことを確認したら、テストリスナー(:8080)でv5になっていることをブラウザで確認します(薄紫色に変更されているはずです。)。確認したら、「一時停止フック」の横にある「アクションを実行する」(画面上部の黄色いバナーからも同じ操作ができます)→ ロールバックを選択 → 確認ボタンを押下します。

Green 側の v5 タスクが停止され、デプロイは取り消されます。パイプラインの Deploy は「失敗」になります。


「テストで問題を見つけたので出さない」という、理想的な止め方になります。
5-2. ベイク時間中にロールバックする(本番リリース後に戻す)
もう一度 v5 を流します。先ほどと同じイメージなので、パイプラインを再実行します。
CodePipeline → ecs-handson-pipeline →「変更をリリースする」

今度は一時停止で「続行」を選び、本番をv5に切り替えます。

ブラウザで80番ポートで確認している画面が薄紫(v5)になったのを確認したら、ベイク時間5分が終わる前にロールバックします。

コンソールから:ECS サービスの「デプロイ」タブ → 進行中のデプロイ →「ロールバック」

ブラウザで80番ポートで確認している画面 をリロードし続けると、数十秒ほどで v4(オレンジ)に戻ります。ベイク時間中はv4のタスクがまだ動いているので、リスナールールの重みを元に戻すだけで済むからです。これがBlue/Greenの「速く戻せる」理由です。
5-3. ECRのlatestを元に戻しておく
サービスはv4に戻りましたが、ECRのlatestはまだ v5 を指しています。今回の v5 は壊れているわけではないので実害はありませんが、本番で動いているものとlatestを一致させておきます。
CloudShellで実行してください。
docker tag ${REPO}:v4 ${ECR_URI}:latest
docker push ${ECR_URI}:latest
パイプラインが起動し、v4 の Blue/Green デプロイが走ります。一時停止したら、続行を選択して完了するまで進めてください。
6.Canary と Linear
ECS ネイティブのデプロイ戦略には、Blue/Green のほかに Canary と Linear もあります(2025年10月からです)。
| デプロイ戦略 | 本番トラフィックの移し方 | 向いている場面 |
| Blue/Green | 0% → 100% を一括で | 切り替えの瞬間をはっきりさせたい。今回の構成 |
| Canary | まず一部(例:10%)だけ流し、様子を見てから残りを一括で | 一部の利用者で先に問題を検知したい |
| Linear | 一定の割合ずつ段階的に(例:10% ずつ 10 回) | 負荷の変化をなだらかにしたい |
LinearやCanary でPRE_PRODUCTION_TRAFFIC_SHIFTに一時停止フックを置くと、段階ごとに毎回止まります。10段階のLinearなら10回承認が必要になるので、フックの置き場所には注意してください。
7.うまくいかないとき
| 状況 | 原因と対応方法 |
| サービス更新時に、ロールの選択肢にecsInfrastructureRoleForLoadBalancersが出てこない | 信頼ポリシーのプリンシパルがecs.amazonaws.com になっているか確認(ecs-tasks.amazonaws.comではありません。) |
| サービス更新時にiam:PassRoleのエラー | 操作している IAMユーザー/ロールに、インフラストラクチャロールを ECS に渡す権限がない。AdministratorAccessなら通常は問題ありません。 |
| 本番リスナールールの選択肢にデフォルトルールが出てこない。 |
HTTP:80 リスナーに、条件がパス /*・優先度 1 のルールを追加し、そのルールを本番リスナールールとして選ぶ |
| グリーンターゲットグループが灰色で「このターゲットグループにトラフィックを転送するルールがありません」 | 本番リスナーのルールに Green が入っていない。2-3①で Blue 100/Green 0の重み付き転送にする。 |
| デプロイがTEST_TRAFFIC_SHIFTから進まない | Greenのタスクがターゲットグループのヘルスチェックに通っていない。ecs-handson-tg-greenのヘルスチェック設定がBlueと同じか確認する。 |
| :8080 を開くとタイムアウトする | ecs-handson-alb-sgのインバウンドに8080がない、またはソースの IP が変わった(「マイ IP」は作成時点の IP で固定される) |
|
:8080 で503が返る |
Green 側にタスクがいない。デプロイ中でなければ正常です。 |
| 一時停止したまま、30分後に勝手にロールバックされた。 | タイムアウト時のアクションが「ロールバック」になっているため。設計どおりの動き。 |
| パイプラインの Deploy がタイムアウトで失敗する | 一時停止中の待ち時間とベイク時間の合計が、Deployアクションのタイムアウトを超えた。承認を早めに行うか、Deployアクションのタイムアウトを延ばす。 |
まとめ
以下の点を確認しました。
- ECS ネイティブ Blue/Green は、既存サービスの設定変更だけで導入できる。… CodeDeployもappspec.ymlファイルも不要。
- 切り替えの実体は、ALB リスナールールの重みの書き換えが行われる。 … そのために ECS インフラストラクチャロールが要る
-
一時停止フックで、テストリスナーを人が確認してから本番に出せる。 … Lambda なしで承認フローが作れる。
- ベイク時間中はリスナーの重みを戻すだけでロールバックできる。 … タスクを起動し直さないから早くロールバックできる。
-
blue / green のターゲットグループは、デプロイのたびに役割が入れ替わる
続き
GitHub Actions を使用してECRへのpushを自動化します。(第4回へ移動する)
最後に
ここで作成したリソースを削除する場合は、以下のリソースを削除してください。次の回に進む場合は、同じリソースを使用しますので削除せずに進みます。
インフラストラクチャロールは、デプロイの実行中に削除しないでください。ECSがリスナールールを書き換えられなくなり、サービスが中途半端な状態で止まる可能性があります。必ずサービスを削除してから削除します。
アーティファクト用バケットは同じリージョンの他のパイプラインでも共用されます。他にパイプラインを使っている場合は削除しないでください。
| 項目 | 項番 | リソース | 場所 | 補足 |
| 1.入り口を止める | 1 | パイプライン ecs-handson-pipeline | CodePipeline | 最初に消します。残したままだと、作業中に ECR の変化を検知してデプロイが走ります |
| 2 | EventBridge ルール | EventBridge → ルール | 「codepipeline-」で始まる名前。パイプライン削除時に自動で消えますが、残っていれば削除します。 | |
| 2. ECS | 3 | サービス ecs-handson-service | ECS → クラスター → サービス | タスクも一緒に停止します。完全に消えるまで数分かかります |
| 4 | クラスター ecs-handson-cluster | ECS | サービスが消えてから削除 | |
| 3. ロードバランサー | 5 | ALB ecs-handson-alb | EC2 → ロードバランサー | :80 と :8080 のリスナーも一緒に消えます |
| 6 | ターゲットグループ ecs-handson-tg-blueおよびecs-handson-tg-green | EC2 → ターゲットグループ | ALB 削除後でないと「ルールから参照されている」エラーで消せません | |
| 4. データ&ログ | 7 | ECR リポジトリ ecs-handson-nginx | ECR | イメージが入っていても強制削除できます |
| 8 | S3 バケット codepipeline-ap-northeast-1-… | S3 |
必ずバケットの中を確認し、他の人や別プロジェクトで同じバケットを使用している場合はバケットは削除しないでください。 他のパイプラインで使っていなければ、「空にする」→ 削除。 |
|
| 9 | ロググループ /ecs/ecs-handson-task | CloudWatch → ロググループ | コンテナのログ | |
| 10 | ロググループ /aws/codepipeline/ecs-handson-pipeline | CloudWatch → ロググループ | Commands アクションのログ | |
| 5. IAM | 11 | ロール AWSCodePipelineServiceRole-ap-northeast-1-ecs-handson-pipeline | IAM → ロール | インラインポリシーのecs-handson-deploy-policyも一緒に消えます |
| 12 | ロール ecsInfrastructureRoleForLoadBalancers |
IAM → ロール | ECSのサービスが削除されてから実施します。デプロイ中は絶対に削除しないでください。 | |
| 13 | ロール ecsTaskExecutionRole | IAM → ロール | 他のECSタスクで使っていなければ削除します。迷ったら残して構いません(無料) | |
| 6. ネットワーク | 14 | VPC ecs-handson-vpc | VPC → お使いの VPC | サブネット、セキュリティグループ 2 つ、インターネットゲートウェイ、ルートテーブルがまとめて消えます |
※ VPC が削除できないときは、ENI(ネットワークインターフェース)が残っています。ALB やタスクを消した直後は解放に数分かかるので、待ってから再試行してください。それでも消えなければ、EC2 コンソールの「ネットワークインターフェース」でecs-handson-vpcに紐づくものを探して手動削除します。