メインコンテンツへスキップ
友田 陽大
ECS on Fargate 本番運用
AWS
ECS
Fargate
CI/CD
Blue/Green
CodeDeploy
GitHub Actions
デプロイ

ECS on Fargate CI/CD 完全ガイド:ネイティブBlue/Green・CodeDeploy・GitHub Actions(OIDC)で安全に出荷する

ECS Fargate の3つのデプロイ戦略(ローリング・ECSネイティブBlue/Green・CodeDeploy)を整理し、GitHub Actions OIDC の鍵レスパイプラインを実コードで示す。本番出荷の品質ゲートまで一気通貫。

公開日
読了時間
16分
著者
友田 陽大
シェア

「新しいコンテナを本番に出した直後に障害が起きたとき、どれだけ速く前の版に戻せるか」——デプロイの本質はここです。速さは二の次。壊れたとき即座に戻せるかが先です。

私は経済産業大臣賞を受賞した木材流通SaaSで、API Gateway → NLB → ALB → ECS on Fargate という構成の上に 221本のAPIエンドポイントを本番運用してきました。決済基盤は本番二重課金0件を維持しています。「一人 × 生成AI(Claude Code)」で本番品質を出すには、デプロイパイプラインそのものを壊れにくく・戻しやすい構造にしておくことが不可欠でした。

この記事は、ECS on Fargate の3つのデプロイ方式を整理し、それぞれをいつ・どう使うかを判断できるようにすることを目的にしています。ECS基盤の設計・ネットワーク・セキュリティの基本はピラー記事に譲り、本稿は**「デプロイそのもの」**に集中します。


ECSの3つのデプロイ方式:まず地図を掴む

ECS on Fargate には、サービスの更新方式として3つの選択肢があります。どれを選ぶかでインフラの複雑さとロールバック速度が変わります。

方式デプロイコントローラBlue/Greenロールバック速度必要な追加リソース
ローリング更新ECSなし新版を落として旧版を起動(数十秒〜)なし
ECSネイティブBlue/GreenECSあり(2025年GA)bake時間中はインスタント切替なし(ECS完結)
CodeDeploy Blue/GreenCODEDEPLOYありbake時間中はインスタント切替CodeDeployアプリ・テストリスナー・TG×2

基本的な選び方

  • ローリング更新:シンプルな構成で十分、デプロイの仕組みをシンプルに保ちたい、短い停止リスクが許容できる。
  • ECSネイティブBlue/Green:Blue/Greenが欲しいが追加リソースを増やしたくない。2025年以降の新規構成のデフォルト推奨
  • CodeDeploy Blue/Green:すでにCodeDeploy資産がある、Lambdaフックで複雑な検証をしたい、NLBと組み合わせた既存構成を踏まえる場合。

①ローリング更新の復習:min/max と サーキットブレーカー

ECSの最もシンプルなデプロイはローリング更新です。デプロイコントローラはECS、デプロイ戦略は暗黙のローリングです。動きは2つのパラメータで決まります(公式)。

  • minimumHealthyPercent:デプロイ中に健全でなければならないタスク数の下限(%、切り上げ)。
  • maximumPercent:デプロイ中に起動してよいタスク数の上限(%、切り下げ)。

min 100% / max 200%(ピラー記事の設定)は最も安全側です。desiredCount=2 なら、新版タスク2つを先に立ち上げ(合計4)、健全を確認してから旧版2つを停止します。一時的にコストが倍になりますが、可用性は一切下がりません。

デプロイサーキットブレーカー

新タスクがクラッシュループし続けているのに気付かずトラフィックを流す事故を防ぐのがデプロイサーキットブレーカーです。

resource "aws_ecs_service" "app" {
  # ...
  deployment_circuit_breaker {
    enable   = true
    rollback = true # 失敗を検知したら前リビジョンへ自動ロールバック
  }
  # CloudWatch アラームとの併用も可能(どちらかの条件成立で失敗扱い)
  deployment_controller {
    type = "ECS"
  }
}

