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

Template file used as user data is forcing new resources when no changes have been made #4358

Closed
boboli opened this issue Dec 17, 2015 · 3 comments

Comments

@boboli
Copy link

boboli commented Dec 17, 2015

I was upgrading my terraform version to the latest (0.6.8), when I noticed a deprecation warning during terraform plan about the new template syntax:

Warnings:

  * template_file.userdata-consul: "filename": [DEPRECATED] Use the 'template' attribute instead.

No errors found. Continuing with 1 warning(s).

So then I updated the template declaration from:

resource "template_file" "userdata-consul" {
    filename = "user_data.tpl"
    vars {
        role = "consul-server"
        minion_id_prefix = "consul-server"
    }
}

to:

resource "template_file" "userdata-consul" {
    template = "${file("user_data.tpl")}"
    vars {
        role = "consul-server"
        minion_id_prefix = "consul-server"
    }
}

And this template is to be rendered as user data for a aws_launch_configuration:

resource "aws_launch_configuration" "consul-server" {
    ...
    user_data = "${template_file.userdata-consul.rendered}"
}

Now, on the old terraform version (and indeed on the old syntax), the plan would correctly detect that nothing has changed, as my infrastructure is up-to-date. But with the new syntax, I get:

-/+ aws_launch_configuration.consul-server
    associate_public_ip_address: "false" => "0"
    ebs_block_device.#:          "0" => "<computed>"
    ebs_optimized:               "false" => "<computed>"
    enable_monitoring:           "false" => "0"
    ...
    root_block_device.#:         "0" => "<computed>"
    user_data:                   "c826193966ca3d9c691383fdd06c4b99b7500af5" => "24ecb49fdc16e75e065c13e4233304d4b3646f19" (forces new resource)

-/+ template_file.userdata-consul
    filename:              "user_data.tpl" => ""
    rendered:              "<...old rendered content here...>" => "<computed>"
    template:              "" => "<...unrendered template text here...>" (forces new resource)
    vars.#:                "2" => "2"
    vars.minion_id_prefix: "consul-server" => "consul-server"
    vars.role:             "consul-server" => "consul-server"


Plan: 2 to add, 0 to change, 2 to destroy.

Which sounds like it will destroy the existing infrastructure and recreate it, when I was expecting zero changes. Is there any reason why the new syntax would cause ${template_file.userdata-consul.rendered} to show up as a different hash?

@apparentlymart
Copy link
Contributor

I think this is just a consequence of how the template_file resource is implemented: it thinks it needs to rebuild itself because its filename and template attributes both "force new resource". Normally that's harmless because template_file is a logical resource and so it can be freely recreated.

However, it's interacting poorly here because now your user_data is being updated to a value that is "computed" until the template_file.userdata-consul resource gets remade. Terraform isn't yet smart enough to understand that it could safely re-render that template at plan time, so it wants to wait until apply time to re-render it, after which it'll end up having the same hash as it did before, but that's too late to prevent your launch configuration from being recreated.

I think this workaround will work:

  • First run a plan/apply cycle with your plan command including the extra argument on your command line: -target=template_file.userdata-consul. This will tell Terraform to do the minimal work it needs to update the template file, which should leave your launch configuration untouched.
  • Now run plan again, and since the template_file has now already been recreated it should interpolate the resolved template as expected into the user_data, and there should then be no diff because the "new" template rendering should be the same as the "old" one.

This sort of weird interaction should be addressed by the architectural change we're discussing in #4169, since it will help Terraform understand that a template file is not something for which "create" and "destroy" are meaningful operations, and it will just always render the template at "plan" time, allowing the diff to reflect the final value and, in your case, see that it hasn't actually changed.

@boboli
Copy link
Author

boboli commented Dec 21, 2015

The workaround worked flawlessly; thanks for the update!

@ghost
Copy link

ghost commented Apr 29, 2020

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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants