terraform
terraform copied to clipboard
Defer missing template variable errors and allow `try` to catch them and provide defaults
The try() function within a templatefile() has inconsistent. Try the following:
cat > try.tpl <<< '${ try(some.bad.expression, "fallback") }'
# this fails with an error
terraform console <<< 'templatefile("try.tpl", {})'
# this succeeds and produces "fallback"
terraform console <<< 'templatefile("try.tpl", {some=false})'
From a user perspective I believe both cases should return "fallback".
Hi @pisto, thanks for reporting this!
The issue that you're hitting here is in the templatefile function, not try. templatefile must be supplied a map including keys for all references in the template. These are checked just before render time to provide useful errors. In the example reproduction you give which errors, try is never evaluated.
As a result, the example you've given is similar to using try with an undeclared variable or local, which also errors:
locals {
foo = try(local.bar, "bar")
}
$ terraform plan
Error: Reference to undeclared local value
on main.tf line 2, in locals:
2: foo = try(local.bar, "bar")
A local value with the name "bar" has not been declared.
As a result, I don't think there's a change that we can make here which would be consistent and useful.
I'm not sure exactly what the use case you have here is, but I can guess. As an alternative, could you use try when building the map of values to pass to templatefile? This would allow you to specify fallback values for each key.
I'm updating this issue to an enhancement and retitling, because I believe Terraform is working as designed.
We have a similar use case: We have a shared template file. A template file that is referenced by different tf files. Now we want to add a new variable to the template file. The variable should be used if provided. It will be used by our newer version of the tf files. Due to conflicts, we cannot adapt all old tf files at once. We need to update them step by step. In the meantime, the newer tf files should make use of the new variable template file.
Maybe it is possible to add a new function "defined", that is respected during the check just before render time
cat > try.tpl <<< '${ defined(variablenotexists, "fallback") }'
# this should succeeds and produces "fallback"
terraform console <<< 'templatefile("try.tpl", {})'
# this should succeeds and produces "bla"
terraform console <<< 'templatefile("try.tpl", {variablenotexists=bla})'
Any movement or thoughts on this? I think @jpbuecken hit the nail on the head.
@alisdair , any possibility on considering @jpbuecken approach?
Currently running into this, too. Wondering how this went on for so many years without such a feature.
(I am noting this for the future, as this issue does not have many upvotes despite the interest. Giving the issue description a thumbs-up will help rank it higher when we are sorting for popular issues. Thanks!)
If you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions. Thanks again!
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.