rollback = true にすると、新タスクが規定回数ヘルスチェックを通らない場合にデプロイ失敗として自動で前リビジョンへ戻します。CloudWatchアラームとの連動も可能で、両方有効にすると「どちらかの条件が成立した時点」で失敗扱いになります。

イメージダイジェストによる版の一貫性

ECSは既定でタグをイメージダイジェストへ解決し、サービス内の全タスクが同一バイナリで動くことを保証します(versionConsistency)。latestタグを使うと「ビルドし直したらlatestの中身が変わって一部タスクだけ別バージョン」という事故が起きます。CommitSHAをタグに使い、latestに依存しないのが鉄則です。


②ECSネイティブBlue/Green:2025年GA、CodeDeploy不要

2025年7月にGAし、2025年10月にcanary/linear追加でCodeDeployと機能同等になったECSネイティブBlue/Greenが、今後の新規構成での推奨です。CodeDeployを別途管理せずにECSだけで完結します。

AWS released native Blue/Green deployments for Amazon ECS — you can now do blue/green deployments directly from ECS without needing AWS CodeDeploy.(— AWS Blog

仕組み

デプロイコントローラをECSのまま、デプロイ戦略にBLUE_GREENを選ぶことで有効になります。

  1. サービス更新が始まると、greenタスク群を起動する。
  2. green が健全になったらALBのトラフィックをgreenへ切り替える。
  3. bakeTimeInMinutes の間、blue(旧版)とgreen(新版)を両方保持する。この間はクリック一つでblueへ即座に戻せる(インスタントロールバック)。
  4. bake時間が切れたらblueタスクを削除する。

6つのデプロイライフサイクルフック

ECSネイティブBlue/Greenでは、Lambdaを差し込める6つのライフサイクルフックが用意されています。

フックタイミング
PRE_SCALE_UPgreenタスクのスケールアップ前
POST_SCALE_UPgreenタスクのスケールアップ後(起動確認)
TEST_TRAFFIC_SHIFTテストトラフィックをgreenへ向ける前
POST_TEST_TRAFFIC_SHIFTテストトラフィック切り替え後(スモークテスト)
PRODUCTION_TRAFFIC_SHIFT本番トラフィックをgreenへ向ける前
POST_PRODUCTION_TRAFFIC_SHIFT本番トラフィック切り替え後(本番確認)

フックのLambdaは検証結果をECSに返す。失敗した場合はその時点でデプロイが中断され、blueへ戻ります。

トラフィックシフトの種類

種類挙動
ALL_AT_ONCE一括でgreenへ切り替え(最速、リスク集中)
CANARY最初に指定%をgreenへ、待機後に残りを切り替え
LINEAR一定%ずつ段階的にgreenへシフト

Terraform設定例

resource "aws_ecs_service" "app" {
  name            = "web-api"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = 2
  launch_type     = "FARGATE"

  deployment_controller {
    type = "ECS" # ECSネイティブBlue/Greenはコントローラ "ECS" のまま
  }

  deployment_configuration {
    strategy {
      type = "BLUE_GREEN"
      bake_time_in_minutes = 10 # 切り替え後10分間、旧版を保持してインスタントロールバックを維持
    }
    # トラフィックシフト方式(CANARY例)
    deployment_circuit_breaker {
      enable   = true
      rollback = true
    }
  }

  # ライフサイクルフック(任意)
  # hooks を指定することで Lambdaによる各段階での検証が可能

  network_configuration {
    subnets          = var.private_subnet_ids
    security_groups  = [aws_security_group.task.id]
    assign_public_ip = false
  }
  load_balancer {
    target_group_arn = aws_lb_target_group.app.arn
    container_name   = "app"
    container_port   = 8080
  }
}

注意:ECSネイティブBlue/Greenは比較的新しい機能(2025年GA)のため、Terraformプロバイダのバージョンによっては deployment_configuration ブロックの strategy サブブロックがまだサポートされていない場合があります。その場合はAWS CLIまたはコンソールで設定し、TerraformでIgnoreする過渡的対応が必要です。AWS CLIでの設定は後述します。

AWS CLI でのECSネイティブBlue/Green有効化

Terraformプロバイダが追いついていない場合、create-service または update-service で直接設定します。

aws ecs update-service \
  --cluster prod \
  --service web-api \
  --deployment-configuration '{
    "strategy": {
      "type": "BLUE_GREEN",
      "bakeTimeInMinutes": 10
    },
    "deploymentCircuitBreaker": {
      "enable": true,
      "rollback": true
    }
  }' \
  --region ap-northeast-1

