🚀 CodeシリーズでECS Fargate
ローリングデプロイ完全ガイド

フードトラックの営業継続リニューアルで理解する!ゼロから本番運用までの完全マニュアル

📑 目次

1 たとえ話で理解する全体像
2 ローリングデプロイの仕組み
3 デプロイ方式の比較と選択
4 実装ステップバイステップ
5 設定ファイル完全解説
6 IAMロール・ポリシー設定
7 トラブルシューティング
8 監視・アラート設定
9 コスト・マルチ環境・FAQ

🍔 フードトラックの「営業しながらメニュー刷新」で例えると超わかりやすい!

ECS Fargateのローリングデプロイ = お店を閉めずにメニューを新しくすること!

フードトラックが4台で営業中。新メニューに切り替えたいけど、
全部同時に閉めたらお客さんが困る... だから1台ずつ順番にリニューアル!

これをAWSのCodeシリーズで 完全自動化 する方法を
ゼロから本番運用まで 徹底解説します✨

🚚 1. フードトラックチェーンで理解する全体像

AWS用語 ↔ フードトラック用語の対応表

🚚 フードトラック

料理を提供する車両
4台で営業中

=

🐳 ECSタスク

アプリを実行するコンテナ
4タスクで稼働中

📋
レシピブック = Dockerイメージ 料理の作り方 = アプリの実行環境
🏭
セントラルキッチン = CodeBuild 新メニュー試作 = イメージビルド
📦
レシピ保管庫 = ECR 完成レシピの倉庫 = イメージレジストリ
🏢
本部 = CodePipeline 全体の指揮 = CI/CDオーケストレーション
👨‍🍳
シェフ = 開発者 新レシピ開発 = コード変更
🚦
交通整理係 = ALB お客さんを空いてる車に案内 = ロードバランシング
🔄
順番にリニューアル = ローリングデプロイ 1台ずつ新メニューに切替 = 順次タスク更新
営業確認 = ヘルスチェック ちゃんと料理出せてる? = アプリ正常?

🔄 2. ローリングデプロイの仕組み

📊 タスク数4の場合のデプロイ進行イメージ

開始前
v1
v1
v1
v1
全4タスクが旧バージョン(v1)で稼働中
Phase 1
v1
v1
v1
v1
v2
新タスク(v2)を追加起動
→ 一時的に5タスク稼働
Phase 2
v1
v1
v1
v1
v2
v2のヘルスチェックOK
→ v1を1つ停止開始
Phase 3
v1
v1
v2
v2
繰り返し...
v1: 2台, v2: 2台
完了
v2
v2
v2
v2
全タスクがv2に更新完了!
ダウンタイムゼロ🎉
旧バージョン(v1) 新バージョン(v2) 起動中 停止中

⚙️ minimumHealthyPercent: 100%

デプロイ中も 最低100%のタスクを維持
つまり、旧タスクを停止する前に必ず新タスクが正常稼働していることを保証。
minimumHealthyPercent = 100

⚙️ maximumPercent: 200%

一時的に 最大200%(2倍)のタスク を許容。
これにより、新タスクを追加してからヘルスチェック後に旧タスクを停止できる。
maximumPercent = 200

⚖️ 3. デプロイ方式の比較と選択

🔄

ECS標準ローリングデプロイ

✅ 今回解説する方式
  • CodeDeployが不要 でシンプル
  • 追加コストがほぼかからない
  • 設定がシンプルで学習コストが低い
  • タスクを順次入れ替え
  • ロールバックは再デプロイで対応
  • 小〜中規模サービスに最適
🔵🟢

CodeDeploy Blue/Green

高度な制御が必要な場合
  • CodeDeployが必要
  • 新環境を完全に構築してから切替
  • 瞬時のロールバックが可能
  • トラフィック段階的シフト可能
  • 一時的に2倍のリソース費用
  • 大規模・ミッションクリティカルに最適

🤔 どちらを選ぶべき?判断フローチャート

瞬時のロールバックが必須?
YES
Blue/Green(CodeDeploy)
NO
トラフィックを段階的に移行したい?
YES
Blue/Green
NO
✅ ローリング(推奨)

🔗 CodePipelineの4ステージ構成

