2020-11-13 03:01:48 +01:00
|
|
|
|
---
|
|
|
|
|
layout: "language"
|
|
|
|
|
page_title: "Strings and Templates - Configuration Language"
|
2021-07-09 21:40:05 +02:00
|
|
|
|
description: |-
|
2021-07-14 22:54:26 +02:00
|
|
|
|
String literals and template sequences interpolate values and manipulate text. Learn about both quoted and "heredoc" string syntax.
|
2020-11-13 03:01:48 +01:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# Strings and Templates
|
|
|
|
|
|
|
|
|
|
String literals are the most complex kind of literal expression in
|
|
|
|
|
Terraform, and also the most commonly used.
|
|
|
|
|
|
|
|
|
|
Terraform supports both a quoted syntax and a "heredoc" syntax for strings.
|
|
|
|
|
Both of these syntaxes support template sequences for interpolating values and
|
|
|
|
|
manipulating text.
|
|
|
|
|
|
|
|
|
|
## Quoted Strings
|
|
|
|
|
|
|
|
|
|
A quoted string is a series of characters delimited by straight double-quote
|
|
|
|
|
characters (`"`).
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
"hello"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Escape Sequences
|
|
|
|
|
|
|
|
|
|
In quoted strings, the backslash character serves as an escape
|
|
|
|
|
sequence, with the following characters selecting the escape behavior:
|
|
|
|
|
|
|
|
|
|
| Sequence | Replacement |
|
|
|
|
|
| ------------ | ----------------------------------------------------------------------------- |
|
|
|
|
|
| `\n` | Newline |
|
|
|
|
|
| `\r` | Carriage Return |
|
|
|
|
|
| `\t` | Tab |
|
|
|
|
|
| `\"` | Literal quote (without terminating the string) |
|
|
|
|
|
| `\\` | Literal backslash |
|
|
|
|
|
| `\uNNNN` | Unicode character from the basic multilingual plane (NNNN is four hex digits) |
|
|
|
|
|
| `\UNNNNNNNN` | Unicode character from supplementary planes (NNNNNNNN is eight hex digits) |
|
|
|
|
|
|
|
|
|
|
There are also two special escape sequences that do not use backslashes:
|
|
|
|
|
|
|
|
|
|
| Sequence | Replacement |
|
|
|
|
|
| --- | ---- |
|
|
|
|
|
| `$${` | Literal `${`, without beginning an interpolation sequence. |
|
|
|
|
|
| `%%{` | Literal `%{`, without beginning a template directive sequence. |
|
|
|
|
|
|
|
|
|
|
## Heredoc Strings
|
|
|
|
|
|
|
|
|
|
Terraform also supports a "heredoc" style of string literal inspired by Unix
|
|
|
|
|
shell languages, which allows multi-line strings to be expressed more clearly.
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
<<EOT
|
|
|
|
|
hello
|
|
|
|
|
world
|
|
|
|
|
EOT
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
A heredoc string consists of:
|
|
|
|
|
|
|
|
|
|
- An opening sequence consisting of:
|
|
|
|
|
- A heredoc marker (`<<` or `<<-` — two less-than signs, with an optional hyphen for indented heredocs)
|
|
|
|
|
- A delimiter word of your own choosing
|
|
|
|
|
- A line break
|
|
|
|
|
- The contents of the string, which can span any number of lines
|
|
|
|
|
- The delimiter word you chose, alone on its own line (with indentation allowed for indented heredocs)
|
|
|
|
|
|
|
|
|
|
The `<<` marker followed by any identifier at the end of a line introduces the
|
|
|
|
|
sequence. Terraform then processes the following lines until it finds one that
|
|
|
|
|
consists entirely of the identifier given in the introducer.
|
|
|
|
|
|
|
|
|
|
In the above example, `EOT` is the identifier selected. Any identifier is
|
|
|
|
|
allowed, but conventionally this identifier is in all-uppercase and begins with
|
|
|
|
|
`EO`, meaning "end of". `EOT` in this case stands for "end of text".
|
|
|
|
|
|
2020-12-08 00:25:57 +01:00
|
|
|
|
### Generating JSON or YAML
|
|
|
|
|
|
|
|
|
|
Don't use "heredoc" strings to generate JSON or YAML. Instead, use
|
2021-01-15 23:13:53 +01:00
|
|
|
|
[the `jsonencode` function](/docs/language/functions/jsonencode.html) or
|
|
|
|
|
[the `yamlencode` function](/docs/language/functions/yamlencode.html) so that Terraform
|
2020-12-08 00:25:57 +01:00
|
|
|
|
can be responsible for guaranteeing valid JSON or YAML syntax.
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
example = jsonencode({
|
|
|
|
|
a = 1
|
|
|
|
|
b = "hello"
|
|
|
|
|
})
|
|
|
|
|
```
|
|
|
|
|
|
2020-11-13 03:01:48 +01:00
|
|
|
|
### Indented Heredocs
|
|
|
|
|
|
|
|
|
|
The standard heredoc form (shown above) treats all space characters as literal
|
|
|
|
|
spaces. If you don't want each line to begin with spaces, then each line must be
|
|
|
|
|
flush with the left margin, which can be awkward for expressions in an
|
|
|
|
|
indented block:
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
block {
|
|
|
|
|
value = <<EOT
|
|
|
|
|
hello
|
|
|
|
|
world
|
|
|
|
|
EOT
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
To improve on this, Terraform also accepts an _indented_ heredoc string variant
|
|
|
|
|
that is introduced by the `<<-` sequence:
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
block {
|
|
|
|
|
value = <<-EOT
|
|
|
|
|
hello
|
|
|
|
|
world
|
|
|
|
|
EOT
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
In this case, Terraform analyses the lines in the sequence to find the one
|
|
|
|
|
with the smallest number of leading spaces, and then trims that many spaces
|
|
|
|
|
from the beginning of all of the lines, leading to the following result:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
hello
|
|
|
|
|
world
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Escape Sequences
|
|
|
|
|
|
|
|
|
|
Backslash sequences are not interpreted as escapes in a heredoc string
|
|
|
|
|
expression. Instead, the backslash character is interpreted literally.
|
|
|
|
|
|
|
|
|
|
Heredocs support two special escape sequences that do not use backslashes:
|
|
|
|
|
|
|
|
|
|
| Sequence | Replacement |
|
|
|
|
|
| --- | ---- |
|
|
|
|
|
| `$${` | Literal `${`, without beginning an interpolation sequence. |
|
|
|
|
|
| `%%{` | Literal `%{`, without beginning a template directive sequence. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## String Templates
|
|
|
|
|
|
|
|
|
|
Within quoted and heredoc string expressions, the sequences `${` and `%{` begin
|
|
|
|
|
_template sequences_. Templates let you directly embed expressions into a string
|
|
|
|
|
literal, to dynamically construct strings from other values.
|
|
|
|
|
|
|
|
|
|
### Interpolation
|
|
|
|
|
|
|
|
|
|
A `${ ... }` sequence is an _interpolation,_ which evaluates the expression
|
|
|
|
|
given between the markers, converts the result to a string if necessary, and
|
|
|
|
|
then inserts it into the final string:
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
"Hello, ${var.name}!"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
In the above example, the named object `var.name` is accessed and its value
|
|
|
|
|
inserted into the string, producing a result like "Hello, Juan!".
|
|
|
|
|
|
|
|
|
|
### Directives
|
|
|
|
|
|
|
|
|
|
A `%{ ... }` sequence is a _directive_, which allows for conditional
|
|
|
|
|
results and iteration over collections, similar to conditional
|
|
|
|
|
and `for` expressions.
|
|
|
|
|
|
|
|
|
|
The following directives are supported:
|
|
|
|
|
|
|
|
|
|
* The `%{if <BOOL>}`/`%{else}`/`%{endif}` directive chooses between two templates based
|
|
|
|
|
on the value of a bool expression:
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
"Hello, %{ if var.name != "" }${var.name}%{ else }unnamed%{ endif }!"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The `else` portion may be omitted, in which case the result is an empty
|
|
|
|
|
string if the condition expression returns `false`.
|
|
|
|
|
|
|
|
|
|
* The `%{for <NAME> in <COLLECTION>}` / `%{endfor}` directive iterates over the
|
|
|
|
|
elements of a given collection or structural value and evaluates a given
|
|
|
|
|
template once for each element, concatenating the results together:
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
<<EOT
|
|
|
|
|
%{ for ip in aws_instance.example.*.private_ip }
|
|
|
|
|
server ${ip}
|
|
|
|
|
%{ endfor }
|
|
|
|
|
EOT
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The name given immediately after the `for` keyword is used as a temporary
|
|
|
|
|
variable name which can then be referenced from the nested template.
|
|
|
|
|
|
|
|
|
|
### Whitespace Stripping
|
|
|
|
|
|
|
|
|
|
To allow template directives to be formatted for readability without adding
|
|
|
|
|
unwanted spaces and newlines to the result, all template sequences can include
|
|
|
|
|
optional _strip markers_ (`~`), immediately after the opening characters or
|
|
|
|
|
immediately before the end. When a strip marker is present, the template
|
|
|
|
|
sequence consumes all of the literal whitespace (spaces and newlines) either
|
|
|
|
|
before the sequence (if the marker appears at the beginning) or after (if the
|
|
|
|
|
marker appears at the end):
|
|
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
|
<<EOT
|
|
|
|
|
%{ for ip in aws_instance.example.*.private_ip ~}
|
|
|
|
|
server ${ip}
|
|
|
|
|
%{ endfor ~}
|
|
|
|
|
EOT
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
In the above example, the newline after each of the directives is not included
|
|
|
|
|
in the output, but the newline after the `server ${ip}` sequence is retained,
|
|
|
|
|
causing only one line to be generated for each element:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
server 10.1.16.154
|
|
|
|
|
server 10.1.16.1
|
|
|
|
|
server 10.1.16.34
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When using template directives, we recommend always using the "heredoc" string
|
|
|
|
|
literal form and then formatting the template over multiple lines for
|
|
|
|
|
readability. Quoted string literals should usually include only interpolation
|
|
|
|
|
sequences.
|