③CodeDeploy Blue/Green:既存資産・高度検証のとき

ECSネイティブBlue/Greenで事足りる場合はCodeDeployを追加する理由はありません。ただし次のケースではCodeDeployが適しています。

  • 既存のCodeDeploy資産(他のサービスや承認フローがある)と統一したい。
  • Lambdaフックで高度な検証(外部APIとの統合テスト、DBマイグレーション確認、Chaos Engineeringシナリオ)をきめ細かく差し込みたい。
  • NLB構成で既存のターゲットグループ切り替え設定がある(ただしNLBの場合はAllAtOnceのみ)。

必要なリソース

CodeDeployによるECS Blue/Greenには以下が必要です(公式)。

  1. ALB(必須。NLBも可だがトラフィックシフト制限あり)
  2. 本番リスナー(ポート443等)と テストリスナー(オプションだが推奨:ポート8080等)、同一ALBに属す
  3. ターゲットグループ×2(blue用・green用)
  4. CodeDeployアプリ(コンピュートプラットフォームECS)とデプロイグループ
  5. AppSpec(タスク定義ARN・コンテナ名・ポート・フックのLambda ARN)
  6. ecsCodeDeployRole(CodeDeployがECSとLBを操作するためのIAMロール)

AppSpec例

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-northeast-1:111122223333:task-definition/web-api:42"
        LoadBalancerInfo:
          ContainerName: "app"
          ContainerPort: 8080
        PlatformVersion: "LATEST"
        NetworkConfiguration:
          AwsvpcConfiguration:
            Subnets:
              - "subnet-0abc123def456"
              - "subnet-0def789abc123"
            SecurityGroups:
              - "sg-0abcdef1234567890"
            AssignPublicIp: "DISABLED"
Hooks:
  - BeforeAllowTestTraffic: "arn:aws:lambda:ap-northeast-1:111122223333:function:pre-deploy-validation"
  - AfterAllowTestTraffic: "arn:aws:lambda:ap-northeast-1:111122223333:function:smoke-test"
  - BeforeAllowTraffic: "arn:aws:lambda:ap-northeast-1:111122223333:function:final-gate"
  - AfterAllowTraffic: "arn:aws:lambda:ap-northeast-1:111122223333:function:post-deploy-check"

事前定義デプロイ設定

設定名挙動
CodeDeployDefault.ECSAllAtOnce一括切り替え(ALB・NLBどちらも利用可)
CodeDeployDefault.ECSLinear10PercentEvery1Minutes1分ごとに10%ずつシフト(10分で完了)
CodeDeployDefault.ECSLinear10PercentEvery3Minutes3分ごとに10%ずつシフト(30分で完了)
CodeDeployDefault.ECSCanary10Percent5Minutes最初に10%を5分確認し、残りを一括
CodeDeployDefault.ECSCanary10Percent15Minutes最初に10%を15分確認し、残りを一括

NLBの制限:NLBと組み合わせた場合はトラフィックシフトが ECSAllAtOnce のみに制限されます。

Terraformでの CodeDeploy 設定

# ECSサービスのデプロイコントローラを CODEDEPLOY に設定
resource "aws_ecs_service" "app" {
  name            = "web-api"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = 2
  launch_type     = "FARGATE"

  deployment_controller {
    type = "CODEDEPLOY"
  }

  # CodeDeploy管理下では load_balancer は2つのTGを参照
  load_balancer {
    target_group_arn = aws_lb_target_group.blue.arn
    container_name   = "app"
    container_port   = 8080
  }

  network_configuration {
    subnets          = var.private_subnet_ids
    security_groups  = [aws_security_group.task.id]
    assign_public_ip = false
  }

  # CodeDeployがTGを入れ替えるため、TFのplan差分を無視する
  lifecycle {
    ignore_changes = [task_definition, load_balancer]
  }
}