1
📝
Source
CodeCommit / GitHub
コード変更を検知してパイプライン開始。
mainブランチへのpushで自動トリガー。
2
🔨
Build
CodeBuild
Dockerイメージをビルド&テスト。
ECRにプッシュ、imagedefinitions.json出力。
3
🚀
Deploy
ECS Deploy Action
ECSサービスを更新。
ローリングデプロイで順次タスク入替。
4
Complete
ECS Fargate
全タスクが新バージョンで稼働。
ダウンタイムゼロでデプロイ完了!

🛠️ 4. 実装ステップバイステップ

🏗️

前提条件の準備

パイプライン構築前に必要なAWSリソースを準備します。

必要なリソース:

  • VPC : パブリック/プライベートサブネット、NAT Gateway
  • ALB : ターゲットグループ、リスナー設定
  • ECR : コンテナイメージ用リポジトリ
  • ECSクラスター : Fargateクラスター
  • CloudWatch Logs : ロググループ
  • セキュリティグループ : ALB用、タスク用
📝

ソースリポジトリの準備

CodeCommitまたはGitHubにリポジトリを作成し、必要なファイルを配置します。

リポジトリ構成:
  • Dockerfile - コンテナイメージ定義
  • buildspec.yml - CodeBuildの設定
  • taskdef.json - ECSタスク定義(オプション)
  • src/ - アプリケーションコード
🐳

ECSタスク定義の作成

ECSコンソールまたはCLIでタスク定義を作成します。

設定ポイント:
  • 起動タイプ: FARGATE
  • ネットワークモード: awsvpc
  • イメージ: ECRのリポジトリURIを指定
  • ログ設定: CloudWatch Logsを設定
⚙️

ECSサービスの作成

タスク定義を使ってECSサービスを作成します。

重要な設定:
  • デプロイタイプ: ローリング更新
  • minimumHealthyPercent: 100
  • maximumPercent: 200
  • ヘルスチェック猶予期間: 60秒〜
  • デプロイサーキットブレーカー: 有効
🔨

CodeBuildプロジェクトの作成

Dockerイメージをビルドするプロジェクトを作成します。

設定ポイント:
  • 環境イメージ: aws/codebuild/amazonlinux2-x86_64-standard:4.0
  • 特権モード: 有効 (Docker使用時必須)
  • サービスロール: ECRアクセス権限を付与
  • 環境変数: AWS_ACCOUNT_ID, IMAGE_REPO_NAME等
🔗

CodePipelineの作成

全体を統括するパイプラインを作成します。

ステージ構成:
  • Source : CodeCommit/GitHub接続
  • Build : CodeBuildプロジェクト指定
  • Deploy : Amazon ECSアクション選択、クラスター・サービス指定

📄 5. 設定ファイル完全解説

buildspec.yml
Dockerfile
imagedefinitions.json
📝 buildspec.yml(CodeBuild設定)
version: 0.2

phases:
  pre_build:
    commands:
      # ECRにログイン
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      # イメージタグにコミットハッシュを使用(latestは避ける)
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
  
  build:
    commands:
      # Dockerイメージをビルド
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:$IMAGE_TAG .
      - docker tag $REPOSITORY_URI:$IMAGE_TAG $REPOSITORY_URI:latest
  
  post_build:
    commands:
      # ECRにプッシュ
      - echo Pushing the Docker image...
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - docker push $REPOSITORY_URI:latest
      # ★重要: imagedefinitions.jsonを出力(CodePipelineのECSデプロイで使用)
      - printf '[{"name":"my-container","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
      - cat imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json  # ★これが必須!
💡 重要ポイント: imagedefinitions.json は、CodePipelineのECSデプロイアクションが どのイメージでタスク定義を更新するか を知るために必須のファイルです。このファイルがないとデプロイが失敗します。
📝 Dockerfile(シンプルなNode.js例)
# ベースイメージ
FROM node:18-alpine

# 作業ディレクトリ
WORKDIR /app

# 依存関係をインストール
COPY package*.json ./
RUN npm ci --only=production

# アプリケーションコードをコピー
COPY . .

# ヘルスチェック用エンドポイント
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

# ポート公開
EXPOSE 3000

