ECSサービスのデプロイ戦略をブルー/グリーンに変更する

ECSサービスのデプロイ戦略をブルー/グリーンに変更する

ECSのデプロイ戦略をブルー/グリーンデプロイに変更する方法をまとめます。
2026.03.02

スターバックスデジタルテクノロジー部のserinaです。

ECSのデプロイ戦略をローリングアップデートから、ブルー/グリーンデプロイに変更する方法をまとめます。

ECSのブルー/グリーンデプロイについて

2025年7月のアップデートで、ECSのデプロイ戦略にブルー/グリーンデプロイを選択できるようになりました。

参考: Amazon ECS の新しい組み込みブルー/グリーンデプロイを使用して、安全なソフトウェアリリースを加速

ブルー/グリーンデプロイの仕組み(イメージ)

  • ブルー:現在動いている本番環境
  • グリーン:新しくリリースする環境

を同時に用意します。

リリースの流れ

  1. 現在は「ブルー(現行環境)」が稼働中
  2. 裏側で「グリーン(新バージョン)」を起動
  3. 問題がないか確認
  4. 問題なければ利用者のアクセスをグリーンへ切り替え
  5. 一定時間(bake_time)監視
  6. 問題なければ古いブルー環境を停止

もし bake_time 中に問題が見つかった場合は、マネジメントコンソールから「Roll back」を選択することで即座に元のブルー環境へ戻すことができます。

Roll Back

参考: Amazon ECS ブルー/グリーンサービスのデプロイワークフロー - AWSドキュメント

必要な変更

  • デプロイ戦略をブルー/グリーンに設定する
  • ブルー用・グリーン用のターゲットグループをそれぞれ作成する
  • 既存のターゲットグループは不要になるため削除する
    • すぐ削除することはできないため、段階的に削除します(動作確認に詳細を記載しています)
  • リスナールールに、ブルー用・グリーン用のターゲットグループを付与し、weight(重み)でトラフィックの割合を制御する
  • IAMロールを作成する
    • ブルー/グリーンデプロイでは、ECSがALBのリスナールールの転送先(weight)を自動で切り替えるための権限が必要です

Terraformで実装する場合

ブルー/グリーンデプロイの設定をするためには、Terraformではload_balancer.advanced_configuration の設定が必要になります。
この設定は、6.4.0 で追加されたため、versionが古い場合はこのversion以上に上げる必要があります。

参考: 6.4.0 (July 17, 2025) - terraform-provider-aws / CHANGELOG.md

変更内容

ECSのデプロイ戦略の変更

  • strategyを BLUE_GREEN にします
  • bake_time_in_minutes には、トラフィックをGreenに切り替えた後、問題がないか監視する時間(分)を設定します
    • この時間が経過すると古いBlue環境が自動的に停止されます。ロールバックが必要な場合はこの時間内に行う必要があります
  • load_balancerの設定を追加します
  deployment_configuration {
    strategy = "BLUE_GREEN"

    bake_time_in_minutes = 5
  }

  load_balancer {
    target_group_arn = var.target_group_blue_arn
    container_name   = format("%s-%s-%s", var.project_name, var.environment, "container")
    container_port   = var.container_port

    advanced_configuration {
      alternate_target_group_arn = var.target_group_green_arn
      production_listener_rule   = var.alb_listener_rule_arn
      role_arn                   = aws_iam_role.alb_service_role.arn
    }
  }

ターゲットグループの追加

resource "aws_lb_target_group" "blue" {
  name     = format("%s-%s-%s", var.project_name, var.environment, "tg-blue")
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  target_type = "ip"

  health_check {
    path                = "/status"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 5
    unhealthy_threshold = 2
    matcher             = "200"
  }

  tags = merge(var.tags, {
    Name = format("%s-%s-%s", var.project_name, var.environment, "tg-blue")
  })
}

resource "aws_lb_target_group" "green" {
  name     = format("%s-%s-%s", var.project_name, var.environment, "tg-green")
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  target_type = "ip"

  health_check {
    path                = "/status"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 5
    unhealthy_threshold = 2
    matcher             = "200"
  }

  tags = merge(var.tags, {
    Name = format("%s-%s-%s", var.project_name, var.environment, "tg-green")
  })
}

リスナールールの変更

  • Blue/Green用のターゲットグループを指定します
  • action[0].forwardignore_changes に設定する
    • デプロイ中にECSがALBリスナールールの weight を自動で書き換えるため、次回の terraform apply 時に差分として検出され意図しない変更が発生するのを防ぐために設定します
resource "aws_lb_listener_rule" "production_listener_rule" {
  listener_arn = aws_lb_listener.https.arn
  priority     = 1

  action {
    type = "forward"

    forward {
      target_group {
        arn    = aws_lb_target_group.blue.arn
        weight = 100
      }

      target_group {
        arn    = aws_lb_target_group.green.arn
        weight = 0
      }
    }
  }

  condition {
    # ~~省略~~
  }

  lifecycle {
    ignore_changes = [action[0].forward]
  }
}

ECS サービスロールの追加

data "aws_iam_policy_document" "alb_service_role_assume_policy" {
  statement {
    effect = "Allow"
    actions = [
      "sts:AssumeRole"
    ]
    principals {
      type = "Service"
      identifiers = [
        "ecs.amazonaws.com"
      ]
    }
  }
}

resource "aws_iam_role" "alb_service_role" {
  name               = "${var.project_name}-${var.environment}-ecs-alb-service-role"
  assume_role_policy = data.aws_iam_policy_document.alb_service_role_assume_policy.json
}

resource "aws_iam_role_policy_attachment" "alb_service_role_policy" {
  role       = aws_iam_role.alb_service_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonECSInfrastructureRolePolicyForLoadBalancers"
}

参考: AmazonECSInfrastructureRolePolicyForLoadBalancers - AWS Managed Policy リファレンスガイド

動作確認

すでに起動しているECSサービスに対して、Terraformでデプロイ戦略の変更を行なった場合の挙動です。
ダウンタイムなく、設定変更できることが確認できました。

既存のターゲットグループについては設定変更時はまだ使用されているため、段階的に削除する手順が必要です。

terraform apply実施後の挙動

  • デプロイ戦略が「Blue/Green」に変わります
  • Green用のターゲットグループが設定された新しいタスクが起動します
  • 既存のターゲットグループはまだ使用されているため、この段階では削除できません

タスク進行中

In Progress_1

タスク完了

Completed_1

再度サービス更新した際の挙動

  • Greenが起動した状態なので、新しくBlueのタスクが起動します
  • 既存のターゲットグループはこの段階で使用されなくなるため削除可能となります

タスク進行中

In Progress_2

タスク完了

Completed_2

最後に

思ったよりも簡単に変更することができました!
再作成せずに、スムーズにデプロイ戦略の変更ができることがわかりました。

参考

この記事をシェアする

FacebookHatena blogX

関連記事