# IAMロール:CodeDeployがECSとLBを操作するための権限
resource "aws_iam_role" "ecs_codedeploy" {
  name               = "ecsCodeDeployRole"
  assume_role_policy = data.aws_iam_policy_document.codedeploy_assume.json
}

resource "aws_iam_role_policy_attachment" "ecs_codedeploy" {
  role       = aws_iam_role.ecs_codedeploy.name
  policy_arn = "arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS"
}

# CodeDeployアプリ・デプロイグループ
resource "aws_codedeploy_app" "ecs" {
  compute_platform = "ECS"
  name             = "web-api"
}

resource "aws_codedeploy_deployment_group" "ecs" {
  app_name               = aws_codedeploy_app.ecs.name
  deployment_group_name  = "prod"
  service_role_arn       = aws_iam_role.ecs_codedeploy.arn
  deployment_config_name = "CodeDeployDefault.ECSCanary10Percent5Minutes"

  ecs_service {
    cluster_name = aws_ecs_cluster.main.name
    service_name = aws_ecs_service.app.name
  }

  load_balancer_info {
    target_group_pair_info {
      prod_traffic_route {
        listener_arns = [aws_lb_listener.https.arn]
      }
      test_traffic_route {
        listener_arns = [aws_lb_listener.test.arn]
      }
      target_group {
        name = aws_lb_target_group.blue.name
      }
      target_group {
        name = aws_lb_target_group.green.name
      }
    }
  }

  auto_rollback_configuration {
    enabled = true
    events  = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
  }

  blue_green_deployment_config {
    deployment_ready_option {
      action_on_timeout = "CONTINUE_DEPLOYMENT"
    }
    terminate_blue_instances_on_deployment_success {
      action                           = "TERMINATE"
      termination_wait_time_in_minutes = 5 # bake時間。この間はblueが残りロールバック可能
    }
  }
}

iam:PassRoleが必要:GitHubActionsやCI/CDのIAMロールには、ecsCodeDeployRolePassRoleする権限も付与してください。


④GitHub Actions(OIDC)パイプライン:鍵レスで安全に

デプロイパイプラインに長期アクセスキーを置くのは2026年のアンチパターンです。GitHub Actions OIDCによる鍵レスCI/CDを使えば、IAMロールへの一時クレデンシャル取得で全て完結します。

パイプライン全体像

git push → GitHub Actions トリガー
  → OIDC で AWS 一時クレデンシャル取得
  → 品質ゲート(型チェック・テスト・脆弱性スキャン)
  → ECR へ CommitSHA タグで push
  → タスク定義の image を新タグに差し替え(新リビジョン登録)
  → ECS サービスへデプロイ(ローリングまたは Blue/Green)

完全な workflow.yml

name: Deploy to ECS Fargate

on:
  push:
    branches:
      - main

permissions:
  id-token: write   # OIDC トークン取得に必要
  contents: read

env:
  AWS_REGION: ap-northeast-1
  ECR_REPOSITORY: web-api
  ECS_CLUSTER: prod
  ECS_SERVICE: web-api
  CONTAINER_NAME: app
  TASK_DEFINITION_FAMILY: web-api

