Terraform で作成した ALB のターゲットグループの名前を変えたいときに発生したエラーを対処する

Terraform で作成した ALB のターゲットグループの名前を変えたいときに発生したエラーを対処しました
2023.05.19

こんにちは、AWS事業本部の平木です!

今回、Terraform で ALB を作成した際にターゲットグループの名前を変更しようとしたところエラーが発生したためその解決策をブログにしました。

前提

既存の ALB のターゲットグループに対して名前を変更することはできません。
ターゲットグループの名前を変更したい場合は、新規でターゲットグループを作成し、
新しいターゲットグループを ALB のリスナールールへ割り当て直す必要があります。

いきなり結論

lifecycleリソースブロックで create_before_destroytrue に指定することで、新しいターゲットグループが作成され、名前の変更が可能になります。

resource "aws_lb_target_group" "myapp" {
  name                 = "system-env-tg"
  port                 = 80
  protocol             = HTTP
  vpc_id               = "vpc-sampleid"
  deregistration_delay = "10"

+  lifecycle {
+    create_before_destroy = true
+  }
}

経緯

あらかじめデプロイされていたコードはこのような形です。

resource "aws_lb_target_group" "myapp" {
  name                 = "system-env-tg"
  port                 = 80
  protocol             = HTTP
  vpc_id               = "vpc-sampleid"
  deregistration_delay = "10"
}

resource "aws_alb_listener" "myapp-http" {
  load_balancer_arn = aws_lb.mylb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    target_group_arn = aws_lb_target_group.myapp.arn
    type             = "forward"
  }
}

このコードを下記のように修正しました。

resource "aws_lb_target_group" "myapp" {
-  name                 = "system-env-tg"
+  name                 = "env-system-tg"
  port                 = 80
  protocol             = HTTP
  vpc_id               = "vpc-sampleid"
  deregistration_delay = "10"
}

resource "aws_alb_listener" "myapp-http" {
  load_balancer_arn = aws_lb.mylb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    target_group_arn = aws_lb_target_group.myapp.arn
    type             = "forward"
  }
}

このままterraform applyしたところ下記のようなエラーが出力され、先へ進めませんでした。

│ Error: error deleting Target Group: ResourceInUse: Target group 'arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:targetgroup/system-env-tg/xxxxxxxxxxxxxxxx' is currently in use by a listener or a rule
│       status code: 400, request id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

解消法

エラー原因を調査したところ、旧ターゲットグループとALB リスナーとの関連付けが残ってしまっているのが原因でした。

解消法を探したところ、lifecycleブロックで create_before_destroy = trueを指定することで、対象リソースに対して 新しいリソースの作成 → 古いリソースの削除 の順に実行が可能ということが分かりました。

今回の場合、
①新規ターゲットグループの作成
②新規ターゲットグループに EC2 を割り当て
③リスナールールの変更
④旧ターゲットグループの削除
という流れです。

CloudTrail でも確認してみました。

lifecycle ブロックとは

過去のブログにて簡潔に説明されていましたので引用します。

lifecycleとは?
対象となるリソースに記載することで、そのリソースに変更が発生する際の挙動を変更できます。

lifecycleには下記にある3通りの挙動を選択できます。
・ create_before_destroy (bool)
既存のリソースが有った場合に、一旦削除してから作り直すようになります。
・ prevent_destroy (bool)
この値があるリソースを削除しようとするとエラーになります。
・ ignore_changes (list of strings)
実際のリソースとTerraform管理下のリソースの差分があった際、指定したリソースの変更が無視される様になります。

Terraformでテンプレートのアップデート時に特定のリソースの変更を適用しない方法

ちなみに CloudFormation の場合

CloudFormation でも同様にターゲットグループの名前変更のみ実施した場合で検証してみると、

変更セットが問題なく作成され、

DepensOnなどの追加のプロパティを指定することなく更新することができました。

参考

終わりに

今回は、Terraform で作成した ALB のターゲットグループの名前を変えたいときに発生したエラーを対処しました。
一から作っては壊してを繰り返していると気づけないエラーだったため新たな気づきが得られました。
CloudFormation では上手く裏で関連付けのしなおしをしてくれるのも AWS だけで使えるサービスならではなのかなと思いました。

この記事がどなたかの役に立てば嬉しいです。