# アプリケーション起動
CMD ["node", "server.js"]
📝 imagedefinitions.json(出力形式)
// ECS標準デプロイで使用する形式
[
  {
    "name": "my-container",        // タスク定義のコンテナ名と一致させる
    "imageUri": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:abc1234"
  }
]
⚠️ 注意: imageDetail.json (CodeDeploy用)と imagedefinitions.json (ECS標準デプロイ用)は 形式が異なります 。今回のローリングデプロイでは imagedefinitions.json を使用します。

🔐 6. IAMロール・ポリシー設定

🔨 CodeBuildサービスロール

CodeBuildがECRにプッシュするために必要な権限

必要な権限:

  • ecr:GetAuthorizationToken
  • ecr:BatchCheckLayerAvailability
  • ecr:GetDownloadUrlForLayer
  • ecr:PutImage
  • ecr:InitiateLayerUpload
  • ecr:UploadLayerPart
  • ecr:CompleteLayerUpload
  • logs:CreateLogStream
  • logs:PutLogEvents

🔗 CodePipelineサービスロール

パイプラインが各サービスを操作するために必要

必要な権限:
  • codecommit:GetBranch(またはGitHub接続権限)
  • codebuild:StartBuild
  • codebuild:BatchGetBuilds
  • ecs:DescribeServices
  • ecs:UpdateService
  • ecs:DescribeTaskDefinition
  • ecs:RegisterTaskDefinition
  • iam:PassRole
  • s3:GetObject / s3:PutObject

🐳 ECSタスク実行ロール

Fargateがコンテナを起動するために必要

必要な権限:
  • ecr:GetAuthorizationToken
  • ecr:BatchCheckLayerAvailability
  • ecr:GetDownloadUrlForLayer
  • ecr:BatchGetImage
  • logs:CreateLogStream
  • logs:PutLogEvents
  • secretsmanager:GetSecretValue(必要時)

📋 ECSタスクロール(オプション)

コンテナ内のアプリがAWSサービスを使う場合

アプリに応じて付与:
  • s3:GetObject / s3:PutObject
  • dynamodb:GetItem / dynamodb:PutItem
  • sqs:SendMessage / sqs:ReceiveMessage
  • sns:Publish
  • その他アプリが必要とする権限

🔧 7. トラブルシューティング

タスクがPENDING状態のまま起動しない

ResourceInitializationError: unable to pull secrets or registry auth

🔍 原因と対策:

  • ECRへのアクセス権限不足 : タスク実行ロールにECR権限があるか確認
  • VPCエンドポイント未設定 : プライベートサブネットの場合、ECR/S3/CloudWatch Logsのエンドポイントが必要
  • セキュリティグループ : アウトバウンド443が許可されているか確認
# タスク停止理由の確認 aws ecs describe-tasks --cluster my-cluster --tasks arn:aws:ecs:... --query 'tasks[].stoppedReason' # サービスイベントの確認 aws ecs describe-services --cluster my-cluster --services my-service --query 'services[].events[:5]'

ヘルスチェックに失敗し続ける

service my-service is unable to consistently start tasks successfully
🔍 原因と対策:
  • アプリ起動時間 : healthCheckGracePeriodSecondsを延長(60→120秒など)
  • ヘルスチェックパス : ALBのヘルスチェックパスが正しいか確認(/health等)
  • ポートマッピング : コンテナポートとターゲットグループのポートが一致しているか
  • セキュリティグループ : ALB→タスク間の通信が許可されているか
# コンテナログの確認 aws logs tail /ecs/my-app --follow # ターゲットグループのヘルスステータス確認 aws elbv2 describe-target-health --target-group-arn arn:aws:elasticloadbalancing:...

CodePipelineのDeployステージが失敗

Invalid action configuration: ImageDefinitions file not found
🔍 原因と対策:
  • ファイル名の確認 : imagedefinitions.json (sが付く)が正しいか
  • artifacts設定 : buildspec.ymlのartifactsにファイルが含まれているか
  • コンテナ名の一致 : imagedefinitions.jsonのnameがタスク定義のコンテナ名と一致しているか
# CodeBuildの出力アーティファクトを確認(S3バケット内) aws s3 ls s3://codepipeline-bucket/my-pipeline/BuildArtif/

デプロイが終わらない・ロールバックされる

Deployment circuit breaker triggered
🔍 原因と対策:
  • サーキットブレーカー発動 : 新タスクが連続して失敗している
  • リソース不足 : CPU/メモリが足りない、Fargateのキャパシティ不足
  • ログ確認 : CloudWatch Logsでアプリのエラーを確認