jobs:
  quality-gate:
    name: Quality Gate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Type check
        run: npm run type-check

      - name: Unit tests
        run: npm test -- --run

      - name: Build
        run: npm run build

  deploy:
    name: Build & Deploy
    runs-on: ubuntu-latest
    needs: quality-gate  # 品質ゲートが通ってからデプロイ
    environment: production

    steps:
      - uses: actions/checkout@v4

      # ─── OIDC で AWS に認証(長期キー不要)───
      - name: Configure AWS credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-deploy
          aws-region: ${{ env.AWS_REGION }}
          # role-session-name でどのジョブが認証したか CloudTrail に残る
          role-session-name: github-${{ github.sha }}

      # ─── ECR へ push ───
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build, tag, and push image to ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          IMAGE_TAG: ${{ github.sha }}  # CommitSHA で版を固定(latest 非依存)
        run: |
          docker build \
            --platform linux/arm64 \
            --build-arg BUILD_SHA=$IMAGE_TAG \
            -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
            -t $ECR_REGISTRY/$ECR_REPOSITORY:latest \
            .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          # latest も更新(human確認用。ECSはSHAタグを使う)
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

      # ─── ECR イメージスキャン結果を確認(HIGH/CRITICALがあれば失敗) ───
      - name: Wait for ECR scan and check results
        env:
          IMAGE_TAG: ${{ github.sha }}
        run: |
          aws ecr wait image-scan-complete \
            --repository-name $ECR_REPOSITORY \
            --image-id imageTag=$IMAGE_TAG \
            --region $AWS_REGION || true
          FINDINGS=$(aws ecr describe-image-scan-findings \
            --repository-name $ECR_REPOSITORY \
            --image-id imageTag=$IMAGE_TAG \
            --query 'imageScanFindings.findingSeverityCounts' \
            --output json 2>/dev/null || echo '{}')
          HIGH=$(echo $FINDINGS | jq '.HIGH // 0')
          CRITICAL=$(echo $FINDINGS | jq '.CRITICAL // 0')
          echo "HIGH=$HIGH CRITICAL=$CRITICAL"
          if [ "$HIGH" -gt 0 ] || [ "$CRITICAL" -gt 0 ]; then
            echo "::error::Image has HIGH or CRITICAL vulnerabilities. Blocking deploy."
            exit 1
          fi

      # ─── タスク定義の image を新タグへ差し替え ───
      - name: Download current task definition
        run: |
          aws ecs describe-task-definition \
            --task-definition $TASK_DEFINITION_FAMILY \
            --query taskDefinition \
            > task-definition.json

      - name: Render new task definition with updated image
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.CONTAINER_NAME }}
          image: ${{ steps.build-image.outputs.image }}

      # ─── ECS へデプロイ(ローリング or ECSネイティブBlue/Green) ───
      - name: Deploy to ECS
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          wait-for-service-stability: true  # デプロイが安定するまで待機(失敗したらCI失敗)

      - name: Notify deployment result
        if: always()
        env:
          STATUS: ${{ job.status }}
          SHA: ${{ github.sha }}
        run: |
          echo "Deploy status: $STATUS | SHA: $SHA"
          # Slack通知などはここで実装

CodeDeploy Blue/Green を使う場合の差分

aws-actions/amazon-ecs-deploy-task-definition は CodeDeploy にも対応しています。codedeploy-appspec オプションでAppSpecを渡すと、CodeDeployのデプロイを開始して完了を待機します。

      - name: Deploy via CodeDeploy Blue/Green
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          wait-for-service-stability: true
          codedeploy-appspec: appspec.yaml
          codedeploy-application: web-api
          codedeploy-deployment-group: prod

OIDCのIAMロール設定(参考)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::111122223333:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
        }
      }
    }
  ]
}

このロールに付与するポリシーには最小限の権限(ECRへのpush・ecs:RegisterTaskDefinitionecs:UpdateServiceiam:PassRole(タスク実行ロール用))を絞り込むのが原則です。詳細はGitHub Actions OIDCガイドを参照してください。


⑤デプロイ前品質ゲートとコンテナ側の準備

デプロイ方式をどれだけ洗練させても、コンテナそのものが壊れていれば何も意味がない。サーキットブレーカーやBlue/Greenは「デプロイを中断して戻す」仕組みであり、「正常なイメージを届ける」仕組みではありません。

出荷前品質ゲートの層

