ECSのネイティブなBlue/Greenデプロイを試してみた
はじめに
こんにちは、八亀です。
ECS を使用した経験がなかったため、理解を深めるために ECS(Fargate)を使った Blue/Green デプロイを実際に構築してみました。
本記事では、AWS マネジメントコンソールを使用して、シンプルな Flask アプリケーションを題材に、v1 から v2 への Blue/Green デプロイの手順をまとめています。
こんな方におすすめ:
- ECS を触ったことがない方
- Blue/Green デプロイを実際に動かしてみたい方
- マネジメントコンソールでの操作を学びたい方
今回作るもの
以下の構成を作成し、v1 → v2 のデプロイでトラフィック切替を確認します:
- Application Load Balancer(ALB)+ 2 つのターゲットグループ(Blue/Green)
- ECS Fargate(Flask アプリ)
- Blue/Green デプロイ戦略
注記:下図は v2 デプロイ完了後の構成イメージです。
前提条件
本手順を実施する前に、以下のリソースを事前に準備してください。
- リージョン:東京リージョン(ap-northeast-1)
- VPC:1 つ(CIDR: 10.0.0.0/16 など)
- パブリックサブネット:2 つ(異なるアベイラビリティーゾーン)
- サブネット 1:10.0.1.0/24(ap-northeast-1a)
- サブネット 2:10.0.2.0/24(ap-northeast-1c)
- パブリック IPv4 アドレスの自動割り当て:有効
- インターネットゲートウェイ:VPC にアタッチ済み
- ルートテーブル:パブリックサブネット用(0.0.0.0/0 → IGW)
注意:本記事内のリソース名は例です。ご自身の環境に合わせて適宜変更してください。
STEP 1:セキュリティグループの作成
今回の構築に必要なセキュリティグループを事前に作成します。
ALB 用セキュリティグループ:
- 名前:alb-yakame
- インバウンドルール:HTTP(80)、ソース:0.0.0.0/0
ECS 用セキュリティグループ:
- 名前:ecs-yakame
- インバウンドルール:カスタム TCP(8080)、ソース:alb-yakame
STEP 2:ALB とターゲットグループの作成
次に、トラフィックを受け付ける ALB と、Blue/Green デプロイに必要な 2 つのターゲットグループを作成します。
ターゲットグループ作成
- EC2 コンソール → ターゲットグループ → 「ターゲットグループの作成」
Blue用ターゲットグループ:
- ターゲットタイプを選択:IP アドレス
- ターゲットグループ名:tg-blue-yakame
- プロトコル:HTTP
- ポート:8080
- VPC:yakame-vpc
- プロトコルバージョン:HTTP/1
- 「次へ」をクリック
- ターゲットの登録画面では何も登録せずに「ターゲットグループの作成」をクリック
Green用ターゲットグループ:
同様の手順で作成:
- ターゲットグループ名:tg-green-yakame
- その他の設定:tg-blue-yakame と同じ
ALB 作成
基本的な設定:
- ロードバランサー名:ecs-alb-yakame
- スキーム:インターネット向け
- IP アドレスタイプ:IPv4
アベイラビリティーゾーンとサブネット:
- ap-northeast-1a → サブネット:yakame-public-1a
- ap-northeast-1c → サブネット:yakame-public-1c
セキュリティグループ:
- セキュリティグループ:alb-yakame
リスナーとルーティング:
- プロトコル:HTTP
- ポート:80
デフォルトアクション:
- アクションのルーティング:ターゲットグループへ転送
- ターゲットグループ:tg-blue-yakame(重み:1)
- 「ターゲットグループの追加」をクリック
- ターゲットグループ:tg-green-yakame(重み:0)
STEP 3: アプリケーション準備
ここでは、ECS で動かす Flask アプリケーションを作成し、ECR にプッシュします。
前提条件として、以下の環境を用意してください:
- Docker がインストール済み
- AWS CLI がインストール・設定済み
Docker と AWS CLI の環境構築については、以下の記事を参考にしてください:
ECRリポジトリ作成
- ECR コンソールを開く
- 「リポジトリを作成」をクリック
設定内容:
- リポジトリ名:flask-app-yakame
- イメージタグのミュータビリティ:Mutable
- 暗号化設定:AES-256
アプリケーションコード作成
以下のファイルを作成します。
app.py
from flask import Flask
import os
app = Flask(__name__)
@app.route("/")
def hello():
version = os.environ.get("APP_VERSION", "unknown")
return f"Hello from ECS Fargate! Version: {version}"
@app.route("/health")
def health():
return "OK", 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
Dockerfile
FROM public.ecr.aws/docker/library/python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
ENV APP_VERSION=v1
EXPOSE 8080
CMD ["python", "app.py"]
requirements.txt
flask==3.1.2
Dockerイメージビルド & Push
ターミナルで以下を実行:
ECR_REPO
は自身のリポジトリ名に置き換えてください。
アカウントID取得
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION=ap-northeast-1
ECR_REPO="flask-app-yakame"
ECR_URI="$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$ECR_REPO"
Dockerイメージビルド
docker build -t $ECR_REPO:v1 .
ECRログイン
aws ecr get-login-password --region $REGION | \
docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com
タグ付け
docker tag $ECR_REPO:v1 $ECR_URI:v1
Push
docker push $ECR_URI:v1
STEP 4:ECS サービス作成(v1 デプロイ)
ECS 環境を作成し、v1 アプリケーションをデプロイします。
ECSクラスター作成
ECS コンソール →「クラスター」→「クラスターの作成」
設定内容:
- クラスター名:ecs-cluster-yakame
- インフラストラクチャ:Fargate のみ
その他項目はデフォルトのままで作成
タスク定義作成
ECS コンソール → タスク定義 → 「新しいタスク定義の作成」
タスク定義の設定:
- タスク定義ファミリー:task-flask-app-yakame
- 起動タイプ:AWS Fargate
- オペレーティングシステム/アーキテクチャ:Linux/X86_64
タスクサイズ:
- CPU:0.25 vCPU
- メモリ:0.5 GB
タスクロール:
- タスクロール:なし(アプリケーションがAWSサービスにアクセスする場合に必要)
- タスク実行ロール:ecsTaskExecutionRole(ECRからのイメージpullに必要)
(存在しない場合は「新しいロールの作成」ボタンから作成)
コンテナの詳細:
- コンテナ名:flask-container
- イメージ URI:ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/flask-app-yakame:v1
(ECRイメージを閲覧からプライベートリポジトリを選択し、イメージタグを使用を押下)
ポートマッピング:
- コンテナポート:8080
- プロトコル:TCP
- ポート名:flask-8080-tcp-yakame
- アプリケーションプロトコル:HTTP
ECSサービス作成
- ECS コンソール → クラスター → ecs-cluster-yakame
- 「サービス」タブ → 「作成」
サービスの詳細:
- タスク定義ファミリー:task-flask-app-yakame
- タスク定義のリビジョン:1
- サービス名:task-flask-app-service-yakame
環境:
- コンピューティング設定:キャパシティープロバイダー戦略
デプロイ設定:
- スケジューリング戦略:レプリカ
- 必要なタスク:1
デプロイオプション:
- デプロイ戦略:ブルー/グリーン
- ベイク時間:15 分
ベイク時間とは、本番トラフィックがグリーンにシフトした後、安定動作を監視するため、ブルータスクが削除されるまでの時間(分)です。検証用であれば 0 分でも問題ありません。今回はデフォルトのまま設定しています。
- トラフィック移行:すべてのトラフィックを一度に移行
- デプロイライフサイクルフック:なし
ネットワーキング:
- VPC:yakame-vpc
- サブネット:
- yakame-public-1a
- yakame-public-1c
- セキュリティグループ:
- 既存のセキュリティグループを使用
- ecs-yakame
- パブリック IP:オンにする
注意:本番環境では、ALBを前段に置く構成の場合、ECSタスクはプライベートサブネットに配置することが推奨されます。今回は検証のため、パブリックサブネットに配置しています。
ロードバランシング:
- ロードバランシングを使用
- ロードバランサーの種類:Application Load Balancer
- コンテナ:flask-container 8080:8080 を選択
- Application Load Balancer:既存のロードバランサーを使用
- ロードバランサー:ecs-alb-yakame
- リスナー:既存のリスナーを使用
- HTTP:80
- 本番リスナールール:優先度 default
- ターゲットグループのオプション:2 つの既存のターゲットグループを使用
- ターゲットグループ:tg-blue-yakame
- 代替ターゲットグループ:tg-green-yakame
STEP 5:v1デプロイ確認
サービス作成後、v1 が正常にデプロイされたか確認します。
ターゲットグループ確認:
- tg-green-yakame:1 healthy
- tg-blue-yakame:0
ALB リスナー確認:
- tg-green-yakame:100%
- tg-blue-yakame:0%
初回デプロイ完了後、トラフィックが自動的にGreenに切り替わっています。
アプリケーション動作確認:
ALB の DNS 名でアクセスして、v1 が正常に動作していることを確認します。
STEP 6:v2デプロイ
v2アプリケーション作成
ローカルにある Dockerfile の以下の内容を編集します。
- ENV APP_VERSION=v1 → ENV APP_VERSION=v2
その後、v1 と同様の手順で v2 イメージをビルド・Push します。(STEP 3参照)
コマンド内の v1 を v2 に変更してください。
タスク定義リビジョン作成(v2)
ECS コンソール → タスク定義 → task-flask-app-yakame → 「新しいリビジョンの作成」
変更箇所:
- イメージ URI:
ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/flask-app-yakame:v2
その他の設定はそのまま作成します。
これでタスク定義のリビジョン 2 が作成されます。
ECS サービス更新(v2 デプロイ)
- ECS コンソール → クラスター → ecs-cluster-yakame
- サービス:task-flask-app-service-yakame を選択
- 「サービスを更新」をクリック
デプロイ設定:
- リビジョン:2 を選択
その他の設定は変更しないで「更新」
STEP 7:v2デプロイ確認
Bake time(15 分)経過後、自動的にトラフィックが切り替わります。
ターゲットグループ確認:
- tg-blue-yakame:1 healthy(v2)
- tg-green-yakame:0
ALB リスナー確認:
- tg-blue-yakame:100%
- tg-green-yakame:0%
アプリケーション動作確認:
ALB の DNS 名でアクセスして、v2 が正常に動作していることを確認します。
おわりに
本記事では、Amazon ECS(Fargate) と ALB を使った Blue/Green デプロイ を実装してみました。
マネジメントコンソールで実際に手を動かすことで、ECS の基本的な構成要素や Blue/Green デプロイの動作を体験することができました。
本記事では紹介できませんでしたが、時間がある方は、ロールバックや異常検知時の自動ロールバックなども試してみると、より実践的な理解が深まります。
参考資料
-
Amazon Elastic Container Service とは - Amazon Elastic Container Service
-
Amazon ECS 用の CodeDeploy ブルー/グリーンデプロイ - Amazon Elastic Container Service
-
M1 Mac に Rancher Desktop を導入して、コンテナ管理してみる (Version 1.9.1) | DevelopersIO
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。