terraform-provider-local icon indicating copy to clipboard operation
terraform-provider-local copied to clipboard

Terraform reports an "inconsistent final plan" if a templatefile changes between plan and apply

Open alexwlchan opened this issue 3 years ago • 6 comments

I've discovered a scenario in which Terraform will report the error

When expanding the plan for local_file.greeting to include new values learned so far during apply, provider "registry.terraform.io/hashicorp/local" produced an invalid new value for .content: was cty.StringVal("Hello {name}!\n"), but now cty.StringVal("Bonjour {name}!\n").

This is a bug in the provider, which should be reported in the provider's own issue tracker.

This is caused when you try to create a local_file that depends on the value read from a second file, and the second file changes between plan and apply. e.g. suppose you had:

resource "local_file" "greeting" {
  content  = file("${path.module}/greeting.txt")
  filename = "out.txt"
}

if the contents of greeting.txt changes between plan and apply.

Terraform Version

$ terraform -v
Terraform v1.0.1
on darwin_amd64
+ provider registry.terraform.io/hashicorp/local v2.1.0

Affected Resource(s)

  • local_file
  • file

Steps to Reproduce

This bash script reliably reproduces the issue on my machine:

#!/bin/bash

set -o xtrace

terraform -version

echo "Hello Lexie!" > greeting.txt

cat > main.tf<< EOF
resource "local_file" "greeting" {
  content  = file("\${path.module}/greeting.txt")
  filename = "out.txt"
}
EOF

terraform init
terraform plan -out=terraform.plan

echo "Bonjour Lexie!" > greeting.txt

terraform apply terraform.plan

Debug Output

Debug and non-debug output: https://gist.github.com/alexwlchan/575770e8f391d474b3f4d5d242387cec

Panic Output

n/a

Expected Behavior

I'd get an error explaining that the resource pointed to by file() has changed, and so Terraform can't apply my change. Or, Terraform would use the original version of the file, as it was at plan time.

Actual Behavior

I get an error telling me it's a provider bug.

Important Factoids

No.

References

This might be related to https://github.com/hashicorp/terraform-provider-local/issues/57, which is a similar error. That ticket is marked "needs investigation", and I'm not sure if they're the same issue.

alexwlchan avatar Jul 06 '21 13:07 alexwlchan

Hello. I am using local_file to generate ansible inventory from template like this:

ansible.hosts

[workers]
%{ for worker in workers ~}
${worker.name} ansible_host=${worker.private_ip} ansible_user=${ssh_user}
%{ endfor ~}

Resource definition

resource "local_file" "ansible_inventory" {
  count = 1

  filename ="${path.cwd}/ansible.hosts"
  content  = templatefile(
    "${path.module}/templates/ansible/ansible.hosts", {
      workers               = var.workers
    })
}

When I resize infrastructure one worker is removed , than I apply and terraform crashes with: log

When expanding the plan for module.provisioner.local_file.ansible_inventory[0]
to include new values learned so far during apply, provider
"registry.terraform.io/-/local" produced an invalid new value for .content:

was cty.StringVal("[workers]\n
shswarm-worker-0-saving-wombat ansible_host=*.*.*.1 ansible_user=centos\n\n
shswarm-gpu-worker-0-superb-sculpin ansible_host=*.*.*.2 ansible_user=centos"),

but now cty.StringVal("[workers]\n
shswarm-worker-0-saving-wombat ansible_host=*.*.*.1 ansible_user=centos")

This is a bug in the provider, which should be reported in the provider's own
issue tracker.

After terraform plan file content is changed because one worker node is removed.

Is there any way to fix that ?

tvildo avatar Aug 31 '21 20:08 tvildo

Is there any update on this? We've updated to the most recent 1.0.X version of terraform and are still encountering this issue.

rightisleft avatar Dec 15 '21 19:12 rightisleft

Any updates or workaround yet anyone has found?

krissell avatar Mar 17 '22 13:03 krissell

This is caused when you try to create a local_file that depends on the value read from a second file, and the second file changes between plan and apply. e.g. suppose you had:

It is intended behavior! You don't want to apply you plan if your infrastructure changed in-between! No difference what kind of resource you are using - aws_anything_very_critical or local_file. Simply run terraform plan again. This issue should be closed

baznikin avatar Sep 14 '23 12:09 baznikin

This is caused when you try to create a local_file that depends on the value read from a second file, and the second file changes between plan and apply. e.g. suppose you had:

It is intended behavior! You don't want to apply you plan if your infrastructure changed in-between! No difference what kind of resource you are using - aws_anything_very_critical or local_file. Simply run terraform plan again. This issue should be closed

That is not very automation friendly as you cannot simply run plan again there, instead there should be an option to ignore the inconsistency within the local_file provider

shubhamsinha-sf avatar Sep 20 '23 12:09 shubhamsinha-sf

This is caused when you try to create a local_file that depends on the value read from a second file, and the second file changes between plan and apply. e.g. suppose you had:

It is intended behavior! You don't want to apply you plan if your infrastructure changed in-between! No difference what kind of resource you are using - aws_anything_very_critical or local_file. Simply run terraform plan again. This issue should be closed

That is not very automation friendly as you cannot simply run plan again there, instead there should be an option to ignore the inconsistency within the local_file provider

Would the changed file happen between the plan and apply be in a different commit? because if its not in git it doesn't exist. (Read: the plan and apply should be done in CI only on the same code.)

tristanmorgan avatar Sep 20 '23 22:09 tristanmorgan