Terraform Interpolation Tester

See what a string with ${ } in it actually produces, and what each piece converts to on the way in. Type conversion is where interpolation goes wrong, and it goes wrong quietly.

Paste below, or drop a file anywhere on this panel

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 Test. Nothing leaves this tab.

Examples

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.

A null in the middle

Renders as nothing, so the result looks valid and is missing a piece

name = "web"
suffix = null

"${name}-${suffix}"

A whole-string interpolation

The quotes are doing nothing but converting the result to a string

count = 3

"${count}"

Joining with +

Arithmetic only, and the error message does not mention strings

a = "hello"
b = "world"

a + b

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Interpolating a value that can be null

    It renders as an empty string, so the result is a valid-looking value that is quietly missing a piece. Nothing errors and nothing warns.

    Instead:Guard it: "${x == null ? "default" : x}", or use coalesce(x, "default").

  2. Writing "${var.thing}" when the whole value is the expression

    The quotes convert the result to a string, so a number or a list stops being one and the type error appears somewhere else entirely.

    Instead:Write var.thing bare.

  3. Putting a shell script with ${ } into a Terraform string

    Terraform tries to resolve every ${ } as an expression and fails on names that belong to the shell.

    Instead:Escape them as ${ }, or move the script to a file and use templatefile with an explicit map.

Interpolation converts, and one of the conversions produces nothing at all

A number and a bool become their text. A list or an object is an error. null becomes an empty string, silently, and that is the one that reaches production.

null renders as nothing

Terraform does not print the word null and does not fail. "${a}-${b}" with b null gives "value-", so a resource ends up named with a trailing dash, a URL loses a path segment, or a tag is set to a prefix. Nothing in the plan looks wrong, because the value is a perfectly valid string.

Wrapping a whole expression in quotes is a conversion

Since 0.12 the expression can be written bare. "${var.count}" is not var.count: it is the string form of it, so a number becomes text and the type error appears wherever the value is used rather than where it was written. If the whole value is one expression, drop the quotes.

A list or an object cannot go in a string

There is no default rendering, so this is an error rather than a surprise. jsonencode() is the answer when you mean to embed the structure, and join() when you mean to flatten a list of strings.

$${ } passes a literal through

Which is how a shell script, a Docker Compose file or anything else using ${ } survives being put in a Terraform string. This is the same escape templates use, and forgetting it is the commonest reason a user_data script fails to render.

Terraform has no + for strings

The operator is arithmetic only, so "a" + "b" is an error whose message talks about types. Almost every other language does the opposite, which is why this is the mistake people make once and remember.

What this cannot see

Whether the value is what you meant, only what the interpolation does to it. Everything runs in your browser and nothing is uploaded, so real values are safe to paste in as bindings.

More terraform tools

Terraform Validator & Formatter Does it parse, and is it formatted? Terraform dynamic Block Generator It is ingress.value, not each.value Terraform check and precondition Generator A failed check does not stop the apply Terraform variables.tf Generator From the var. references you already wrote Terraform Unused Declaration Linter Dead variables, locals and data sources Terraform Atlantis YAML Generator when_modified misses your modules Terraform Function Tester and HCL Console terraform console, in a tab Terraform for Expression Tester Where do the keys collide? Terraform templatefile Tester Render it before you apply it Terraform Resource Count Calculator How many objects, not how many blocks Terraform count to for_each Converter With the moved blocks it needs Terraform moved Block Generator Rename without destroying Terraform state mv Command Builder No plan, no undo Terraform target Flag Builder And why to stop using it Terraform outputs.tf Generator Outputs are not sensitive by default Terraform Remote State Data Source Generator It grants read of the whole state Terraform Provider Block Generator docker is not hashicorp/docker Terraform .gitignore Generator and Checker .terraform* eats the lock file Terraform to OpenTofu Migration Checker The state is the part to watch Terraform tfvars to JSON Converter The JSON file wins Terraform Version Constraint Parser What ~> actually allows Terraform Resource Address Parser Quote it before the shell eats it Terraform cidrsubnet Calculator newbits is added, not the target Terraform Import Block Generator The id is not the name Terraform Lock File Viewer Why CI fails and your laptop does not Terraform Variables Checker A missing value hangs CI Terraform tfvars to Env Vars Converter Lists and maps have to be JSON Terraform Deprecated Syntax Checker What a current Terraform rejects Terraform State File Viewer Read it without uploading it Terraform Plan JSON Viewer It is not redacted Terraform HCL to JSON Converter And what the conversion loses Terraform Module Source Validator version only works for the registry Terraform Backend Config Decoder Is state actually locked? Terraform Naming Convention Validator A hyphen makes a resource unreferenceable

Elsewhere on the site