目次Category
はじめに
こんにちは、26卒の仲山です。
本記事では、ECSとCodeDeployを連携させたネイティブなBlue/Greenデプロイの構築手順を解説します。さらに、単なる背景色の変化だけでなく、フロントエンドから秒間10回(100ms周期)リクエストを送り続ける「リアルタイム連打カウンター」アプリを用いて、ダウンタイムゼロを実現・検証する手順をご紹介します。
本記事の目標とBlue/Greenデプロイの仕組み
まずは、本記事で達成するゴールと、Blue/Greenデプロイの概念について整理します。
- Blue/Greenデプロイとは: 現行稼働中の環境(Blue)と、まったく同じ新バージョンの環境(Green)を並行して立ち上げ、ALB(Application Load Balancer)のターゲットグループの向き先を瞬時に切り替えることで、リスクなく安全にデプロイを行う手法です。
- 今回の検証ゴール: 画面上の連打カウンター(秒間10回リクエスト送信)を動かした状態でデプロイを実行し、エラーカウント(Errors)が「0」のまま、シームレスにGreen(新バージョン)へ切り替わることを目視で確認します。
使用するAWSサービス
今回のアーキテクチャで使用する主なAWSサービスは以下の通りです。
- Amazon ECS (Fargate): コンテナを実行するサーバーレス基盤。新しいタスク定義へシームレスに切り替えることで、ダウンタイムを抑えたアプリケーションの更新を実現します。
- Application Load Balancer (ALB): ユーザーからのリクエストを受け付け、ECS(Fargate)のタスクへトラフィックをルーティングします。
- Amazon ECR (Elastic Container Registry): アプリケーションのDockerイメージを保存・管理するプライベートレジストリです。
前提条件
以下のリソースが事前に準備されていることを前提に進めます。
- 適切なVPC、パブリック/プライベートサブネット、インターネットゲートウェイなどのネットワーク環境
- AWS CLIおよびDockerがインストールされた開発端末
1. 検証用アプリの作成とECRへのプッシュ
検証用アプリの作成
以下のものを作成します
アプリフォルダ(ecs-bg-app)
┣ server.js
┗ Dockerfile
1. フォルダを作成し、エクスプローラーを起動
mkdir ecs-bg-app
cd ecs-bg-app
explorer.exe .
2. Dockerfileとserver.jsを作成
const http = require('http');
const VERSION = process.env.VERSION || 'Blue (v1.0)';
const PORT = process.env.PORT || 3000;
const HTML_TEMPLATE = `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECS B/G Tester</title>
<style>
body { font-family: sans-serif; text-align: center; padding-top: 40px; background: #f4f7f6; }
.card { background: white; max-width: 400px; margin: 0 auto; padding: 20px; border-radius: 8px; }
.stat { font-size: 1.1em; margin: 8px 0; }
.red { color: #dc3545; }
button { padding: 8px 16px; font-size: 1em; cursor: pointer; }
</style>
</head>
<body>
<div class="card">
<h2>ECS B/G Deployment Tester</h2>
<p class="stat">Version: <strong id="version">Connecting...</strong></p>
<p class="stat">Requests: <span id="total">0</span></p>
<p class="stat">Errors: <span id="errors" class="red">0</span></p>
<button id="toggleBtn" onclick="toggleTest()">Stop Test</button>
</div>
<script>
let total = 0, errors = 0, running = true;
function toggleTest() {
running = !running;
document.getElementById('toggleBtn').innerText = running ? 'Stop Test' : 'Start Test';
}
setInterval(async () => {
if (!running) return;
document.getElementById('total').innerText = ++total;
try {
let res = await fetch('/api/count');
if (!res.ok) throw new Error('HTTP ' + res.status);
let data = await res.json();
let el = document.getElementById('version');
el.innerText = data.version;
el.style.color = data.version.includes('Green') ? '#28a745' : '#007acc';
} catch (e) {
document.getElementById('errors').innerText = ++errors;
}
}, 100);
</script>
</body>
</html>`;
const server = http.createServer((req, res) => {
if (req.url === '/api/count') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ version: VERSION, timestamp: Date.now() }));
return;
}
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(HTML_TEMPLATE);
});
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}, Version: ${VERSION}`);
});
3. ECRリポジトリを作成
リポジトリ名: app-test-ecr-<name>-01
他の設定はデフォルトのままで作成。
4. プッシュコマンドを実行
DockerイメージをECRにプッシュします。
まずは、自身の使用しているシェルからAWSにログインし、ecs-bg-appディレクトリに移動してください。
もし、AWSへのログイン方法が分からない方は以下の記事を参考にしてください。
https://www.yaz.co.jp/tec-blog/cloud-basis/aws/3648#chapter-9
無事、ログイン出来たら以下のプッシュコマンドを1から順に実行してください。

※WindowsでWSLを使用していると以下のようなエラーが出ることがあります。
これは、AWS ECRが発行するトークン長が、Windows Credential Managerの許容上限を超えていることが原因です。
以下の手順を行った後に再度コマンドを実行してください。
~/.docker/config.json(Windowsの場合は%USERPROFILE%\.docker\config.json)を開きます。"credsStore": "wincred"(または"credsStore": "desktop")の行を削除して保存します。
2. ALBと2つのターゲットグループの作成
Blue/Greenデプロイでは、ALB配下に2つのターゲットグループ(Target Group A / B)が必要です。
- ターゲットグループ 1 (TG-Blue):
- ターゲットの種類: IPアドレス
- ターゲットグループ名: app-test-tg-blue-<name>-01
- プロトコル: HTTP
- ポート: 3000(Node.jsアプリのポート番号)
- VPC: 自身のもの
- ターゲットグループ 2 (TG-Green):
- ターゲットの種類: IPアドレス
- ターゲットグループ名: app-test-tg-green-<name>-01
- プロトコル: HTTP
- ポート: 3000(Node.jsアプリのポート番号)
- VPC: 自身のもの
- ALB リスナー:
- ロードバランサータイプの比較と選択: Application Load Balancer
- 基本的な設定
- ロードバランサー名: app-test-alb-<name>-01
- IP アドレスタイプ: IPv4
- ネットワークマッピング
- VPC: 先ほどターゲットグループで選んだものと同じVPC
- アベイラビリティーゾーンとサブネット
- アベイラビリティゾーン: 2つ以上チェック
- サブネット: パブリックサブネットを選択
- セキュリティグループ
- インバウンドルールで HTTP (ポート80) が許可されているセキュリティグループを選択
- リスナーとルーティング
- デフォルトのリスナー
- プロトコル: HTTP
- ポート80
- デフォルトアクション
- アクションのルーティング: ターゲットグループへ転送
- ターゲットグループ(1つ目): Blueを選択
- 重み: 1
- ターゲットグループ(2つ目): Greenを選択
- 重み: 0
※ターゲットグループの追加を押すとターゲットグループを最大3つまで追加できます。
- 重み: 0
- デフォルトのリスナー
ターゲットグループの作成


ALBの作成

3.ECSタスク定義とサービスの作成
v1デプロイ(Blueデプロイ)
タスク定義の作成
- タスク定義ファミリー: app-test-ecs-taskdef-<name>-01
- 起動タイプ: AWS Fargate
- オペレーティングシステム/アーキテクチャ:Linux/X86_64
- タスクサイズ
- CPU: 0.25 vCPU
- メモリ: 0.5 GB
- コンテナ
- 名前: app-test-ecs-container-nakayama-01
- イメージ URI: 先ほどpushしたECRのURI
- コンテナポート: 3000
- プロトコル: TCP
- 環境変数->環境変数を追加
- キー: VERSION
- 値: Blue (v1.0)
- ロードバランサー設定: 先ほど作成したALBを選び、プロダクションリスナー(80)とターゲットグループ(TG-Blue, TG-Green)を割り当てます。

クラスターの作成
- クラスター名: app-test-cluster-nakayama-01
- インフラストラクチャ: Fargateのみ
serviceの作成
- サービスの詳細
- タスク定義ファミリー: 先ほど作成したもの
- タスク定義のリビジョン: 1
- サービス名: app-test-ecs-taskdef-service-<name>-01
- 環境
- コンピューティングオプション: 起動タイプ
- 起動タイプ: Fargate
- デプロイ設定
- スケジューリング戦略: レプリカ
- 必要なタスク: 1
- デプロイオプション
- デプロイ戦略: ブルー/グリーン
- デプロイベイク時間: 15
- ネットワーキング
- VPC: 自身のもの
- サブネット: ALBで選択したパブリックサブネット2つを選択
- セキュリティグループ: インバウンドルールにポート3000(Node.jsアプリのポート)へのアクセスを許可しているもの
- ロードバランシング
- ロール: ECS用のもの
- ※無ければ新しいロールを作成
- ロードバランサーの種類: Application Load Balancer
- ロードバランサーの選択: 「既存のロードバランサーを使用する」にし、先ほど作ったALBを選択
- リスナー: 既存のリスナーを使用
- リスナー: HTTP: 80
- 本番リスナールール: 優先度:default
- ターゲットグループ
- オプション: 2つの既存のターゲットグループを使用
- ターゲットグループ: Blueのもの
- グリーンターゲットグループ: Greenのもの
- ロール: ECS用のもの

サービスを作成すると、デプロイが始まります。
デプロイが完了したら、ロードバランサーのDNSをコピーしブラウザのURLに張り付けアプリが動いていることを確認しましょう。
※httpsになっている場合はhttpにしてください。
v2デプロイ(Greenデプロイ)
Dockerfile (またはコードの環境変数)を開き、VERSION の部分を Green (v2.0) に書き換える
Dockerイメージを新しくビルド・ECRへプッシュ
3と4のタグ付与とpushコマンドのみ以下のようにlatestをv2.0に変更してください
例: docker tag app-test-ecr-nakayama-01:latest 123456789123..dkr.ecr.ap-northeast-3.amazonaws.com/app-test-ecr-nakayama-01:v2.0
docker push 123456789123.dk
r.ecr.ap-northeast-3.amazonaws.com/app-test-ecr-nakayama-01:v2.0
タスク定義の「新しいリビジョン(v2用)」を作成する
先ほど作成したタスク定義を開き、『新しいリビジョンの作成』ボタンを押して必要箇所のみ変更します。
- コンテナ
- イメージ URI: 先ほどpushしたECRのURIの末尾に「:v2.0」をつけたもの
- 例: dkr.ecr.ap-northeast-?.amazonaws.com/app-test-ecr-nakayama-01:v2.0
- イメージ URI: 先ほどpushしたECRのURIの末尾に「:v2.0」をつけたもの
- 環境変数->環境変数を追加
- キー: VERSION
- 値: Green (v2.0)

次に、もう一度先ほどのWebアプリケーションを開きカウンターが動いているのを確認してください。
ECSサービスを更新
先ほど作成したサービスを選択し、右上の「サービスを更新」を選択してください。
- タスク定義ファミリー: app-test-ecs-taskdef-<name>-01
- タスク定義のリビジョン: 2(最新のもの)
- デプロイ戦略: ブルー/グリーン

以上の設定を終えたら、更新を押してください。
更新を押したらアプリケーションを見つめていてください。
errorが0で、ダウンタイム無しでデプロイ出来ているのが見れると思います!
以上で工程は終了です。
終わりに
今回は、Amazon ECSのネイティブBlue/Greenデプロイの構築と、連打カウンターアプリを用いたダウンタイムゼロの検証を行いました。
検証が終わったら、予期せぬAWSコストが発生しないよう、ECSサービス、ALB、ターゲットグループ、CodeDeployリポジトリなどのリソースを忘れずに削除または停止してください。
本記事が、ECS運用の参考になれば幸いです。
最後までお読みいただきありがとうございました!
同じカテゴリーの記事
同じカテゴリの記事を読む