Terraform-provider-aws: aws_alb_target_group can`t recreate with attached listeners

Created on 13 Jun 2017  ·  33Comments  ·  Source: hashicorp/terraform-provider-aws

_This issue was originally opened by @AlexShuraits as hashicorp/terraform#13076. It was migrated here as part of the provider split. The original body of the issue is below._


Hi there,

I have change the port for aws_alb_target_group, that forces new resource.
Than while trying to delete the target group. I get following error:

Error deleting Target Group: ResourceInUse: Target group 'xxxx' is currently in use by a listener or a rule status code: 400, request id: 747913f1-1213-11e7-916c-3f605d5e091b

So, I assume that it should delete the listener first. That's what I've done manually to resolve the problem.

Terraform Version

Terraform v0.9.1

Affected Resource(s)

  • aws_alb_target_group
  • aws_alb_listener_rule
servicelbv2

Most helpful comment

The combination of moving name to tags and enabling create_before_destroy resolves the issue.

resource "aws_alb_target_group" "test" {
  lifecycle {
    create_before_destroy = true
  }

  port     = "8081"
  protocol = "HTTP"
  vpc_id   = "${var.vpc_id}"


  tags {
    Name = "test"
  }
}

All 33 comments

I am running into this with 0.9.8 as well

@radeksimko This is a tricky issue as well. Would you help us to solve it please? What is the proper way to solve it?

There is two possibility to "resource in use" to prevent destroys as far as I knows.

  1. Default action of a aws_alb_listener
  2. Part of aws_alb_listener_rule

I am considering to add a parameter like "force_destroy". Enabling of it, force to iterate all load balancers, than listeners, than rules. In case a relationship with a rule, rule will be deleted as well. This will solve second problem. I am not sure about the first one but a next candidate target can be set for being default one. This sounds not so bad.

What do you think @radeksimko?

BTW this issue was one of the top issue in the previous trackers. :)

Same in 0.9.11

I added

  lifecycle {
    create_before_destroy = true
  }

to the listener and the target group and was able to successfully do a re-apply with changes. Not sure which one did the trick.

@spanktar It doesn't seem like that would work if your target group name doesn't change, since target group names must be unique. Can you confirm or deny?

@spanktar's solution doesn't work if target group name doesn't change.

@varjoinen you need to use name_prefix with create_before_destroy.

@hoffmannliu-ayla that would be nice if this was fixed https://github.com/terraform-providers/terraform-provider-aws/issues/1301

You can append a random_id|pet to the target group resource ID with a create_before_destroy in the lifecycle policy, and use keepers on the random ID for the things that would end up trying to cycle the resource as a workaround.

@GrantSheehan that worked, thanks. Horrific, but it gets the job done.

For my use case I ended up amending your idea slightly:

resource "random_string" "target_group" {
  length = 8
  special = false
}


resource "aws_lb_target_group" "preview" {
  # Target group names conflict on update, hence the random 
  name     = "my-name-${random_string.target_group.result}"
  ...

  lifecycle {
    create_before_destroy = true
    ignore_changes = ["name"]
  }
}

without keepers to automatically update on any change.

@hraban Terraform doesn't like it on my end
Error is
aws_alb_target_group.blabla-tg: aws_alb_target_group.blabla-tg: diffs didn't match during apply. This is a bug with Terraform and should be reported as a GitHub Issue

ok, keep us updated on your bug reporting progress!

@hraban's solution isn't working for me in 11.1.0

*(i suppose i could go and manually remove the conflicting rules/attachments prior to applying again -- this is not ideal)

-- slamming my face on the desk makes the hurt stop --

The combination of moving name to tags and enabling create_before_destroy resolves the issue.

resource "aws_alb_target_group" "test" {
  lifecycle {
    create_before_destroy = true
  }

  port     = "8081"
  protocol = "HTTP"
  vpc_id   = "${var.vpc_id}"


  tags {
    Name = "test"
  }
}

I am using https://www.terraform.io/docs/providers/random/r/id.html to get around the issue as well.

As we found out, the issue really is that we can not remove the resource before a new target group gets created. We work around that with the lifecycle attribute by setting create_before_destroy to true.
Unfortunately, if the resource name is static we run into the problem, where we have a name collision. This is only an issue, when an attribute is changed that forces a new target group creation. The attributes that enforce that behaviour are well defined in https://github.com/terraform-providers/terraform-provider-aws/blob/master/aws/resource_aws_lb_target_group.go#L48

A solution to the problem can be implemented, abstracted in a module or be resolved inline, I'll post my solution as to how we fixed this inline.

locals {
  LB-name = "${terraform.workspace}-LB"
  LB-protocol = "HTTP"
  LB-vpc-id = "${var.vpc-id}"
  LB-target-type = "ip"
}

resource "random_id" "LB" {
  keepers {
    name = "${local.LB-name}"
    protocol = "${local.LB-protocol}"
    vpc_id ="${local.LB-vpc-id}"
    target_type = "${local.LB-target-type}"
  }
  byte_length = 4
}

resource "aws_lb_target_group" "LB" {
  name = "${local.LB-name}-${random_id.LB.hex}"
  port = 9292
  protocol = "${local.LB-protocol}"
  vpc_id ="${local.LB-vpc-id}"
  target_type = "${local.LB-target-type}"

  lifecycle {
    create_before_destroy = true
  }
}

In my case name, protocol, vpc_id and target_type are potentially changing attributes that if changed force a new target group to be created. I extracted them into local variables and pass them into the random_id resource as keepers - that basically reads among the lines off "if none of the attributes in the keepers map change, the output of the random_id resource remains static". I deliberately did not add port to the keepers map (and local variables), as it doesn't force a new target group to be created, but can be updated in place.

Note, that I use random_id.LB.hex inside the target_groups name, so that if a keepers attribute changes changes, the name of the target group changes, which makes us work around the problem of colliding names.

That said, this is a generic high-level solution to the problem and perhaps it would be better if it can be fixed inside the provider or core. The solution can surely be abstracted into a module as well.

I experienced this issue recently.

I deleted my listeners in my AWS console . and then ran a terrafrom plan / apply and it worked.

Using ${substr(uuid(),0, 3)} worked for me

resource "aws_lb_target_group" "preview" {
  # Target group names conflict on update, hence the random 
  name     = "my-name-${${substr(uuid(),0, 3)}}"
  ...

  lifecycle {
    create_before_destroy = true
    ignore_changes = ["name"]
  }
}

Don't really see a point of cutting a random string of 3 chars, collisions are so a possibility at that granularity.

still a problem on 0.11.13

And still a problem at 0.12.3

I tried the uuid solution, but I need it to not change if other things haven't changed and I can't figure out how.

I found decent success so far using random_integer, similar to the workaround above. I make sure to pull the values through the keepers.

resource "random_integer" "web_target_group_id" {
  min = 1
  max = 999

  keepers = {
    port        = "${local.web_port}"
    protocol    = "HTTP"
    vpc_id      = "${var.vpc_id}"
  }
}
resource "aws_lb_target_group" "web" {
  name                 = "foo-web-${random_integer.web_target_group_id.result}"
  port                 = "${random_integer.web_target_group_id.keepers.port}"
  protocol             = "${random_integer.web_target_group_id.keepers.protocol}"
  vpc_id               = "${random_integer.web_target_group_id.keepers.vpc_id}"

  lifecycle {
    create_before_destroy = true
  }

  # ...etc
}

Seeing this in v0.12.4

Seeing this in v0.12.8

Seeing this in v0.12.9

Seeing this in v0.12.10

This issue is now three years old.

I got this in Terraform v0.12.24 and provider.aws v2.58.0.

same issue with v0.12.24:
Error: Error deleting Target Group: ResourceInUse: Target group 'arn:aws:elasticloadbalancing:XXXXXXXXXXXX' is currently in use by a listener or a rule
status code: 400, request id: XXXXXXXX

Is there a workaround for this? I can't seem to get by it either.

Hi everyone.

As you're seeing, the AWS API doesn't allow a Target Group to be deleted when there's a Listener Rule attached to it. When a port number on the Target Group is changed, it forces the Target Group to be re-created. Unfortunately there is currently no way in Terraform to say "also delete this resource when another resource is deleted", but we have some thoughts about how to address it.

In addition to the name argument, aws_alb_target_group supports name_prefix, and will also generate a random name if neither of those is supplied. As suggested in https://github.com/terraform-providers/terraform-provider-aws/issues/636#issuecomment-397459646, the name can be set in a Name tag instead. Because of how name_prefix works and the length limit on Target Group names, the prefix can only be six characters.

Some of the other solutions using the random provider to add uniqueness to the names will work as well.

Setting lifecycle { create_before_destroy = true } is also needed to break the dependency cycle between the resources.

I'm going to close this issue because this is a limitation of the AWS API and how Terraform handles resources, and it cannot be addressed by the AWS Provider. There are a number of workarounds that can be used to address the issue.

Got past this by renaming and unrenaming the aws_alb_target_group

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

Was this page helpful?
0 / 5 - 0 ratings