本記事は「2025 Japan AWS Jr. Chanpions 夏のQiitaリレー 」の35日目の記事です。
過去の投稿はこちらからご覧ください!
はじめに
2025年7月17日より、ECS の組み込みBlue/Greenデプロイがリリースされました!
従来は、Blue/Greenデプロイの際は、CodeDeployを使う必要がありましたが、ECSの機能で、Blue/Greenデプロイができるようになりました。
ちょうど、Codeシリーズの勉強しているタイミングでのリリースだったので、さっそくCodePipelineでECSの組み込みBlue/Greenデプロイを使用できるのか試してみました。
これまでBlue/Greenデプロイについてはほとんど触れてきていないので、初心者目線の記事になります。
今回はAWS公式のCI/CDハンズオンを活用しています。このハンズオンのBlue/Greenデプロイのパートを従来のCodeDeployを使用した方法ではなく、ECS組み込みBlue/Greenデプロイに置き換えて実施してみます。
目次
ECS組み込みBlue/Greenデプロイ設定
具体的にやってみる前に、ECS組み込みBlue/Greenデプロイの設定内容を確認していきます。
ECSのサービスのデプロイ戦略の項目で、ブルー/グリーンが選択できるようになっています。
ベイク時間
ベイク時間とは、本番トラフィックをGreenの(新しい)サービスリビジョンが100%受けるようになってから、監視やロールバックのために、Blueの(古い)サービスリビジョンも引き続き実行している、つまりBlueとGreenのタスク両方が実行されている期間のことです。時間は0~1440分を選択できます。
トラフィック移行
トラフィック移行は、BlueのサービスリビジョンからGreenのサービスリビジョンへトラフィックを切り替えるために使用するアルゴリズムです。
現在のECSは、トラフィックを一度に切り替える機能をサポートしています。
CodeDeployでは、1分ごとに10%の割合でGreenに切り替え、などの選択できるためこの点は注意が必要かと思います。
デプロイメントのライフサイクルステージとデプロイライフサイクルフック
デプロイメントには、ライフサイクルステージがあります。
各ステージで組み込みの検証チェックポイントを行い、検証が失敗したら自動でロールバックするようになっています。
また、デプロイ中の各ステージでLambda関数を呼び出してデプロイ成否をカスタムロジックで検証できる、ライフサイクルフックの機能も設定できます。
各ステージの内容を簡単に以下にまとめました。
ステージ名 | 説明 | ライフサイクルフック設定可否 |
---|---|---|
RECONCILE_SERVICE(サービスを調整) | ACTIVE状態にあるサービスリビジョンが1つ以上ある状態で新しいサービス展開が開始された状態 | 可 |
PRE_SCALE_UP(スケールアップ前) | グリーンのサービスリビジョンが開始される前の状態 | 可 |
SCALE_UP(スケールアップ) | グリーンのサービスリビジョンを開始している最中の状態 | 否 |
POST_SCALE_UP(スケールアップ後) | グリーンのサービスリビジョンが開始した状態 | 可 |
TEST_TRAFFIC_SHIFT(テストトラフィック移行) | ブルーとグリーンのサービスリビジョンが両方動き、本番トラフィックはブルーが受け、テストトラフィックをグリーンに0%→100%ずつ移行している状態 | 可 |
POST_TEST_TRAFFIC_SHIFT(テストトラフィック移行後) | ブルーとグリーンのサービスリビジョンが両方動き、本番トラフィックはブルーが受け、テスト用トラフィックはグリーンが100%受けるようになった状態 | 可 |
PRODUCTION_TRAFFIC_SHIFT(本番トラフィック移行) | 本番トラフィックをグリーンに0%→100%ずつ移行している状態 | 可 |
POST_PRODUCTION_TRAFFIC_SHIFT(本番トラフィック移行後) | 本番トラフィックをグリーンが100%受けるようになった状態 | 可 |
BAKE_TIME(ベイク時間) | ブルーとグリーンのサービスリビジョンが両方実行されている状態 | 否 |
CLEAN_UP | ブルーのサービスリビジョンが0になった状態 | 否 |
Application Load Balancer
Blue/Greenデプロイで、トラフィックを分散させるために、ALBを使用することができます。
後述の手順でも、ALBを使用したBlue/Greenデプロイ方法を実施しました。(他にもNetwork Load BalancerやService Connectを使う方法もあります。)
ALB利用時には、本番用のターゲットグループ・リスナー・リスナールールに加えて、テストトラフィックを流すためのターゲットグループ・リスナー・リスナールールが必要です。
ALBを使った、Blue/Greenデプロイの流れは以下のイメージです。
本番用のリスナーを80ポート、テスト用のリスナーを81ポートと想定しています。
まずテスト用リソースを使って、テストトラフィックを実施し、問題なければ本番トラフィックをGreenのサービスリビジョンに流していくという、デプロイの流れになります。
手順前の状態
ハンズオンで、一通り本番環境へのデプロイ(Blue/Greenデプロイではなく通常のデプロイ)までの作成を終えている状態から、ECS組み込みBlue/Greenデプロイに手順を以下に記載します。
ここまでの手順は、CI/CDハンズオンを実施してみてください。
通常のデプロイで本番環境へのデプロイまで組んだパイプラインは以下になります。
GitHubリポジトリのmainブランチをソースとし、テストステージ→Docker Pushステージ→テスト環境へのデプロイステージ→承認後に本番環境へのデプロイというパイプラインになっています。
なお、ハンズオンはCDKを使ってリソースを作成していますが、ECS組み込みBlue/Greenデプロイの実装はマネージメントコンソールから実施します。
手順
必要なリソースの作成
ハンズオンではALBと本番用のリスナー・ターゲットグループは作成されているので、Green用のターゲットグループとテスト用のリスナーを追加で作成します。
Green用ターゲットグループ
テスト用リスナー
81ポートで設定します。転送先は、Green用のターゲットグループに100%流れるように設定しています。
IAMロール
Blue/Greenデプロイを実装する際は、ECSのサービスがELBのリスナー設定を変更したりするための特定のIAMロールが必要だそうです。
設定は、公式ドキュメントを参考にしました。
ポリシーは、マネージドポリシーAmazonECSInfrastructureRolePolicyForLoadBalancers
を設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAccessToECSForInfrastructureManagement",
"Effect": "Allow",
"Principal": {
"Service": "ecs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
ECSのサービスを更新
ハンズオンで既にサービスが作成済みのためこのサービスを更新していきます。
デプロイ戦略を、ブルー/グリーンに変更します。
今回は、ライフサイクルフックは設定しないで実施してみます。
ロードバランサーもハンズオンで作成済みのものを設定していきます。
本番リスナーには既存のリスナーを設定し、テストリスナーに先ほど作成したテスト用リスナーを設定します。
ターゲットグループは既存のターゲットグループを使用を選択し、ターゲットグループにBlueが設定されているターゲットグループを設定し、代替ターゲットグループに、先ほど作成したGreen用のターゲットグループを設定します。
(新しく作成を選択することもできます。)
新しいイメージをデプロイ
現時点では、80ポートでBlueと書かれた画面へアクセスできるようになっています。
UIをGreenに変更
すでに、ハンズオンの方でGitHubに変更がプッシュされたらデプロイまでのパイプラインが走るように設定してあるので、Blueと表示される箇所をGreenに変更して、GitHubリポジトリにプッシュします。
$ git add .
$ git commit -m "Modify Green"
$ git push origin main
デプロイを実行
本番環境デプロイの承認を実施し、本番環境デプロイを実行します。
デプロイ開始~完了の動きを確認
ECSのサービス側でデプロイが開始されました。サービスリビジョンでGreenのターゲットグループがターゲットとして設定されたことが確認できます。
この時点でのデプロイ段階は、スケールアップ前
となっています。
デプロイ段階はテストトラフィック移行
に変わりました。
テスト用の81ポートにアクセスしてみると、Greenへアクセスできるようになりました。
この時点で、80ポートはまだBlueのままです。
80ポートにアクセスしてみると、Greenに切り替わっています。
ターゲットグループを確認してみると、80ポートのリスナーの転送先が、Greenのターゲットグループに切り替わっています。
本番トラフィック移行後に問題がなければ、ベイク時間
に移行します。
設定したベイク時間が終了すると、デプロイのステータスが成功になりました。サービスリビジョンもGreenのみに変わりました。
Blueをターゲットとしていたターゲットグループからは、Blueのコンテナが登録解除されています。
CodePipelineの方もベイク時間が終了してデプロイが成功したタイミングで、成功ステータスになりました。
おわりに
ECSの組み込みBlue/Greenデプロイを試しに実施してみました。まだLambdaのライフサイクルフック機能やService Connectを使った方法など、試せていないことがたくさんあるので、これからもっと試してみようと思います!
トラフィック移行はまだAt all Onceしかサポートしていないので、今後の拡張に期待しています。
CodePipeline側では、デプロイステージでECSアクションを選択するだけでいいので、その点は非常に楽だと感じました!