Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interpolating name of resource causes recreation when value hasn't changed #3744

Closed
jurajseffer opened this issue Mar 12, 2018 · 10 comments
Closed
Labels
stale Old or inactive issues managed by automation, if no further action taken these will get closed. upstream-terraform Addresses functionality related to the Terraform core binary.

Comments

@jurajseffer
Copy link
Contributor

jurajseffer commented Mar 12, 2018

Terraform Version

Terraform v0.11.1

  • provider.aws v1.11.0

Affected Resource(s)

  • aws_autoscaling_group

Terraform Configuration Files

resource "aws_autoscaling_group" "asg" {
...
name                      = "${var.a}-${var.b}-${var.c}"
lifecycle {
    create_before_destroy = true
  }
...
}

changing to

// var.switch = false

resource "aws_autoscaling_group" "asg" {
...
name                      = "${var.switch ? aws_launch_configuration.lc.name : format("%s-%s-%s", var.a, var.b, var.c)}"
lifecycle {
    create_before_destroy = true
  }
...
}

Expected Behavior

aws_autoscaling_group resource is updated without recreating it.

Actual Behavior

Once we've added the true/false logic with switch = false and aws_launch_configuration.lc needing to be recreated, Terraform thinks the entire ASG needs to be recreated (destroy+create) even though the result of the name interpolation remains the same, i.e. concatenation of a,b and c variables. This seems to happen only once when switching from simple concat to the true/false logic with concat.

@bflad
Copy link
Contributor

bflad commented Mar 12, 2018

Hi @jurajseffer! 👋 Sorry you're running into unexpected behavior here.

Two questions:

  • Does the line in the plan that says (forces new resource) also have "..." => "<computed>"?
  • When you apply this, does it actually recreate the ASG? (Obviously don't test this in production 😄 )

I have a feeling that Terraform core (nothing in the AWS provider) might be confused about computing the attribute with the ternary operator and showing the unexpected difference.

@bflad bflad added the upstream-terraform Addresses functionality related to the Terraform core binary. label Mar 12, 2018
@jurajseffer
Copy link
Contributor Author

Thanks for your reply @bflad.

Plan shows this for the ASG resource when LC needs to be recreated:

name: "a-b-c" => "${var.switch ? aws_launch_configuration.lc.name : format(\"%s-%s-%s\", var.a, var.b, var.c)}" (forces new resource)
id: "a-b-c" => <computed> (forces new resource)
launch_configuration: "***" => "${aws_launch_configuration.lc.id}"

Apply fails because it does try to create the new resource first as per my lifecycle policy:
* aws_autoscaling_group.asg: Error creating AutoScaling Group: AlreadyExists: AutoScalingGroup by this name already exists - A group with the name a-b-c already exists

@jurajseffer
Copy link
Contributor Author

Also once I've applied the above and it failed, TF created new launch configuration and the next plan shows it wants to update launch_configuration property of the ASG as expected, rather than recreating the entire ASG.

@FrenchBen
Copy link

FrenchBen commented Apr 9, 2018

@jurajseffer can you provide a bit more information on the aws_launch_configuration.lc.id switch?
It's usually desirable for the ASG to not be a "computed" value, as the ID is here.
Did you try to push the logic to a local var instead?

// var.switch = false

locals {
  asg_name = "${var.switch ? aws_launch_configuration.lc.name : format("%s-%s-%s", var.a, var.b, var.c)}"
}

resource "aws_autoscaling_group" "asg" {
...
name                      = "${local.asg_name}"
lifecycle {
    create_before_destroy = true
  }
...
}

@jurajseffer
Copy link
Contributor Author

Hey @FrenchBen, the reason for that interpolation of LC id into ASG name is to provide rolling deploys for ASGs with "create before destroy" and Ansible local-exec to provide transition from old into a new ASG. My twist on it with the switch is because some of our existing ASGs cannot be redeployed this way and we wanted to retain backwards compatibility with existing ASGs.

I've not tried locals with it, good shout, it might be a workaround unless Terraform does lazy evaluation? I.e. it would just take the locals statement and evaluate it within the ASG context anyway.

@FrenchBen
Copy link

@jurajseffer I may be missing the bigger picture - My understanding of having aws_launch_configuration.lc.name is that TF crated it. If it's to re-use an existing one, wouldn't it be easier as a var?
Unsure of the lazy evaluation, although I've had better luck setting ternary operations in locals than in resources.

@jurajseffer
Copy link
Contributor Author

The launch configuration is immutable so AWS recreates it every time we change it. We use name_prefix to name it. We then interpolate that LC name into the ASG name so we'd recreate ASG as well to swap all the EC2 instances. My switch deals with the name of the ASG for some ASGs that cannot be recreated so for those we expected update in place, not recreate of the ASG.

@nevins-b
Copy link
Contributor

nevins-b commented Jan 11, 2019

We're seeing this same behavior in terraform v0.11.11.

in our case we have

resource "aws_launch_configuration" "this" {
...
}

resource "aws_autoscaling_group" "this" {
   name =  "${var.rolling_updates ? aws_launch_configuration.this.name : var.name}"
...
}

even with rolling_updates = false we're seeing terraform wanting to recreate our ASG

name:   "production-shared-ecs" => "${var.rolling_updates ? aws_launch_configuration.this.name : var.name}" (forces new resource)

@github-actions
Copy link

github-actions bot commented Jan 1, 2021

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

@github-actions github-actions bot added the stale Old or inactive issues managed by automation, if no further action taken these will get closed. label Jan 1, 2021
@github-actions github-actions bot closed this as completed Feb 1, 2021
@ghost
Copy link

ghost commented Mar 4, 2021

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!

@ghost ghost locked as resolved and limited conversation to collaborators Mar 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
stale Old or inactive issues managed by automation, if no further action taken these will get closed. upstream-terraform Addresses functionality related to the Terraform core binary.
Projects
None yet
Development

No branches or pull requests

4 participants