# デプロイメントの詳細確認 aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[].deployments' # 失敗したタスクの停止理由確認 aws ecs list-tasks --cluster my-cluster --service-name my-service --desired-status STOPPED

📊 8. 監視・アラート設定

📈

ECSサービスメトリクス

タスクの状態とリソース使用率を監視

監視項目:

  • ✓ CPUUtilization(CPU使用率)
  • ✓ MemoryUtilization(メモリ使用率)
  • ✓ RunningTaskCount(実行中タスク数)
  • ✓ DesiredTaskCount(希望タスク数)
⚖️

ALBメトリクス

ロードバランサーの健全性を監視

監視項目:
  • ✓ HealthyHostCount(正常ホスト数)
  • ✓ UnHealthyHostCount(異常ホスト数)
  • ✓ HTTPCode_Target_5XX_Count
  • ✓ TargetResponseTime(レスポンス時間)
🔔

パイプライン通知

デプロイ成功/失敗を即座に通知

設定方法:
  • ✓ CodePipeline通知ルール作成
  • ✓ SNSトピックに連携
  • ✓ Slack/Teams/メール通知
  • ✓ 失敗時のみ通知も可能
📝 CloudWatchアラーム設定例(AWS CLI)
# デプロイ失敗検知アラーム(実行中タスク < 希望タスク)
aws cloudwatch put-metric-alarm \
  --alarm-name "ECS-RunningTaskCount-Low" \
  --alarm-description "Running tasks below desired count" \
  --metric-name RunningTaskCount \
  --namespace AWS/ECS \
  --statistic Average \
  --period 60 \
  --threshold 2 \
  --comparison-operator LessThanThreshold \
  --dimensions Name=ClusterName,Value=my-cluster Name=ServiceName,Value=my-service \
  --evaluation-periods 2 \
  --alarm-actions arn:aws:sns:ap-northeast-1:123456789012:my-alerts

# 5xxエラー急増アラーム
aws cloudwatch put-metric-alarm \
  --alarm-name "ALB-5xxErrors-High" \
  --metric-name HTTPCode_Target_5XX_Count \
  --namespace AWS/ApplicationELB \
  --statistic Sum \
  --period 60 \
  --threshold 10 \
  --comparison-operator GreaterThanThreshold \
  --dimensions Name=LoadBalancer,Value=app/my-alb/xxx Name=TargetGroup,Value=targetgroup/my-tg/xxx \
  --evaluation-periods 1 \
  --alarm-actions arn:aws:sns:ap-northeast-1:123456789012:my-alerts

💰 9. コスト情報

サービス 料金体系 目安(東京リージョン)
CodePipeline パイプライン数 × 月額 $1/パイプライン/月(最初の1つは無料)
CodeBuild ビルド時間(分単位) $0.005/分〜(general1.small)
毎月100分無料
ECR ストレージ + データ転送 $0.10/GB/月
最初の500MB無料
ECS(Fargate) vCPU + メモリ × 時間 vCPU: $0.05056/時間
メモリ: $0.00553/GB/時間
ALB 時間 + LCU $0.0243/時間 + LCU使用量

💡 コスト最適化のポイント

  • ECRライフサイクルポリシー : 古いイメージを自動削除してストレージ費用を削減
  • Fargate Spot : 中断可能なワークロードなら最大70%オフ
  • 適切なリソースサイジング : CPU/メモリを実際の使用量に合わせて最適化
  • ビルドキャッシュ活用 : CodeBuildのキャッシュでビルド時間短縮

🌍 マルチ環境パイプライン構成

📝
Source
🔨
Build
🧪
Dev
承認
🎭
Staging
承認
🚀
Prod
💡 ポイント: 本番環境へのデプロイ前に 手動承認ステージ を挿入することで、意図しないデプロイを防止できます。CodePipelineの「Manual approval」アクションを使用します。

✅ デプロイ前チェックリスト

📋 インフラ準備

  • VPC、サブネット、NAT Gatewayを作成
  • ALB、ターゲットグループを作成
  • ECRリポジトリを作成
  • ECSクラスターを作成
  • CloudWatch Logsグループを作成
  • セキュリティグループを適切に設定

