kakakakakku blog

Weekly Tech Blog: Keep on Learning!

ecspresso で ECS Blue/Green デプロイを試す

2025年7月19日に nightly ビルドとしてリリースされた ecspresso v2.5.0-nightly-f361aa7 を使って Amazon ECS の新機能「Amazon ECS Blue/Green Deployment(Blue/Green デプロイ)」を試してみた❗️ ecspresso の爆速対応に本当に感謝 \( 'ω')/

$ ~/ecspresso version
ecspresso v2.5.0-nightly-f361aa7

github.com

Amazon ECS Blue/Green Deployment(Blue/Green デプロイ)の基本的な仕組みは以下の記事にまとめてある📝今回もシンプルに ALB (Application Load Balancer) を使った Blue/Green デプロイを試す.

kakakakakku.hatenablog.com

👾 ecs-service-def.json(tfstate プラグイン含む)

今回試した ecs-service-def.json を載せておく.個人的な検証環境だから tfstate プラグインで参照してるリソースとベタ書きになってるリソースがあって微妙なのはお許しを🙏今回は ALB (Application Load Balancer)・ターゲットグループ・リスナールール・セキュリティグループなどを Terraform でデプロイした.

ポイントは deploymentConfigurationstrategyBLUE_GREEN を指定しつつ bakeTimeInMinutes も指定しているところ.あと loadBalancersadvancedConfiguration に Blue/Green デプロイに使う「代替ターゲットグループ」「リスナールール」「IAM Role」を指定した.

{
  "deploymentConfiguration": {
    "strategy": "BLUE_GREEN",
    "deploymentCircuitBreaker": {
      "enable": true,
      "rollback": true
    },
    "maximumPercent": 200,
    "minimumHealthyPercent": 100,
    "bakeTimeInMinutes": 5
  },
  "deploymentController": {
    "type": "ECS"
  },
  "desiredCount": 2,
  "enableECSManagedTags": true,
  "launchType": "FARGATE",
  "loadBalancers": [
    {
      "targetGroupArn": "{{ tfstatef `aws_lb_target_group.blue.arn` }}",
      "containerName": "fargate-app",
      "containerPort": 80,
      "advancedConfiguration": {
          "alternateTargetGroupArn": "{{ tfstatef `aws_lb_target_group.green.arn` }}",
          "productionListenerRule": "arn:aws:elasticloadbalancing:ap-northeast-1:000000000000:listener-rule/app/sandbox-ecspresso/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx",
          "roleArn": "arn:aws:iam::000000000000:role/ecs-elb-role"
      }
    }
  ],
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "securityGroups": [
        "{{ tfstatef `aws_security_group.task.id` }}"
      ],
      "subnets": [
        "subnet-xxxxxxxx",
        "subnet-yyyyyyyy"
      ]
    }
  },
  "platformFamily": "Linux",
  "platformVersion": "LATEST",
  "propagateTags": "SERVICE",
  "schedulingStrategy": "REPLICA"
}

ちなみに loadBalancersadvancedConfiguration.productionListenerRule には aws_lb_listener でデプロイした「デフォルトアクション (default_action)」の ARN を指定している.しかしこの ARN は tfstate から取得できなさそうでコンソールから直接取得した.Terraform AWS Provider のドキュメントを確認してもわからなかった😇

👾 ecs-service-def.json(ecspresso render servicedef コマンド)

ARN を指定するイメージを伝えるために ecspresso render servicedef コマンドの結果も載せておく💡

{
  "availabilityZoneRebalancing": "",
  "deploymentConfiguration": {
    "bakeTimeInMinutes": 5,
    "deploymentCircuitBreaker": {
      "enable": true,
      "rollback": true
    },
    "maximumPercent": 200,
    "minimumHealthyPercent": 100,
    "strategy": "BLUE_GREEN"
  },
  "deploymentController": {
    "type": "ECS"
  },
  "desiredCount": 2,
  "enableECSManagedTags": true,
  "enableExecuteCommand": false,
  "launchType": "FARGATE",
  "loadBalancers": [
    {
      "advancedConfiguration": {
        "alternateTargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:000000000000:targetgroup/sandbox-ecspresso-green/xxxxxxxxxxxxxxxx",
        "productionListenerRule": "arn:aws:elasticloadbalancing:ap-northeast-1:000000000000:listener-rule/app/sandbox-ecspresso/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx",
        "roleArn": "arn:aws:iam::000000000000:role/ecs-elb-role"
      },
      "containerName": "fargate-app",
      "containerPort": 80,
      "targetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:000000000000:targetgroup/sandbox-ecspresso-blue/xxxxxxxxxxxxxxxx"
    }
  ],
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "securityGroups": [
        "sg-xxxxxxxxxxxxxxxxx"
      ],
      "subnets": [
        "subnet-xxxxxxxx",
        "subnet-yyyyyyyy"
      ]
    }
  },
  "pendingCount": 0,
  "platformFamily": "Linux",
  "platformVersion": "LATEST",
  "propagateTags": "SERVICE",
  "runningCount": 0,
  "schedulingStrategy": "REPLICA",
  "serviceName": "sandbox-terraform-ecspresso-service"
}

ecspresso deploy コマンド

ecspresso deploy コマンドでデプロイすると期待した通りに「ターゲットグループ」「代替ターゲットグループ」が設定されていた.前回のブログ記事ではリスナールール(優先度: 1)を使ったけど,今回はリスナールール(デフォルト)を使っている.

Blue デプロイ

Blue 状態のときは ALB (Application Load Balancer) のリスナールールで sandbox-ecspresso-blue 100%sandbox-ecspresso-green 0% という加重ターゲットグループ設定になっていた.

Green デプロイ

Green 状態のときは ALB (Application Load Balancer) のリスナールールで sandbox-ecspresso-green 100%sandbox-ecspresso-blue 0% という加重ターゲットグループ設定になっていた.

まとめ

ecspresso v2.5.0-nightly-f361aa7 を使って Amazon ECS Blue/Green Deployment(Blue/Green デプロイ)」の基本的な流れを試してみた❗️仕事で使う機会が多そうなので,どんどん試していくぞ〜 \( 'ω')/

参考情報

Terraform の aws_lb_listener でデフォルトアクションを設定した後に Blue/Green デプロイを実行すると weight の値が更新されて plan 実行時に差分として出てしまう.今回は lifecycleignore_changes を使うことにした.

resource "aws_lb_listener" "main" {
  load_balancer_arn = aws_lb.main.arn
  port              = "80"
  protocol          = "HTTP"

  default_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
      }
    }
  }

  lifecycle {
    ignore_changes = [default_action]
  }
}

関連ポスト