0.7.9
template_file resource declaration:
data "template_file" "foo" {
template = "${file("${path.module}/foo/environment.json")}"
vars {
name = "myname"
# app1
app1_foo = "${module.app1.foo}"
app1_bar = "${module.app1.bar}"
app1_baz = "${module.app1.baz}"
# app2
app2_foo = "${coalesce(module.app2.foo, module.app1.foo)}"
app2_bar = "${coalesce(module.app2.bar, module.app1.bar)}"
app2_baz = "${coalesce(module.app2.baz, module.app1.baz)}"
}
}
template_file file (/path/foo/environment.json):
{
"template_file_name": "${name}",
"app1_foo": "${app1_foo}",
"app1_bar": "${app1_bar}",
"app1_baz": "${app1_baz}",
"app2_foo": "${app2_foo}",
"app2_bar": "${app2_bar}",
"app2_baz": "${app2_baz}"
}
https://gist.github.com/jcderose/ded36006a6368346b32ad9ea77926b74
n/a
The template file should be populated with the interpolated values.
I get the now-infamous error message:
module.site.data.template_file.foo: Refreshing state...
Error applying plan:
1 error(s) occurred:
* data.template_file.foo: failed to render : 2:15: unknown variable accessed: name
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
terraform apply (terraform plan doesn't catch the error)I know this may be fixed with the upcoming 0.8 release (given the PR references I found below), but the linked issues and use cases don't quite seem to match my own.
And if nothing else, I'd love a temporary workaround.
@apparentlymart, you've chimed in on most of the threads surrounding this issue. Does a temporary workaround exist?
I'm unable to reproduce this locally, but I have it feeling it may have to do with those modules, or it may already be fixed. @jcderose can you try with 0.7.11 with the -Xnew-apply flag?
That didn't resolve the issue. Here's my debug output, if it helps: https://gist.github.com/jcderose/d352206735196050fdd16cc852e24dfb
To clarify our use case: the app1 module is always called/run, but the app2 module may or may not be called, depending on the environment. So in cases where the app2 module is not called (and thus, the module.app2.* output variables don't exist), I want the app2_* variables (passed into the template_file resource) to default to the corresponding module.app1_* values instead.
Also to clarify, this code worked before I added the coalesce() functions to the template_file vars block. So I think the error has to do with the coalesce() functions being passed into the template.
Two interesting notes:
First, I tried replacing the coalesce() functions with other interpolation functions, to see if the issue is with the coalesce() function itself, but still received the error message.
Second, I re-ordered the variables in the template_file file (/path/foo/environment.json) to:
{
"app1_foo": "${app1_foo}",
"template_file_name": "${name}",
"app1_bar": "${app1_bar}",
"app1_baz": "${app1_baz}",
"app2_foo": "${app2_foo}",
"app2_bar": "${app2_bar}",
"app2_baz": "${app2_baz}"
}
And now the error message complains about the app1_foo variable instead of the name variable:
module.site.data.template_file.foo: Refreshing state...
Error applying plan:
1 error(s) occurred:
* data.template_file.foo: failed to render : 2:22: unknown variable accessed: app1_foo
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
In troubleshooting this issue, I noticed the docs for the template_file resource say the vars block only supports primitives - so I assume I can't use the coalesce() function within the template_file vars block?
I've tried refactoring the coalesce() function to a separate null_data_source resource (and then passing the result to the template_file vars block) via suggestions in https://github.com/hashicorp/terraform/issues/4084 but haven't been able to get that to work either.
Okay, I resolved my issue: the output variable module.app2.foo references a resource that doesn't exist. Therefore, Terraform errors out anywhere module.app2.foo is referenced.
In my app2 module, I changed the output variable from:
output "foo" {
value = "${aws_route53_record.db_master.fqdn}"
}
to:
output "foo" {
value = "${join(",", aws_route53_record.db_master.*.fqdn)}"
}
This creates my intended effect of assigning an empty string to the output variable module.app2.foo if the aws_route53_record.db_master resource doesn't exist. Then in my template_file resource declaration I wrote:
data "template_file" "foo" {
template = "${file("${path.module}/foo/environment.json")}"
vars {
...
app2_foo = "${coalesce(element(split(",", module.app2.foo), 0), module.app1.foo)}"
}
}
This compares the sometimes-empty string of module.app1.db_fqdn against the non-empty string of module.app0.db_fqdn and assigns whichever first value is non-empty.
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.
Most helpful comment
Okay, I resolved my issue: the output variable
module.app2.fooreferences a resource that doesn't exist. Therefore, Terraform errors out anywheremodule.app2.foois referenced.In my app2 module, I changed the output variable from:
to:
This creates my intended effect of assigning an empty string to the output variable
module.app2.fooif theaws_route53_record.db_masterresource doesn't exist. Then in my template_file resource declaration I wrote:This compares the sometimes-empty string of module.app1.db_fqdn against the non-empty string of module.app0.db_fqdn and assigns whichever first value is non-empty.