レイヤ内容タイミング
型チェックTypeScript tsc --noEmit / Pythonなら mypyPR + main push
ユニットテストビジネスロジック・バリデーションPR + main push
コンテナビルドdocker build 成功を確認main push
脆弱性スキャンECR Enhanced Scanning / Trivypush後、デプロイ前
インテグレーションテストステージング環境での疎通確認(任意)main push

グレースフルシャットダウンとの連携

デプロイ中にECSはタスクを停止します。停止の流れはこうです。

  1. タスクをALBターゲットグループから登録解除deregistration_delayの間、処理中リクエストを保護)
  2. コンテナに SIGTERM を送る
  3. stopTimeout(既定30秒・最大120秒)の間、終了を待つ
  4. 終わらなければ SIGKILL で強制終了(データ損失リスク)

Blue/Greenデプロイでも、旧版(blue)タスクを削除する際には同じSIGTERMシーケンスが走ります。bake時間の終了後にblueを落とすタイミングでも、SIGTERMを正しく処理できていなければデータ損失が起きます。

ヘルスチェックとの連携で特に重要なのが startPeriod です。コンテナ起動直後の初期化中(DBコネクション確立・キャッシュウォームアップ)にヘルスチェックを失敗させないよう、猶予時間を設定しておきます。

{
  "healthCheck": {
    "command": ["CMD-SHELL", "wget -q -O - http://localhost:8080/healthz || exit 1"],
    "interval": 15,
    "timeout": 5,
    "retries": 3,
    "startPeriod": 30
  },
  "stopTimeout": 60
}

グレースフルシャットダウンの実装詳細(SIGTERMハンドラのNode.jsコード等)はピラー記事に記載しています。本番でのトラブルシュートはECSトラブルシューティング記事が役に立ちます。

ヘルスチェックの二層構造

ECSには2つのヘルスチェックレイヤが存在し、両方が連動します。

  • コンテナヘルスチェック(タスク定義のhealthCheck):コンテナが落ちているかどうかをECSが判断。失敗が続くとECSがタスクを置換する。
  • ALBターゲットヘルスチェック(ターゲットグループのhealth_check):ALBが「このIPへリクエストを送っていいか」を判断。失敗するとALBがタスクをターゲットから外す。

Blue/Greenデプロイ時、greenタスクが「ALBターゲットヘルスチェックをパス」して初めて本番トラフィックが移ります。ステージングや社内テスト用のリスナーをテストリスナーとして使うと、本番に流す前に追加の疎通確認ができます。


まとめ:壊れたとき即座に戻せる状態を作る

ECS on Fargate のデプロイ戦略を3方式で整理しました。

方式推奨場面追加リソース
ローリング + サーキットブレーカーシンプルな構成、短時間停止許容なし
ECSネイティブBlue/Green2025年以降の新規構成の第一選択なし
CodeDeploy Blue/Green既存CodeDeploy資産、高度なLambdaフック検証TG×2・テストリスナー・CodeDeploy設定

どの方式を選んでも、「安全に出荷する」ための本質は変わりません

  1. 品質ゲートをCIで固める(型・テスト・スキャン)
  2. CommitSHAタグでイメージの版を固定するlatest依存をなくす)
  3. OIDC鍵レスで認証し、長期アクセスキーを一切置かない
  4. SIGTERMを正しく処理して、デプロイ・スケールイン・中断のたびに綺麗に終わる
  5. 自動ロールバックを有効にする(サーキットブレーカー or Blue/Greenのbake時間)

私はこの型で、API Gateway → NLB → ALB → ECS on Fargate 上の221エンドポイントを本番運用し、決済基盤の二重課金0件を維持してきました。詳しくは木材流通SaaSの事例をご覧ください。

Fargateの計算基盤選定(ECS vs Lambda vs App Runner)は比較記事を、IaCのstate管理・モジュール設計はTerraform記事を、デプロイ後の可観測性はOpenTelemetry × ECSをあわせて参照してください。

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事で解説した技術の適用事例

経済産業大臣賞受賞 | 木材流通業界のDXを実現したB2BサブスクリプションSaaS

ケーススタディを見る