🔐 IAM設定

  • CodeBuildサービスロールを作成
  • CodePipelineサービスロールを作成
  • ECSタスク実行ロールを作成
  • 必要に応じてタスクロールを作成
  • 最小権限の原則に従っているか確認

📝 ソースコード

  • Dockerfileが正しく動作する
  • buildspec.ymlを配置
  • imagedefinitions.jsonが出力される
  • ヘルスチェックエンドポイントがある
  • 環境変数の設定が適切

⚙️ ECS設定

  • タスク定義のコンテナ名を確認
  • minimumHealthyPercent: 100
  • maximumPercent: 200
  • healthCheckGracePeriodを適切に設定
  • デプロイサーキットブレーカー有効化
  • ログ設定が正しい

❓ よくある質問

Q1. imageDetail.jsonとimagedefinitions.jsonの違いは?
imagedefinitions.json : ECS標準デプロイ(ローリング)で使用。形式は [{"name":"コンテナ名","imageUri":"イメージURI"}]

imageDetail.json : CodeDeployを使ったBlue/Greenデプロイで使用。形式は {"ImageURI":"イメージURI"}

今回のローリングデプロイでは imagedefinitions.json を使用します。
Q2. タスク数が1つでもローリングデプロイできる?
はい、可能です!
maximumPercent: 200%の設定により、新タスクを先に起動(一時的に2タスク)→ヘルスチェックOK→旧タスク停止、という流れでダウンタイムなしでデプロイできます。
ただし、可用性を考えると本番環境では2タスク以上を推奨します。
Q3. デプロイに失敗したらどうなる?
デプロイサーキットブレーカーを有効 にしておくと、新タスクの起動が連続して失敗した場合に自動でロールバックします。
無効の場合は、新タスクが起動できず古いタスクが稼働し続けます。
本番環境では必ずサーキットブレーカーを有効にしましょう!
Q4. GitHubを使う場合の接続方法は?
CodePipeline V2のGitHub接続 を使用します。
1. CodePipelineコンソールで「設定」→「接続」から新規作成
2. GitHubにOAuth認証でログイン
3. リポジトリへのアクセスを許可
4. パイプラインのSourceステージで作成した接続を選択
Webhook経由でpushを検知し、自動でパイプラインが開始されます。
Q5. Blue/Greenとローリング、どちらが安全?
一長一短があります:

Blue/Green : ロールバックが瞬時(数秒)。問題発生時の影響を最小化できる。ただし一時的に2倍のリソース費用がかかる。

ローリング : ロールバックは再デプロイ(数分)。コスト効率が良い。サーキットブレーカーで自動ロールバックも可能。

ミッションクリティカルなサービスはBlue/Green、それ以外はローリングがバランスが良いでしょう。
💡 成功のためのベストプラクティス
1. イメージタグにlatestを使わない:
コミットハッシュやビルド番号をタグに使用。どのバージョンがデプロイされたか追跡可能に!

2. ヘルスチェックを正しく実装:
単純な200 OKではなく、DB接続など依存サービスの確認も含めた/healthエンドポイントを実装。

3. healthCheckGracePeriodを十分に取る:
アプリケーションの起動時間 + 余裕を持った値を設定(最低60秒、Spring Bootなどは120秒以上推奨)。

4. デプロイサーキットブレーカーを有効化:
失敗が続いた場合に自動でロールバック。ECSサービス設定で必ず有効化!

5. CloudWatch Logsでコンテナログを収集:
デプロイ失敗時の原因調査に必須。Container Insightsも有効化するとさらに便利。

🎓 まとめ

🚚 フードトラックのリニューアル = ECSローリングデプロイ

CodeシリーズでECS Fargateへの完全自動CI/CDパイプラインを構築!
お客さん(ユーザー)に影響を与えずに 新バージョンをデプロイできます

📝
Source
🔨
Build
📦
ECR
🚀
Deploy
完了!
🎯 重要な設定:
• minimumHealthyPercent: 100% (常にサービス維持)
• maximumPercent: 200% (新タスク追加を許容)
• デプロイサーキットブレーカー: 有効 (失敗時自動ロールバック)
• 出力ファイル: imagedefinitions.json (これが必須!)

これで ダウンタイムゼロ のローリングデプロイを実現!🎉

Created by SSuzuki1063

AWS SAP Learning Resources