I'm trying to check if a variable exists on a template file using terraform template syntax, but I get error that This object does not have an attribute named "proxy_set_header
.
$ cat nginx.conf.tmpl
%{ for location in jsondecode(locations) }
location ${location.path} {
%{ if location.proxy_set_header }
proxy_set_header ${location.proxy_set_header};
%{ endif }
}
%{ endfor }
I tried with if location.proxy_set_header != ""
and if location.proxy_set_header
without success.
How to check if a variable exists with the String Templates?
If you are using Terraform 0.12.20 or later then you can use the new function can
to concisely write a check like this:
%{ for location in jsondecode(locations) }
location ${location.path} {
%{ if can(location.proxy_set_header) }
proxy_set_header ${location.proxy_set_header};
%{ endif }
}
%{ endfor }
The can
function returns true if the given expression could evaluate without an error.
The documentation does suggest preferring try
in most cases, but in this particular situation your goal is to show nothing at all if that attribute isn't present, and so this equivalent approach with try
is, I think, harder to understand for a future reader:
%{ for location in jsondecode(locations) }
location ${location.path} {
${ try("proxy_set_header ${location.proxy_set_header};", "") }
}
%{ endfor }
As well as being (subjectively) more opaque as to the intent, this ignores the recommendation in the try
docs of using it only with attribute lookup and type conversion expressions. Therefore I think the can
usage above is justified due to its relative clarity, but either way should work.
I would do something like the following, using contains
and keys
%{ for location in jsondecode(locations) }
location ${location.path} {
%{ if contains(keys(location), "proxy_set_header") }
proxy_set_header ${location.proxy_set_header};
%{ endif }
}
%{ endfor }
The parsed JSON essentially becomes a map
which can be checked for key contents.
I tested this with the following code
data "template_file" "init" {
template = file("${path.module}/file.template")
vars = {
locations = <<DOC
[
{
"path": "foo",
"proxy_set_header": "foohdr"
},
{
"path": "bar"
}
]
DOC
}
}
output "answer" {
value = data.template_file.init.rendered
}
and it had the following output
Outputs:
answer =
location foo {
proxy_set_header foohdr;
}
location bar {
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With