この記事について

ECS FargateのCI/CDパイプラインをCodeシリーズ(CodePipeline/CodeDeploy/CodeBuild)で実装しています。またこれら一連のAWSリソースはTerraformにより構成管理しています。

あるときterraform applyを実行しようとした際に、ECSサービスのLoadBalancerに変更を検出して、ECSサービスを更新しようとしていることがわかりました。

なにも変更を加えているつもりはなかったのに、変更が検出されるため、何が原因か調べました。その結果、変更が検出された理由に加えて、自分自身がECSのBlue/Greenデプロイの挙動を正しく理解できていないことがわかりました。

どのように挙動を勘違いしていたのか、そして正しい挙動はどうなっているのか、またterraformで変更が検出された原因について、解説していきます。

構成

  • ECS
    • データプレーンはFargate
    • 以下のコンテナがタスク内にて稼働
      • PHP-FPM(Laravelが実行)
      • NGINX
  • CI/CDパイプライン
    • ソース : CodeCommit
    • ビルド : CodeBuild
    • デプロイ : CodeDeploy
  • IaC
    • Terraform

よくある構成だと思います。

何が起きたかのおさらい。

terraform applyを実行した際に以下の差分が検出されました。

# aws_ecs_service.hogehoge will be updated in-place
~ resource "aws_ecs_service" "hogehoge" {
id = "arn:aws:ecs:ap-northeast-1:111122223333:service/hogehoge/fugafuga"
name = "hogehoge"
tags = {}
# (16 unchanged attributes hidden)
- load_balancer {
- container_name = "nginx" -> null
- container_port = 80 -> null
- target_group_arn = "arn:aws:elasticloadbalancing:ap-northeast-1:111122223333:targetgroup/targetgroup-2/6621b4dd8e08cd79" -> null
}
+ load_balancer {
+ container_name = "nginx"
+ container_port = 80
- target_group_arn = "arn:aws:elasticloadbalancing:ap-northeast-1:111122223333:targetgroup/targetgroup-1/6621b4dd8e08cd79" -> null }

ECSサービスに紐づいているターゲットグループに差分が生じているというようです。

では、この差分はなぜ生じているのでしょうか?

Blue/Greenデプロイの挙動を勘違いしていた

私は元々Blue/Greenデプロイの挙動を以下のように認識していました。

勘違いしていた挙動

デプロイ前

移行期間中

デプロイ後

移行期間が完了して、デプロイが完了したらターゲットグループ1が再度新しいECSサービスに紐づき直すと思いました。ただこれが誤りでした。
デプロイ前->移行期間中->デプロイ後の流れをみると、違和感を感じる方もいるかと思います。

正しい挙動は以下の通りでした。

正しい挙動

(デプロイ前と移行期間中は同じです)

デプロイ前

移行期間中

デプロイ後


 

Terraformで差分を検出していた原因

aws_ecs_serviceリソースのload_balancerは一意にならない(デプロイごとに変わる)ため、ignore_changesしてあげる必要がありました。

resource "aws_ecs_service" "hogehoge" {
..省略..

  lifecycle {
    ignore_changes = [task_definition, load_balancer]
  }
}

(タスク定義もCI/CDパイプラインにより更新されるため、ignoreします)

これをしていなかったため、Terraformで差分を検出してしまっていました。

最後に

図に起こしてみると、勘違いしていた挙動には違和感しかありませんでした。でも、整理して図に起こさないと、その違和感すら感じることができませんでした。また、公式ドキュメントにもBlue/Greenデプロイの挙動についての記載が見当たらなかったので、実際にTerraformで差分を検出するまで間違っていることに気が付きませんでした。

最初から全てを正しく理解するというのは難しいので、こういった機会に自分の理解が間違っているものをきちんと正していければいいのかなと。。(他にもいろいろ勘違いしていること多そうですが)