Building names from a list
The bindings above are used below, exactly like a locals block
zones = ["eu-west-1a", "eu-west-1b"]
prefix = "app"
[for z in zones : "${prefix}-${z}"] Evaluate an HCL expression the way terraform console would, without a working directory, an init, or a provider. Assign values on the lines above and use them below.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Evaluate. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
The bindings above are used below, exactly like a locals block
zones = ["eu-west-1a", "eu-west-1b"]
prefix = "app"
[for z in zones : "${prefix}-${z}"]The commonest expression mistake, and Terraform's own error does not mention strings
a = "hello" b = "world" a + b
Refused by name rather than approximated, because a wrong answer would be believed
timestamp()
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
Terraform has no concatenation operator, so this is an error about types rather than about strings. Almost every other language does it the other way round.
Instead:Use an interpolation: "${a}${b}". For several parts, join("", [a, b]) reads better than a chain.
keys(), values() and a for expression over a map all use sorted key order. The output will not match the input order, which looks like a bug and is a deliberate choice for plan stability.
Instead:If order matters, use a list. If you need both, keep the list and build the map from it.
Both return a different value on every evaluation, so every plan shows a change. Terraform's own documentation warns against them for this reason.
Instead:Use a fixed value, or a resource whose provider generates one once and records it in state, such as random_id.
A calculator gets believed, so this one draws a hard line: it either computes the real answer or says why it will not.
Any line of the form name = expression becomes a binding, and each can use the ones above it, exactly like a locals block. The last line that is not an assignment is the thing evaluated. So var = { name = "web" } then upper(var.name) works, and so does zones = ["a"] then zones[0].
Anything that reads the world or the clock: file, fileexists, templatefile, timestamp, uuid, bcrypt, and the hash functions. A browser has no filesystem, and a value that changes every call is not something you can test. Each one is refused by name with the reason, rather than approximated, because a plausible wrong answer from a calculator is worse than no answer at all.
regex and regexall. Terraform uses Go's RE2, and a browser has JavaScript's engine. They agree on ordinary patterns and disagree on lookahead and backreferences, which RE2 does not support at all. A pattern using either is flagged, because Terraform will reject it even though it evaluates here.
Terraform has no string concatenation operator. "a" + "b" is an error, not "ab", and the message talks about types rather than about concatenation, which is why this catches people who write every other language. Use an interpolation or join().
keys(), values() and a for expression over a map all go by sorted key, not by the order you wrote. That is deliberate in Terraform: it makes plans stable. It also means the output order will not match your input, which reads like a bug the first time.
Every evaluation happens in this tab. That is why it is safe to paste real values into the bindings, including ones out of a state file, to work out what an expression will produce before running a plan.