website: Break up Expressions page into smaller chunks
This commit converts the previous URL for this content to a landing page, which captures all of the previous in-page anchors and directs readers to the new home for each section.
This commit is contained in:
parent
b06db967b7
commit
a446ecb7b7
|
@ -1,905 +1,123 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Expressions - Configuration Language"
|
||||
page_title: "Expressions Landing Page - Configuration Language"
|
||||
sidebar_current: "docs-config-expressions"
|
||||
description: |-
|
||||
The Terraform language allows the use of expressions to access data exported
|
||||
by resources and to transform and combine that data to produce other values.
|
||||
---
|
||||
|
||||
# Expressions
|
||||
# Expressions Landing Page
|
||||
|
||||
-> **Note:** This page is about Terraform 0.12 and later. For Terraform 0.11 and
|
||||
earlier, see
|
||||
[0.11 Configuration Language: Interpolation Syntax](../configuration-0-11/interpolation.html).
|
||||
To improve navigation, we've split the old Expressions page into several smaller
|
||||
pages.
|
||||
|
||||
_Expressions_ are used to refer to or compute values within a configuration.
|
||||
The simplest expressions are just literal values, like `"hello"` or `5`,
|
||||
but the Terraform language also allows more complex expressions such as
|
||||
references to data exported by resources, arithmetic, conditional evaluation,
|
||||
and a number of built-in functions.
|
||||
<a id="types-and-values"></a>
|
||||
<a id="advanced-type-details"></a>
|
||||
<a id="type-conversion"></a>
|
||||
<a id="literal-expressions"></a>
|
||||
<a id="indices-and-attributes"></a>
|
||||
|
||||
Expressions can be used in a number of places in the Terraform language,
|
||||
but some contexts limit which expression constructs are allowed,
|
||||
such as requiring a literal value of a particular type or forbidding
|
||||
[references to resource attributes](/docs/configuration/expressions.html#references-to-resource-attributes).
|
||||
Each language feature's documentation describes any restrictions it places on expressions.
|
||||
## Types and Values, Literal Expressions, Indices and Attributes
|
||||
|
||||
You can experiment with the behavior of Terraform's expressions from
|
||||
the Terraform expression console, by running
|
||||
[the `terraform console` command](/docs/commands/console.html).
|
||||
Terraform's types are `string`, `number`, `bool`, `list`, `tuple`, `map`,
|
||||
`object`, and `null`.
|
||||
|
||||
The rest of this page describes all of the features of Terraform's
|
||||
expression syntax.
|
||||
This information has moved to
|
||||
[Types and Values](/docs/configuration/expressions/types.html).
|
||||
|
||||
## Types and Values
|
||||
<a id="references-to-named-values"></a>
|
||||
<a id="local-named-values"></a>
|
||||
<a id="named-values-and-dependencies"></a>
|
||||
<a id="references-to-resource-attributes"></a>
|
||||
<a id="local-named-values-1"></a>
|
||||
<a id="values-not-yet-known"></a>
|
||||
|
||||
The result of an expression is a _value_. All values have a _type_, which
|
||||
dictates where that value can be used and what transformations can be
|
||||
applied to it.
|
||||
## References to Named Values (Resource Attributes, Variables, etc.)
|
||||
|
||||
The Terraform language uses the following types for its values:
|
||||
You can refer to certain values by name, like `var.some_variable` or
|
||||
`aws_instance.example.ami`.
|
||||
|
||||
* `string`: a sequence of Unicode characters representing some text, like
|
||||
`"hello"`.
|
||||
* `number`: a numeric value. The `number` type can represent both whole
|
||||
numbers like `15` and fractional values like `6.283185`.
|
||||
* `bool`: either `true` or `false`. `bool` values can be used in conditional
|
||||
logic.
|
||||
* `list` (or `tuple`): a sequence of values, like
|
||||
`["us-west-1a", "us-west-1c"]`. Elements in a list or tuple are identified by
|
||||
consecutive whole numbers, starting with zero.
|
||||
* `map` (or `object`): a group of values identified by named labels, like
|
||||
`{name = "Mabel", age = 52}`.
|
||||
This information has moved to
|
||||
[References to Values](/docs/configuration/expressions/references.html).
|
||||
|
||||
Strings, numbers, and bools are sometimes called _primitive types._ Lists/tuples and maps/objects are sometimes called _complex types,_ _structural types,_ or _collection types._
|
||||
|
||||
Finally, there is one special value that has _no_ type:
|
||||
|
||||
* `null`: a value that represents _absence_ or _omission._ If you set an
|
||||
argument of a resource or module to `null`, Terraform behaves as though you
|
||||
had completely omitted it — it will use the argument's default value if it has
|
||||
one, or raise an error if the argument is mandatory. `null` is most useful in
|
||||
conditional expressions, so you can dynamically omit an argument if a
|
||||
condition isn't met.
|
||||
|
||||
### Advanced Type Details
|
||||
|
||||
In most situations, lists and tuples behave identically, as do maps and objects.
|
||||
Whenever the distinction isn't relevant, the Terraform documentation uses each
|
||||
pair of terms interchangeably (with a historical preference for "list" and
|
||||
"map").
|
||||
|
||||
However, module authors and provider developers should understand the
|
||||
differences between these similar types (and the related `set` type), since they
|
||||
offer different ways to restrict the allowed values for input variables and
|
||||
resource arguments.
|
||||
|
||||
For complete details about these types (and an explanation of why the difference
|
||||
usually doesn't matter), see [Type Constraints](./types.html).
|
||||
|
||||
### Type Conversion
|
||||
|
||||
Expressions are most often used to set values for the arguments of resources and
|
||||
child modules. In these cases, the argument has an expected type and the given
|
||||
expression must produce a value of that type.
|
||||
|
||||
Where possible, Terraform automatically converts values from one type to
|
||||
another in order to produce the expected type. If this isn't possible, Terraform
|
||||
will produce a type mismatch error and you must update the configuration with a
|
||||
more suitable expression.
|
||||
|
||||
Terraform automatically converts number and bool values to strings when needed.
|
||||
It also converts strings to numbers or bools, as long as the string contains a
|
||||
valid representation of a number or bool value.
|
||||
|
||||
* `true` converts to `"true"`, and vice-versa
|
||||
* `false` converts to `"false"`, and vice-versa
|
||||
* `15` converts to `"15"`, and vice-versa
|
||||
|
||||
## Literal Expressions
|
||||
|
||||
A _literal expression_ is an expression that directly represents a particular
|
||||
constant value. Terraform has a literal expression syntax for each of the value
|
||||
types described above:
|
||||
|
||||
* Strings are usually represented by a double-quoted sequence of Unicode
|
||||
characters, `"like this"`. There is also a "heredoc" syntax for more complex
|
||||
strings. String literals are the most complex kind of literal expression in
|
||||
Terraform, and have additional documentation on this page:
|
||||
* See [String Literals](#string-literals) below for information about escape
|
||||
sequences and the heredoc syntax.
|
||||
* See [String Templates](#string-templates) below for information about
|
||||
interpolation and template directives.
|
||||
* Numbers are represented by unquoted sequences of digits with or without a
|
||||
decimal point, like `15` or `6.283185`.
|
||||
* Bools are represented by the unquoted symbols `true` and `false`.
|
||||
* The null value is represented by the unquoted symbol `null`.
|
||||
* Lists/tuples are represented by a pair of square brackets containing a
|
||||
comma-separated sequence of values, like `["a", 15, true]`.
|
||||
|
||||
List literals can be split into multiple lines for readability, but always
|
||||
require a comma between values. A comma after the final value is allowed,
|
||||
but not required. Values in a list can be arbitrary expressions.
|
||||
* Maps/objects are represented by a pair of curly braces containing a series of
|
||||
`<KEY> = <VALUE>` pairs:
|
||||
|
||||
```hcl
|
||||
{
|
||||
name = "John"
|
||||
age = 52
|
||||
}
|
||||
```
|
||||
|
||||
Key/value pairs can be separated by either a comma or a line break. Values
|
||||
can be arbitrary expressions. Keys are strings; they can be left unquoted if
|
||||
they are a valid [identifier](./syntax.html#identifiers), but must be quoted
|
||||
otherwise. You can use a non-literal expression as a key by wrapping it in
|
||||
parentheses, like `(var.business_unit_tag_name) = "SRE"`.
|
||||
|
||||
## Indices and Attributes
|
||||
|
||||
[inpage-index]: #indices-and-attributes
|
||||
|
||||
Elements of list/tuple and map/object values can be accessed using
|
||||
the square-bracket index notation, like `local.list[3]`. The expression within
|
||||
the brackets must be a whole number for list and tuple values or a string
|
||||
for map and object values.
|
||||
|
||||
Map/object attributes with names that are valid identifiers can also be accessed
|
||||
using the dot-separated attribute notation, like `local.object.attrname`.
|
||||
In cases where a map might contain arbitrary user-specified keys, we recommend
|
||||
using only the square-bracket index notation (`local.map["keyname"]`).
|
||||
|
||||
## References to Named Values
|
||||
|
||||
Terraform makes several kinds of named values available. Each of these names is
|
||||
an expression that references the associated value; you can use them as
|
||||
standalone expressions, or combine them with other expressions to compute new
|
||||
values.
|
||||
|
||||
The following named values are available:
|
||||
|
||||
* `<RESOURCE TYPE>.<NAME>` is an object representing a
|
||||
[managed resource](./resources.html) of the given type
|
||||
and name. The attributes of the resource can be accessed using
|
||||
[dot or square bracket notation][inpage-index].
|
||||
|
||||
Any named value that does not match another pattern listed below
|
||||
will be interpreted by Terraform as a reference to a managed resource.
|
||||
|
||||
If the resource has the `count` argument set, the value of this expression
|
||||
is a _list_ of objects representing its instances.
|
||||
|
||||
If the resource has the `for_each` argument set, the value of this expression
|
||||
is a _map_ of objects representing its instances.
|
||||
|
||||
For more information, see
|
||||
[references to resource attributes](#references-to-resource-attributes) below.
|
||||
* `var.<NAME>` is the value of the
|
||||
[input variable](./variables.html) of the given name.
|
||||
* `local.<NAME>` is the value of the
|
||||
[local value](./locals.html) of the given name.
|
||||
* `module.<MODULE NAME>.<OUTPUT NAME>` is the value of the specified
|
||||
[output value](./outputs.html) from a
|
||||
[child module](./modules.html) called by the current module.
|
||||
* `data.<DATA TYPE>.<NAME>` is an object representing a
|
||||
[data resource](./data-sources.html) of the given data
|
||||
source type and name. If the resource has the `count` argument set, the value
|
||||
is a list of objects representing its instances. If the resource has the `for_each`
|
||||
argument set, the value is a map of objects representing its instances.
|
||||
* `path.module` is the filesystem path of the module where the expression
|
||||
is placed.
|
||||
* `path.root` is the filesystem path of the root module of the configuration.
|
||||
* `path.cwd` is the filesystem path of the current working directory. In
|
||||
normal use of Terraform this is the same as `path.root`, but some advanced
|
||||
uses of Terraform run it from a directory other than the root module
|
||||
directory, causing these paths to be different.
|
||||
* `terraform.workspace` is the name of the currently selected
|
||||
[workspace](/docs/state/workspaces.html).
|
||||
|
||||
Although many of these names use dot-separated paths that resemble
|
||||
[attribute notation][inpage-index] for elements of object values, they are not
|
||||
implemented as real objects. This means you must use them exactly as written:
|
||||
you cannot use square-bracket notation to replace the dot-separated paths, and
|
||||
you cannot iterate over the "parent object" of a named entity (for example, you
|
||||
cannot use `aws_instance` in a `for` expression).
|
||||
|
||||
### Local Named Values
|
||||
|
||||
Within the bodies of certain expressions, or in some other specific contexts,
|
||||
there are other named values available beyond the global values listed above.
|
||||
These local names are described in the documentation for the specific contexts
|
||||
where they appear. Some of most common local names are:
|
||||
|
||||
- `count.index`, in resources that use
|
||||
[the `count` meta-argument](./resources.html#count-multiple-resource-instances-by-count).
|
||||
- `each.key` / `each.value`, in resources that use
|
||||
[the `for_each` meta-argument](./resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings).
|
||||
- `self`, in [provisioner](../provisioners/index.html) and
|
||||
[connection](../provisioners/connection.html) blocks.
|
||||
|
||||
-> **Note:** Local names are often referred to as _variables_ or
|
||||
_temporary variables_ in their documentation. These are not [input
|
||||
variables](./variables.html); they are just arbitrary names
|
||||
that temporarily represent a value.
|
||||
|
||||
### Named Values and Dependencies
|
||||
|
||||
Constructs like resources and module calls often use references to named values
|
||||
in their block bodies, and Terraform analyzes these expressions to automatically
|
||||
infer dependencies between objects. For example, an expression in a resource
|
||||
argument that refers to another managed resource creates an implicit dependency
|
||||
between the two resources.
|
||||
|
||||
### References to Resource Attributes
|
||||
|
||||
The most common reference type is a reference to an attribute of a resource
|
||||
which has been declared either with a `resource` or `data` block. Because
|
||||
the contents of such blocks can be quite complicated themselves, expressions
|
||||
referring to these contents can also be complicated.
|
||||
|
||||
Consider the following example resource block:
|
||||
|
||||
```hcl
|
||||
resource "aws_instance" "example" {
|
||||
ami = "ami-abc123"
|
||||
instance_type = "t2.micro"
|
||||
|
||||
ebs_block_device {
|
||||
device_name = "sda2"
|
||||
volume_size = 16
|
||||
}
|
||||
ebs_block_device {
|
||||
device_name = "sda3"
|
||||
volume_size = 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The documentation for [`aws_instance`](/docs/providers/aws/r/instance.html)
|
||||
lists all of the arguments and nested blocks supported for this resource type,
|
||||
and also lists a number of attributes that are _exported_ by this resource
|
||||
type. All of these different resource type schema constructs are available
|
||||
for use in references, as follows:
|
||||
|
||||
* The `ami` argument set in the configuration can be used elsewhere with
|
||||
the reference expression `aws_instance.example.ami`.
|
||||
* The `id` attribute exported by this resource type can be read using the
|
||||
same syntax, giving `aws_instance.example.id`.
|
||||
* The arguments of the `ebs_block_device` nested blocks can be accessed using
|
||||
a [splat expression](#splat-expressions). For example, to obtain a list of
|
||||
all of the `device_name` values, use
|
||||
`aws_instance.example.ebs_block_device[*].device_name`.
|
||||
* The nested blocks in this particular resource type do not have any exported
|
||||
attributes, but if `ebs_block_device` were to have a documented `id`
|
||||
attribute then a list of them could be accessed similarly as
|
||||
`aws_instance.example.ebs_block_device[*].id`.
|
||||
* Sometimes nested blocks are defined as taking a logical key to identify each
|
||||
block, which serves a similar purpose as the resource's own name by providing
|
||||
a convenient way to refer to that single block in expressions. If `aws_instance`
|
||||
had a hypothetical nested block type `device` that accepted such a key, it
|
||||
would look like this in configuration:
|
||||
|
||||
```hcl
|
||||
device "foo" {
|
||||
size = 2
|
||||
}
|
||||
device "bar" {
|
||||
size = 4
|
||||
}
|
||||
```
|
||||
|
||||
Arguments inside blocks with _keys_ can be accessed using index syntax, such
|
||||
as `aws_instance.example.device["foo"].size`.
|
||||
|
||||
To obtain a map of values of a particular argument for _labelled_ nested
|
||||
block types, use a [`for` expression](#for-expressions):
|
||||
`{for k, device in aws_instance.example.device : k => device.size}`.
|
||||
|
||||
When a resource has the
|
||||
[`count`](https://www.terraform.io/docs/configuration/resources.html#count-multiple-resource-instances-by-count)
|
||||
argument set, the resource itself becomes a _list_ of instance objects rather than
|
||||
a single object. In that case, access the attributes of the instances using
|
||||
either [splat expressions](#splat-expressions) or index syntax:
|
||||
|
||||
* `aws_instance.example[*].id` returns a list of all of the ids of each of the
|
||||
instances.
|
||||
* `aws_instance.example[0].id` returns just the id of the first instance.
|
||||
|
||||
When a resource has the
|
||||
[`for_each`](/docs/configuration/resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings)
|
||||
argument set, the resource itself becomes a _map_ of instance objects rather than
|
||||
a single object, and attributes of instances must be specified by key, or can
|
||||
be accessed using a [`for` expression](#for-expressions).
|
||||
|
||||
* `aws_instance.example["a"].id` returns the id of the "a"-keyed resource.
|
||||
* `[for value in aws_instance.example: value.id]` returns a list of all of the ids
|
||||
of each of the instances.
|
||||
|
||||
Note that unlike `count`, splat expressions are _not_ directly applicable to resources managed with `for_each`, as splat expressions are for lists only. You may apply a splat expression to values in a map like so:
|
||||
|
||||
* `values(aws_instance.example)[*].id`
|
||||
|
||||
### Values Not Yet Known
|
||||
|
||||
When Terraform is planning a set of changes that will apply your configuration,
|
||||
some resource attribute values cannot be populated immediately because their
|
||||
values are decided dynamically by the remote system. For example, if a
|
||||
particular remote object type is assigned a generated unique id on creation,
|
||||
Terraform cannot predict the value of this id until the object has been created.
|
||||
|
||||
To allow expressions to still be evaluated during the plan phase, Terraform
|
||||
uses special "unknown value" placeholders for these results. In most cases you
|
||||
don't need to do anything special to deal with these, since the Terraform
|
||||
language automatically handles unknown values during expressions, so that
|
||||
for example adding a known value to an unknown value automatically produces
|
||||
an unknown value as the result.
|
||||
|
||||
However, there are some situations where unknown values _do_ have a significant
|
||||
effect:
|
||||
|
||||
* The `count` meta-argument for resources cannot be unknown, since it must
|
||||
be evaluated during the plan phase to determine how many instances are to
|
||||
be created.
|
||||
|
||||
* If unknown values are used in the configuration of a data resource, that
|
||||
data resource cannot be read during the plan phase and so it will be deferred
|
||||
until the apply phase. In this case, the results of the data resource will
|
||||
_also_ be unknown values.
|
||||
|
||||
* If an unknown value is assigned to an argument inside a `module` block,
|
||||
any references to the corresponding input variable within the child module
|
||||
will use that unknown value.
|
||||
|
||||
* If an unknown value is used in the `value` argument of an output value,
|
||||
any references to that output value in the parent module will use that
|
||||
unknown value.
|
||||
|
||||
* Terraform will attempt to validate that unknown values are of suitable
|
||||
types where possible, but incorrect use of such values may not be detected
|
||||
until the apply phase, causing the apply to fail.
|
||||
|
||||
Unknown values appear in the `terraform plan` output as `(not yet known)`.
|
||||
<a id="arithmetic-operators"></a>
|
||||
<a id="equality-operators"></a>
|
||||
<a id="comparison-operators"></a>
|
||||
<a id="logical-operators"></a>
|
||||
|
||||
## Arithmetic and Logical Operators
|
||||
|
||||
An _operator_ is a type of expression that transforms or combines one or more
|
||||
other expressions. Operators either combine two values in some way to
|
||||
produce a third result value, or transform a single given value to
|
||||
produce a single result.
|
||||
Operators are expressions that transform other expressions, like adding two
|
||||
numbers (`+`) or comparing two values to get a bool (`==`, `>=`, etc.).
|
||||
|
||||
Operators that work on two values place an operator symbol between the two
|
||||
values, similar to mathematical notation: `1 + 2`. Operators that work on
|
||||
only one value place an operator symbol before that value, like
|
||||
`!true`.
|
||||
|
||||
The Terraform language has a set of operators for both arithmetic and logic,
|
||||
which are similar to operators in programming languages such as JavaScript
|
||||
or Ruby.
|
||||
|
||||
When multiple operators are used together in an expression, they are evaluated
|
||||
in the following order of operations:
|
||||
|
||||
1. `!`, `-` (multiplication by `-1`)
|
||||
1. `*`, `/`, `%`
|
||||
1. `+`, `-` (subtraction)
|
||||
1. `>`, `>=`, `<`, `<=`
|
||||
1. `==`, `!=`
|
||||
1. `&&`
|
||||
1. `||`
|
||||
|
||||
Parentheses can be used to override the default order of operations. Without
|
||||
parentheses, higher levels are evaluated first, so `1 + 2 * 3` is interpreted
|
||||
as `1 + (2 * 3)` and _not_ as `(1 + 2) * 3`.
|
||||
|
||||
The different operators can be gathered into a few different groups with
|
||||
similar behavior, as described below. Each group of operators expects its
|
||||
given values to be of a particular type. Terraform will attempt to convert
|
||||
values to the required type automatically, or will produce an error message
|
||||
if this automatic conversion is not possible.
|
||||
|
||||
### Arithmetic Operators
|
||||
|
||||
The arithmetic operators all expect number values and produce number values
|
||||
as results:
|
||||
|
||||
* `a + b` returns the result of adding `a` and `b` together.
|
||||
* `a - b` returns the result of subtracting `b` from `a`.
|
||||
* `a * b` returns the result of multiplying `a` and `b`.
|
||||
* `a / b` returns the result of dividing `a` by `b`.
|
||||
* `a % b` returns the remainder of dividing `a` by `b`. This operator is
|
||||
generally useful only when used with whole numbers.
|
||||
* `-a` returns the result of multiplying `a` by `-1`.
|
||||
|
||||
### Equality Operators
|
||||
|
||||
The equality operators both take two values of any type and produce boolean
|
||||
values as results.
|
||||
|
||||
* `a == b` returns `true` if `a` and `b` both have the same type and the same
|
||||
value, or `false` otherwise.
|
||||
* `a != b` is the opposite of `a == b`.
|
||||
|
||||
### Comparison Operators
|
||||
|
||||
The comparison operators all expect number values and produce boolean values
|
||||
as results.
|
||||
|
||||
* `a < b` returns `true` if `a` is less than `b`, or `false` otherwise.
|
||||
* `a <= b` returns `true` if `a` is less than or equal to `b`, or `false`
|
||||
otherwise.
|
||||
* `a > b` returns `true` if `a` is greater than `b`, or `false` otherwise.
|
||||
* `a >= b` returns `true` if `a` is greater than or equal to `b`, or `false` otherwise.
|
||||
|
||||
### Logical Operators
|
||||
|
||||
The logical operators all expect bool values and produce bool values as results.
|
||||
|
||||
* `a || b` returns `true` if either `a` or `b` is `true`, or `false` if both are `false`.
|
||||
* `a && b` returns `true` if both `a` and `b` are `true`, or `false` if either one is `false`.
|
||||
* `!a` returns `true` if `a` is `false`, and `false` if `a` is `true`.
|
||||
This information has moved to
|
||||
[Operators](/docs/configuration/expressions/references.html).
|
||||
|
||||
## Conditional Expressions
|
||||
|
||||
A _conditional expression_ uses the value of a bool expression to select one of
|
||||
two values.
|
||||
The `condition ? true_val : false_val` expression chooses between two
|
||||
expressions based on a bool condition.
|
||||
|
||||
The syntax of a conditional expression is as follows:
|
||||
This information has moved to
|
||||
[Conditional Expressions](/docs/configuration/expressions/conditionals.html).
|
||||
|
||||
```hcl
|
||||
condition ? true_val : false_val
|
||||
```
|
||||
|
||||
If `condition` is `true` then the result is `true_val`. If `condition` is
|
||||
`false` then the result is `false_val`.
|
||||
|
||||
A common use of conditional expressions is to define defaults to replace
|
||||
invalid values:
|
||||
|
||||
```
|
||||
var.a != "" ? var.a : "default-a"
|
||||
```
|
||||
|
||||
If `var.a` is an empty string then the result is `"default-a"`, but otherwise
|
||||
it is the actual value of `var.a`.
|
||||
|
||||
Any of the equality, comparison, and logical operators can be used to define
|
||||
the condition. The two result values may be of any type, but they must both
|
||||
be of the _same_ type so that Terraform can determine what type the whole
|
||||
conditional expression will return without knowing the condition value.
|
||||
<a id="expanding-function-arguments"></a>
|
||||
<a id="available-functions"></a>
|
||||
|
||||
## Function Calls
|
||||
|
||||
The Terraform language has a number of
|
||||
[built-in functions](./functions.html) that can be used
|
||||
within expressions as another way to transform and combine values. These
|
||||
are similar to the operators but all follow a common syntax:
|
||||
Terraform's functions can be called like `function_name(arg1, arg2)`.
|
||||
|
||||
```hcl
|
||||
<FUNCTION NAME>(<ARGUMENT 1>, <ARGUMENT 2>)
|
||||
```
|
||||
This information has moved to
|
||||
[Function Calls](/docs/configuration/expressions/function-calls.html).
|
||||
|
||||
The function name specifies which function to call. Each defined function
|
||||
expects a specific number of arguments with specific value types, and returns a
|
||||
specific value type as a result.
|
||||
|
||||
Some functions take an arbitrary number of arguments. For example, the `min`
|
||||
function takes any amount of number arguments and returns the one that is
|
||||
numerically smallest:
|
||||
|
||||
```hcl
|
||||
min(55, 3453, 2)
|
||||
```
|
||||
|
||||
### Expanding Function Arguments
|
||||
|
||||
If the arguments to pass to a function are available in a list or tuple value,
|
||||
that value can be _expanded_ into separate arguments. Provide the list value as
|
||||
an argument and follow it with the `...` symbol:
|
||||
|
||||
```hcl
|
||||
min([55, 2453, 2]...)
|
||||
```
|
||||
|
||||
The expansion symbol is three periods (`...`), not a Unicode ellipsis character
|
||||
(`…`). Expansion is a special syntax that is only available in function calls.
|
||||
|
||||
### Available Functions
|
||||
|
||||
For a full list of available functions, see
|
||||
[the function reference](./functions.html).
|
||||
<a id="for-expressions"></a>
|
||||
|
||||
## `for` Expressions
|
||||
|
||||
A _`for` expression_ creates a complex type value by transforming
|
||||
another complex type value. Each element in the input value
|
||||
can correspond to either one or zero values in the result, and an arbitrary
|
||||
expression can be used to transform each input element into an output element.
|
||||
Expressions like `[for s in var.list : upper(s)]` can transform a complex type
|
||||
value into another complex type value.
|
||||
|
||||
For example, if `var.list` is a list of strings, then the following expression
|
||||
produces a list of strings with all-uppercase letters:
|
||||
This information has moved to
|
||||
[For Expressions](/docs/configuration/expressions/for.html).
|
||||
|
||||
```hcl
|
||||
[for s in var.list : upper(s)]
|
||||
```
|
||||
|
||||
This `for` expression iterates over each element of `var.list`, and then
|
||||
evaluates the expression `upper(s)` with `s` set to each respective element.
|
||||
It then builds a new tuple value with all of the results of executing that
|
||||
expression in the same order.
|
||||
|
||||
The type of brackets around the `for` expression decide what type of result
|
||||
it produces. The above example uses `[` and `]`, which produces a tuple. If
|
||||
`{` and `}` are used instead, the result is an object, and two result
|
||||
expressions must be provided separated by the `=>` symbol:
|
||||
|
||||
```hcl
|
||||
{for s in var.list : s => upper(s)}
|
||||
```
|
||||
|
||||
This expression produces an object whose attributes are the original elements
|
||||
from `var.list` and their corresponding values are the uppercase versions.
|
||||
|
||||
A `for` expression can also include an optional `if` clause to filter elements
|
||||
from the source collection, which can produce a value with fewer elements than
|
||||
the source:
|
||||
|
||||
```
|
||||
[for s in var.list : upper(s) if s != ""]
|
||||
```
|
||||
|
||||
The source value can also be an object or map value, in which case two
|
||||
temporary variable names can be provided to access the keys and values
|
||||
respectively:
|
||||
|
||||
```
|
||||
[for k, v in var.map : length(k) + length(v)]
|
||||
```
|
||||
|
||||
Finally, if the result type is an object (using `{` and `}` delimiters) then
|
||||
the value result expression can be followed by the `...` symbol to group
|
||||
together results that have a common key:
|
||||
|
||||
```
|
||||
{for s in var.list : substr(s, 0, 1) => s... if s != ""}
|
||||
```
|
||||
|
||||
For expressions are particularly useful when combined with other language
|
||||
features to combine collections together in various ways. For example,
|
||||
the following two patterns are commonly used when constructing map values
|
||||
to use with [resource `for_each`](./resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings):
|
||||
|
||||
* Transform a multi-level nested structure into a flat list by
|
||||
[using nested `for` expressions with the `flatten` function](./functions/flatten.html#flattening-nested-structures-for-for_each).
|
||||
* Produce an exhaustive list of combinations of elements from two or more
|
||||
collections by
|
||||
[using the `setproduct` function inside a `for` expression](./functions/setproduct.html#finding-combinations-for-for_each).
|
||||
<a id="splat-expressions"></a>
|
||||
<a id="legacy-attribute-only-splat-expressions"></a>
|
||||
|
||||
## Splat Expressions
|
||||
|
||||
A _splat expression_ provides a more concise way to express a common
|
||||
operation that could otherwise be performed with a `for` expression.
|
||||
Expressions like `var.list[*].id` can extract simpler collections from complex
|
||||
collections.
|
||||
|
||||
If `var.list` is a list of objects that all have an attribute `id`, then
|
||||
a list of the ids could be produced with the following `for` expression:
|
||||
This information has moved to
|
||||
[Splat Expressions](/docs/configuration/expressions/splat.html).
|
||||
|
||||
```hcl
|
||||
[for o in var.list : o.id]
|
||||
```
|
||||
<a id="dynamic-blocks"></a>
|
||||
<a id="best-practices-for-dynamic-blocks"></a>
|
||||
|
||||
This is equivalent to the following _splat expression:_
|
||||
## `dynamic` Blocks
|
||||
|
||||
```hcl
|
||||
var.list[*].id
|
||||
```
|
||||
The special `dynamic` block type serves the same purpose as a `for` expression,
|
||||
except it creates multiple repeatable nested blocks instead of a complex value.
|
||||
|
||||
The special `[*]` symbol iterates over all of the elements of the list given
|
||||
to its left and accesses from each one the attribute name given on its
|
||||
right. A splat expression can also be used to access attributes and indexes
|
||||
from lists of complex types by extending the sequence of operations to the
|
||||
right of the symbol:
|
||||
This information has moved to
|
||||
[Dynamic Blocks](/docs/configuration/expressions/dynamic-blocks.html).
|
||||
|
||||
```hcl
|
||||
var.list[*].interfaces[0].name
|
||||
```
|
||||
<a id="string-literals"></a>
|
||||
<a id="string-templates"></a>
|
||||
<a id="interpolation"></a>
|
||||
<a id="directives"></a>
|
||||
|
||||
The above expression is equivalent to the following `for` expression:
|
||||
## String Literals and String Templates
|
||||
|
||||
```hcl
|
||||
[for o in var.list : o.interfaces[0].name]
|
||||
```
|
||||
|
||||
Splat expressions are for lists only (and thus cannot be used [to reference resources
|
||||
created with `for_each`](/docs/configuration/resources.html#referring-to-instances-1),
|
||||
which are represented as maps in Terraform). However, if a splat expression is applied
|
||||
to a value that is _not_ a list or tuple then the value is automatically wrapped in
|
||||
a single-element list before processing.
|
||||
|
||||
For example, `var.single_object[*].id` is equivalent to `[var.single_object][*].id`,
|
||||
or effectively `[var.single_object.id]`. This behavior is not interesting in most cases,
|
||||
but it is particularly useful when referring to resources that may or may
|
||||
not have `count` set, and thus may or may not produce a tuple value:
|
||||
|
||||
```hcl
|
||||
aws_instance.example[*].id
|
||||
```
|
||||
|
||||
The above will produce a list of ids whether `aws_instance.example` has
|
||||
`count` set or not, avoiding the need to revise various other expressions
|
||||
in the configuration when a particular resource switches to and from
|
||||
having `count` set.
|
||||
|
||||
### Legacy (Attribute-only) Splat Expressions
|
||||
|
||||
An older variant of the splat expression is available for compatibility with
|
||||
code written in older versions of the Terraform language. This is a less useful
|
||||
version of the splat expression, and should be avoided in new configurations.
|
||||
|
||||
An "attribute-only" splat expression is indicated by the sequence `.*` (instead
|
||||
of `[*]`):
|
||||
|
||||
```
|
||||
var.list.*.interfaces[0].name
|
||||
```
|
||||
|
||||
This form has a subtly different behavior, equivalent to the following
|
||||
`for` expression:
|
||||
|
||||
```
|
||||
[for o in var.list : o.interfaces][0].name
|
||||
```
|
||||
|
||||
Notice that with the attribute-only splat expression the index operation
|
||||
`[0]` is applied to the result of the iteration, rather than as part of
|
||||
the iteration itself.
|
||||
|
||||
## `dynamic` blocks
|
||||
|
||||
Within top-level block constructs like resources, expressions can usually be
|
||||
used only when assigning a value to an argument using the `name = expression`
|
||||
form. This covers many uses, but some resource types include repeatable _nested
|
||||
blocks_ in their arguments, which do not accept expressions:
|
||||
|
||||
```hcl
|
||||
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
|
||||
name = "tf-test-name" # can use expressions here
|
||||
|
||||
setting {
|
||||
# but the "setting" block is always a literal block
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can dynamically construct repeatable nested blocks like `setting` using a
|
||||
special `dynamic` block type, which is supported inside `resource`, `data`,
|
||||
`provider`, and `provisioner` blocks:
|
||||
|
||||
```hcl
|
||||
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
|
||||
name = "tf-test-name"
|
||||
application = "${aws_elastic_beanstalk_application.tftest.name}"
|
||||
solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6"
|
||||
|
||||
dynamic "setting" {
|
||||
for_each = var.settings
|
||||
content {
|
||||
namespace = setting.value["namespace"]
|
||||
name = setting.value["name"]
|
||||
value = setting.value["value"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A `dynamic` block acts much like a `for` expression, but produces nested blocks
|
||||
instead of a complex typed value. It iterates over a given complex value, and
|
||||
generates a nested block for each element of that complex value.
|
||||
|
||||
- The label of the dynamic block (`"setting"` in the example above) specifies
|
||||
what kind of nested block to generate.
|
||||
- The `for_each` argument provides the complex value to iterate over.
|
||||
- The `iterator` argument (optional) sets the name of a temporary variable
|
||||
that represents the current element of the complex value. If omitted, the name
|
||||
of the variable defaults to the label of the `dynamic` block (`"setting"` in
|
||||
the example above).
|
||||
- The `labels` argument (optional) is a list of strings that specifies the block
|
||||
labels, in order, to use for each generated block. You can use the temporary
|
||||
iterator variable in this value.
|
||||
- The nested `content` block defines the body of each generated block. You can
|
||||
use the temporary iterator variable inside this block.
|
||||
|
||||
Since the `for_each` argument accepts any collection or structural value,
|
||||
you can use a `for` expression or splat expression to transform an existing
|
||||
collection.
|
||||
|
||||
The iterator object (`setting` in the example above) has two attributes:
|
||||
|
||||
* `key` is the map key or list element index for the current element. If the
|
||||
`for_each` expression produces a _set_ value then `key` is identical to
|
||||
`value` and should not be used.
|
||||
* `value` is the value of the current element.
|
||||
|
||||
A `dynamic` block can only generate arguments that belong to the resource type,
|
||||
data source, provider or provisioner being configured. It is _not_ possible
|
||||
to generate meta-argument blocks such as `lifecycle` and `provisioner`
|
||||
blocks, since Terraform must process these before it is safe to evaluate
|
||||
expressions.
|
||||
|
||||
The `for_each` value must be a map or set with one element per desired
|
||||
nested block. If you need to declare resource instances based on a nested
|
||||
data structure or combinations of elements from multiple data structures you
|
||||
can use Terraform expressions and functions to derive a suitable value.
|
||||
For some common examples of such situations, see the
|
||||
[`flatten`](/docs/configuration/functions/flatten.html)
|
||||
and
|
||||
[`setproduct`](/docs/configuration/functions/setproduct.html)
|
||||
functions.
|
||||
|
||||
### Best Practices for `dynamic` Blocks
|
||||
|
||||
Overuse of `dynamic` blocks can make configuration hard to read and maintain, so
|
||||
we recommend using them only when you need to hide details in order to build a
|
||||
clean user interface for a re-usable module. Always write nested blocks out
|
||||
literally where possible.
|
||||
|
||||
## String Literals
|
||||
|
||||
The Terraform language has two different syntaxes for string literals. The
|
||||
most common is to delimit the string with quote characters (`"`), like
|
||||
`"hello"`. 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) |
|
||||
|
||||
The alternative syntax for string literals is the so-called "heredoc" style,
|
||||
inspired by Unix shell languages. This style allows multi-line strings to
|
||||
be expressed more clearly by using a custom delimiter word on a line of its
|
||||
own to close the string:
|
||||
Strings can be `"double-quoted"` or
|
||||
|
||||
```hcl
|
||||
<<EOT
|
||||
hello
|
||||
world
|
||||
heredocs
|
||||
EOT
|
||||
```
|
||||
|
||||
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".
|
||||
Strings can also include escape sequences like `\n`, interpolation sequences
|
||||
(`${ ... }`), and template sequences (`%{ ... }`).
|
||||
|
||||
The "heredoc" form shown above requires that the lines following be flush with
|
||||
the left margin, which can be awkward when an expression is inside 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
|
||||
```
|
||||
|
||||
Backslash sequences are not interpreted in a heredoc string expression.
|
||||
Instead, the backslash character is interpreted literally.
|
||||
|
||||
In both quoted and heredoc string expressions, Terraform supports template
|
||||
sequences that begin with `${` and `%{`. These are described in more detail
|
||||
in the following section. To include these sequences _literally_ without
|
||||
beginning a template sequence, double the leading character: `$${` or `%%{`.
|
||||
|
||||
## 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.
|
||||
|
||||
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.
|
||||
This information has moved to
|
||||
[Strings and Templates](/docs/configuration/expressions/strings.html).
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Conditional Expressions - Configuration Language"
|
||||
---
|
||||
|
||||
# Conditional Expressions
|
||||
|
||||
A _conditional expression_ uses the value of a bool expression to select one of
|
||||
two values.
|
||||
|
||||
The syntax of a conditional expression is as follows:
|
||||
|
||||
```hcl
|
||||
condition ? true_val : false_val
|
||||
```
|
||||
|
||||
If `condition` is `true` then the result is `true_val`. If `condition` is
|
||||
`false` then the result is `false_val`.
|
||||
|
||||
A common use of conditional expressions is to define defaults to replace
|
||||
invalid values:
|
||||
|
||||
```
|
||||
var.a != "" ? var.a : "default-a"
|
||||
```
|
||||
|
||||
If `var.a` is an empty string then the result is `"default-a"`, but otherwise
|
||||
it is the actual value of `var.a`.
|
||||
|
||||
## Conditions
|
||||
|
||||
The condition can be any expression that resolves to a boolean value. This will
|
||||
usually be an expression that uses the equality, comparison, or logical
|
||||
operators.
|
||||
|
||||
## Result Types
|
||||
|
||||
The two result values may be of any type, but they must both
|
||||
be of the _same_ type so that Terraform can determine what type the whole
|
||||
conditional expression will return without knowing the condition value.
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Dynamic Blocks - Configuration Language"
|
||||
---
|
||||
|
||||
|
||||
# `dynamic` Blocks
|
||||
|
||||
Within top-level block constructs like resources, expressions can usually be
|
||||
used only when assigning a value to an argument using the `name = expression`
|
||||
form. This covers many uses, but some resource types include repeatable _nested
|
||||
blocks_ in their arguments, which do not accept expressions:
|
||||
|
||||
```hcl
|
||||
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
|
||||
name = "tf-test-name" # can use expressions here
|
||||
|
||||
setting {
|
||||
# but the "setting" block is always a literal block
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can dynamically construct repeatable nested blocks like `setting` using a
|
||||
special `dynamic` block type, which is supported inside `resource`, `data`,
|
||||
`provider`, and `provisioner` blocks:
|
||||
|
||||
```hcl
|
||||
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
|
||||
name = "tf-test-name"
|
||||
application = "${aws_elastic_beanstalk_application.tftest.name}"
|
||||
solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6"
|
||||
|
||||
dynamic "setting" {
|
||||
for_each = var.settings
|
||||
content {
|
||||
namespace = setting.value["namespace"]
|
||||
name = setting.value["name"]
|
||||
value = setting.value["value"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A `dynamic` block acts much like a `for` expression, but produces nested blocks
|
||||
instead of a complex typed value. It iterates over a given complex value, and
|
||||
generates a nested block for each element of that complex value.
|
||||
|
||||
- The label of the dynamic block (`"setting"` in the example above) specifies
|
||||
what kind of nested block to generate.
|
||||
- The `for_each` argument provides the complex value to iterate over.
|
||||
- The `iterator` argument (optional) sets the name of a temporary variable
|
||||
that represents the current element of the complex value. If omitted, the name
|
||||
of the variable defaults to the label of the `dynamic` block (`"setting"` in
|
||||
the example above).
|
||||
- The `labels` argument (optional) is a list of strings that specifies the block
|
||||
labels, in order, to use for each generated block. You can use the temporary
|
||||
iterator variable in this value.
|
||||
- The nested `content` block defines the body of each generated block. You can
|
||||
use the temporary iterator variable inside this block.
|
||||
|
||||
Since the `for_each` argument accepts any collection or structural value,
|
||||
you can use a `for` expression or splat expression to transform an existing
|
||||
collection.
|
||||
|
||||
The iterator object (`setting` in the example above) has two attributes:
|
||||
|
||||
* `key` is the map key or list element index for the current element. If the
|
||||
`for_each` expression produces a _set_ value then `key` is identical to
|
||||
`value` and should not be used.
|
||||
* `value` is the value of the current element.
|
||||
|
||||
A `dynamic` block can only generate arguments that belong to the resource type,
|
||||
data source, provider or provisioner being configured. It is _not_ possible
|
||||
to generate meta-argument blocks such as `lifecycle` and `provisioner`
|
||||
blocks, since Terraform must process these before it is safe to evaluate
|
||||
expressions.
|
||||
|
||||
The `for_each` value must be a map or set with one element per desired
|
||||
nested block. If you need to declare resource instances based on a nested
|
||||
data structure or combinations of elements from multiple data structures you
|
||||
can use Terraform expressions and functions to derive a suitable value.
|
||||
For some common examples of such situations, see the
|
||||
[`flatten`](/docs/configuration/functions/flatten.html)
|
||||
and
|
||||
[`setproduct`](/docs/configuration/functions/setproduct.html)
|
||||
functions.
|
||||
|
||||
## Best Practices for `dynamic` Blocks
|
||||
|
||||
Overuse of `dynamic` blocks can make configuration hard to read and maintain, so
|
||||
we recommend using them only when you need to hide details in order to build a
|
||||
clean user interface for a re-usable module. Always write nested blocks out
|
||||
literally where possible.
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "For Expressions - Configuration Language"
|
||||
---
|
||||
|
||||
# `for` Expressions
|
||||
|
||||
A _`for` expression_ creates a complex type value by transforming
|
||||
another complex type value. Each element in the input value
|
||||
can correspond to either one or zero values in the result, and an arbitrary
|
||||
expression can be used to transform each input element into an output element.
|
||||
|
||||
For example, if `var.list` is a list of strings, then the following expression
|
||||
produces a list of strings with all-uppercase letters:
|
||||
|
||||
```hcl
|
||||
[for s in var.list : upper(s)]
|
||||
```
|
||||
|
||||
This `for` expression iterates over each element of `var.list`, and then
|
||||
evaluates the expression `upper(s)` with `s` set to each respective element.
|
||||
It then builds a new tuple value with all of the results of executing that
|
||||
expression in the same order.
|
||||
|
||||
The type of brackets around the `for` expression decide what type of result
|
||||
it produces. The above example uses `[` and `]`, which produces a tuple. If
|
||||
`{` and `}` are used instead, the result is an object, and two result
|
||||
expressions must be provided separated by the `=>` symbol:
|
||||
|
||||
```hcl
|
||||
{for s in var.list : s => upper(s)}
|
||||
```
|
||||
|
||||
This expression produces an object whose attributes are the original elements
|
||||
from `var.list` and their corresponding values are the uppercase versions.
|
||||
|
||||
A `for` expression can also include an optional `if` clause to filter elements
|
||||
from the source collection, which can produce a value with fewer elements than
|
||||
the source:
|
||||
|
||||
```
|
||||
[for s in var.list : upper(s) if s != ""]
|
||||
```
|
||||
|
||||
The source value can also be an object or map value, in which case two
|
||||
temporary variable names can be provided to access the keys and values
|
||||
respectively:
|
||||
|
||||
```
|
||||
[for k, v in var.map : length(k) + length(v)]
|
||||
```
|
||||
|
||||
Finally, if the result type is an object (using `{` and `}` delimiters) then
|
||||
the value result expression can be followed by the `...` symbol to group
|
||||
together results that have a common key:
|
||||
|
||||
```
|
||||
{for s in var.list : substr(s, 0, 1) => s... if s != ""}
|
||||
```
|
||||
|
||||
For expressions are particularly useful when combined with other language
|
||||
features to combine collections together in various ways. For example,
|
||||
the following two patterns are commonly used when constructing map values
|
||||
to use with
|
||||
[the `for_each` meta-argument](/docs/configuration/meta-arguments/for_each.html):
|
||||
|
||||
* Transform a multi-level nested structure into a flat list by
|
||||
[using nested `for` expressions with the `flatten` function](/docs/configuration/functions/flatten.html#flattening-nested-structures-for-for_each).
|
||||
* Produce an exhaustive list of combinations of elements from two or more
|
||||
collections by
|
||||
[using the `setproduct` function inside a `for` expression](/docs/configuration/functions/setproduct.html#finding-combinations-for-for_each).
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Function Calls - Configuration Language"
|
||||
---
|
||||
|
||||
# Function Calls
|
||||
|
||||
The Terraform language has a number of
|
||||
[built-in functions](/docs/configuration/functions.html) that can be used
|
||||
in expressions to transform and combine values. These
|
||||
are similar to the operators but all follow a common syntax:
|
||||
|
||||
```hcl
|
||||
<FUNCTION NAME>(<ARGUMENT 1>, <ARGUMENT 2>)
|
||||
```
|
||||
|
||||
The function name specifies which function to call. Each defined function
|
||||
expects a specific number of arguments with specific value types, and returns a
|
||||
specific value type as a result.
|
||||
|
||||
Some functions take an arbitrary number of arguments. For example, the `min`
|
||||
function takes any amount of number arguments and returns the one that is
|
||||
numerically smallest:
|
||||
|
||||
```hcl
|
||||
min(55, 3453, 2)
|
||||
```
|
||||
|
||||
A function call expression evaluates to the function's return value.
|
||||
|
||||
## Expanding Function Arguments
|
||||
|
||||
If the arguments to pass to a function are available in a list or tuple value,
|
||||
that value can be _expanded_ into separate arguments. Provide the list value as
|
||||
an argument and follow it with the `...` symbol:
|
||||
|
||||
```hcl
|
||||
min([55, 2453, 2]...)
|
||||
```
|
||||
|
||||
The expansion symbol is three periods (`...`), not a Unicode ellipsis character
|
||||
(`…`). Expansion is a special syntax that is only available in function calls.
|
||||
|
||||
## Available Functions
|
||||
|
||||
For a full list of available functions, see
|
||||
[the function reference](/docs/configuration/functions.html).
|
||||
|
|
@ -15,7 +15,8 @@ Expressions can be used in a number of places in the Terraform language,
|
|||
but some contexts limit which expression constructs are allowed,
|
||||
such as requiring a literal value of a particular type or forbidding
|
||||
[references to resource attributes](/docs/configuration/expressions/references.html#references-to-resource-attributes).
|
||||
Each language feature's documentation describes any restrictions it places on expressions.
|
||||
Each language feature's documentation describes any restrictions it places on
|
||||
expressions.
|
||||
|
||||
You can experiment with the behavior of Terraform's expressions from
|
||||
the Terraform expression console, by running
|
||||
|
@ -23,3 +24,44 @@ the Terraform expression console, by running
|
|||
|
||||
The other pages in this section describe the features of Terraform's
|
||||
expression syntax.
|
||||
|
||||
- [Types and Values](/docs/configuration/expressions/types.html)
|
||||
documents the data types that Terraform expressions can resolve to, and the
|
||||
literal syntaxes for values of those types.
|
||||
|
||||
- [Strings and Templates](/docs/configuration/expressions/strings.html)
|
||||
documents the syntaxes for string literals, including interpolation sequences
|
||||
and template directives.
|
||||
|
||||
- [References to Values](/docs/configuration/expressions/references.html)
|
||||
documents how to refer to named values like variables and resource attributes.
|
||||
|
||||
- [Operators](/docs/configuration/expressions/references.html)
|
||||
documents the arithmetic, comparison, and logical operators.
|
||||
|
||||
- [Function Calls](/docs/configuration/expressions/function-calls.html)
|
||||
documents the syntax for calling Terraform's built-in functions.
|
||||
|
||||
- [Conditional Expressions](/docs/configuration/expressions/conditionals.html)
|
||||
documents the `<CONDITION> ? <TRUE VAL> : <FALSE VAL>` expression, which
|
||||
chooses between two values based on a bool condition.
|
||||
|
||||
- [For Expressions](/docs/configuration/expressions/for.html)
|
||||
documents expressions like `[for s in var.list : upper(s)]`, which can
|
||||
transform a complex type value into another complex type value.
|
||||
|
||||
- [Splat Expressions](/docs/configuration/expressions/splat.html)
|
||||
documents expressions like `var.list[*].id`, which can extract simpler
|
||||
collections from more complicated expressions.
|
||||
|
||||
- [Dynamic Blocks](/docs/configuration/expressions/dynamic-blocks.html)
|
||||
documents a way to create multiple repeatable nested blocks within a resource
|
||||
or other construct.
|
||||
|
||||
- [Type Constraints](/docs/configuration/types.html)
|
||||
documents the syntax for referring to a type, rather than a value of that
|
||||
type. Input variables expect this syntax in their `type` argument.
|
||||
|
||||
- [Version Constraints](/docs/configuration/version-constraints.html)
|
||||
documents the syntax of special strings that define a set of allowed software
|
||||
versions. Terraform uses version constraints in several places.
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Operators - Configuration Language"
|
||||
---
|
||||
|
||||
# Arithmetic and Logical Operators
|
||||
|
||||
An _operator_ is a type of expression that transforms or combines one or more
|
||||
other expressions. Operators either combine two values in some way to
|
||||
produce a third result value, or transform a single given value to
|
||||
produce a single result.
|
||||
|
||||
Operators that work on two values place an operator symbol between the two
|
||||
values, similar to mathematical notation: `1 + 2`. Operators that work on
|
||||
only one value place an operator symbol before that value, like
|
||||
`!true`.
|
||||
|
||||
The Terraform language has a set of operators for both arithmetic and logic,
|
||||
which are similar to operators in programming languages such as JavaScript
|
||||
or Ruby.
|
||||
|
||||
When multiple operators are used together in an expression, they are evaluated
|
||||
in the following order of operations:
|
||||
|
||||
1. `!`, `-` (multiplication by `-1`)
|
||||
1. `*`, `/`, `%`
|
||||
1. `+`, `-` (subtraction)
|
||||
1. `>`, `>=`, `<`, `<=`
|
||||
1. `==`, `!=`
|
||||
1. `&&`
|
||||
1. `||`
|
||||
|
||||
Parentheses can be used to override the default order of operations. Without
|
||||
parentheses, higher levels are evaluated first, so `1 + 2 * 3` is interpreted
|
||||
as `1 + (2 * 3)` and _not_ as `(1 + 2) * 3`.
|
||||
|
||||
The different operators can be gathered into a few different groups with
|
||||
similar behavior, as described below. Each group of operators expects its
|
||||
given values to be of a particular type. Terraform will attempt to convert
|
||||
values to the required type automatically, or will produce an error message
|
||||
if this automatic conversion is not possible.
|
||||
|
||||
## Arithmetic Operators
|
||||
|
||||
The arithmetic operators all expect number values and produce number values
|
||||
as results:
|
||||
|
||||
* `a + b` returns the result of adding `a` and `b` together.
|
||||
* `a - b` returns the result of subtracting `b` from `a`.
|
||||
* `a * b` returns the result of multiplying `a` and `b`.
|
||||
* `a / b` returns the result of dividing `a` by `b`.
|
||||
* `a % b` returns the remainder of dividing `a` by `b`. This operator is
|
||||
generally useful only when used with whole numbers.
|
||||
* `-a` returns the result of multiplying `a` by `-1`.
|
||||
|
||||
## Equality Operators
|
||||
|
||||
The equality operators both take two values of any type and produce boolean
|
||||
values as results.
|
||||
|
||||
* `a == b` returns `true` if `a` and `b` both have the same type and the same
|
||||
value, or `false` otherwise.
|
||||
* `a != b` is the opposite of `a == b`.
|
||||
|
||||
## Comparison Operators
|
||||
|
||||
The comparison operators all expect number values and produce boolean values
|
||||
as results.
|
||||
|
||||
* `a < b` returns `true` if `a` is less than `b`, or `false` otherwise.
|
||||
* `a <= b` returns `true` if `a` is less than or equal to `b`, or `false`
|
||||
otherwise.
|
||||
* `a > b` returns `true` if `a` is greater than `b`, or `false` otherwise.
|
||||
* `a >= b` returns `true` if `a` is greater than or equal to `b`, or `false` otherwise.
|
||||
|
||||
## Logical Operators
|
||||
|
||||
The logical operators all expect bool values and produce bool values as results.
|
||||
|
||||
* `a || b` returns `true` if either `a` or `b` is `true`, or `false` if both are `false`.
|
||||
* `a && b` returns `true` if both `a` and `b` are `true`, or `false` if either one is `false`.
|
||||
* `!a` returns `true` if `a` is `false`, and `false` if `a` is `true`.
|
|
@ -0,0 +1,247 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "References to Values - Configuration Language"
|
||||
---
|
||||
|
||||
# References to Named Values
|
||||
|
||||
Terraform makes several kinds of named values available. Each of these names is
|
||||
an expression that references the associated value; you can use them as
|
||||
standalone expressions, or combine them with other expressions to compute new
|
||||
values.
|
||||
|
||||
## Types of Named Values
|
||||
|
||||
The main kinds of named values available in Terraform are:
|
||||
|
||||
- Resources
|
||||
- Input variables
|
||||
- Local values
|
||||
- Child module outputs
|
||||
- Data sources
|
||||
- Filesystem and workspace info
|
||||
- Block-local values
|
||||
|
||||
The sections below explain each kind of named value in detail.
|
||||
|
||||
Although many of these names use dot-separated paths that resemble
|
||||
[attribute notation](./types.html#indices-and-attributes) for elements of object values, they are not
|
||||
implemented as real objects. This means you must use them exactly as written:
|
||||
you cannot use square-bracket notation to replace the dot-separated paths, and
|
||||
you cannot iterate over the "parent object" of a named entity; for example, you
|
||||
cannot use `aws_instance` in a `for` expression to iterate over every AWS
|
||||
instance resource.
|
||||
|
||||
### Resources
|
||||
|
||||
`<RESOURCE TYPE>.<NAME>` represents a [managed resource](/docs/configuration/blocks/resources/index.html) of
|
||||
the given type and name.
|
||||
|
||||
The value of a resource reference can vary, depending on whether the resource
|
||||
uses `count` or `for_each`:
|
||||
|
||||
- If the resource doesn't use `count` or `for_each`, the reference's value is an
|
||||
object. The resource's attributes are elements of the object, and you can
|
||||
access them using [dot or square bracket notation](./types.html#indices-and-attributes).
|
||||
- If the resource has the `count` argument set, the reference's value is a
|
||||
_list_ of objects representing its instances.
|
||||
- If the resource has the `for_each` argument set, the reference's value is a
|
||||
_map_ of objects representing its instances.
|
||||
|
||||
Any named value that does not match another pattern listed below
|
||||
will be interpreted by Terraform as a reference to a managed resource.
|
||||
|
||||
For more information about how to use resource references, see
|
||||
[references to resource attributes](#references-to-resource-attributes) below.
|
||||
|
||||
### Input Variables
|
||||
|
||||
`var.<NAME>` is the value of the [input variable](/docs/configuration/variables.html) of the given name.
|
||||
|
||||
### Local Values
|
||||
|
||||
`local.<NAME>` is the value of the [local value](/docs/configuration/locals.html) of the given name.
|
||||
|
||||
### Child Module Outputs
|
||||
|
||||
* `module.<MODULE NAME>.<OUTPUT NAME>` is the value of the specified
|
||||
[output value](/docs/configuration/outputs.html) from a
|
||||
[child module](/docs/configuration/blocks/modules/index.html) called by the
|
||||
current module.
|
||||
|
||||
### Data Sources
|
||||
|
||||
* `data.<DATA TYPE>.<NAME>` is an object representing a
|
||||
[data resource](/docs/configuration/data-sources.html) of the given data
|
||||
source type and name. If the resource has the `count` argument set, the value
|
||||
is a list of objects representing its instances. If the resource has the `for_each`
|
||||
argument set, the value is a map of objects representing its instances.
|
||||
|
||||
### Filesystem and Workspace Info
|
||||
|
||||
* `path.module` is the filesystem path of the module where the expression
|
||||
is placed.
|
||||
* `path.root` is the filesystem path of the root module of the configuration.
|
||||
* `path.cwd` is the filesystem path of the current working directory. In
|
||||
normal use of Terraform this is the same as `path.root`, but some advanced
|
||||
uses of Terraform run it from a directory other than the root module
|
||||
directory, causing these paths to be different.
|
||||
* `terraform.workspace` is the name of the currently selected
|
||||
[workspace](/docs/state/workspaces.html).
|
||||
|
||||
### Block-Local Values
|
||||
|
||||
Within the bodies of certain blocks, or in some other specific contexts,
|
||||
there are other named values available beyond the global values listed above.
|
||||
These local names are described in the documentation for the specific contexts
|
||||
where they appear. Some of most common local names are:
|
||||
|
||||
- `count.index`, in resources that use
|
||||
[the `count` meta-argument](/docs/configuration/meta-arguments/count.html).
|
||||
- `each.key` / `each.value`, in resources that use
|
||||
[the `for_each` meta-argument](/docs/configuration/meta-arguments/for_each.html).
|
||||
- `self`, in [provisioner](/docs/provisioners/index.html) and
|
||||
[connection](/docs/provisioners/connection.html) blocks.
|
||||
|
||||
-> **Note:** Local names are often referred to as _variables_ or
|
||||
_temporary variables_ in their documentation. These are not [input
|
||||
variables](/docs/configuration/variables.html); they are just arbitrary names
|
||||
that temporarily represent a value.
|
||||
|
||||
## Named Values and Dependencies
|
||||
|
||||
Constructs like resources and module calls often use references to named values
|
||||
in their block bodies, and Terraform analyzes these expressions to automatically
|
||||
infer dependencies between objects. For example, an expression in a resource
|
||||
argument that refers to another managed resource creates an implicit dependency
|
||||
between the two resources.
|
||||
|
||||
## References to Resource Attributes
|
||||
|
||||
The most common reference type is a reference to an attribute of a resource
|
||||
which has been declared either with a `resource` or `data` block. Because
|
||||
the contents of such blocks can be quite complicated themselves, expressions
|
||||
referring to these contents can also be complicated.
|
||||
|
||||
Consider the following example resource block:
|
||||
|
||||
```hcl
|
||||
resource "aws_instance" "example" {
|
||||
ami = "ami-abc123"
|
||||
instance_type = "t2.micro"
|
||||
|
||||
ebs_block_device {
|
||||
device_name = "sda2"
|
||||
volume_size = 16
|
||||
}
|
||||
ebs_block_device {
|
||||
device_name = "sda3"
|
||||
volume_size = 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The documentation for [`aws_instance`](/docs/providers/aws/r/instance.html)
|
||||
lists all of the arguments and nested blocks supported for this resource type,
|
||||
and also lists a number of attributes that are _exported_ by this resource
|
||||
type. All of these different resource type schema constructs are available
|
||||
for use in references, as follows:
|
||||
|
||||
* The `ami` argument set in the configuration can be used elsewhere with
|
||||
the reference expression `aws_instance.example.ami`.
|
||||
* The `id` attribute exported by this resource type can be read using the
|
||||
same syntax, giving `aws_instance.example.id`.
|
||||
* The arguments of the `ebs_block_device` nested blocks can be accessed using
|
||||
a [splat expression](./splat.html). For example, to obtain a list of
|
||||
all of the `device_name` values, use
|
||||
`aws_instance.example.ebs_block_device[*].device_name`.
|
||||
* The nested blocks in this particular resource type do not have any exported
|
||||
attributes, but if `ebs_block_device` were to have a documented `id`
|
||||
attribute then a list of them could be accessed similarly as
|
||||
`aws_instance.example.ebs_block_device[*].id`.
|
||||
* Sometimes nested blocks are defined as taking a logical key to identify each
|
||||
block, which serves a similar purpose as the resource's own name by providing
|
||||
a convenient way to refer to that single block in expressions. If `aws_instance`
|
||||
had a hypothetical nested block type `device` that accepted such a key, it
|
||||
would look like this in configuration:
|
||||
|
||||
```hcl
|
||||
device "foo" {
|
||||
size = 2
|
||||
}
|
||||
device "bar" {
|
||||
size = 4
|
||||
}
|
||||
```
|
||||
|
||||
Arguments inside blocks with _keys_ can be accessed using index syntax, such
|
||||
as `aws_instance.example.device["foo"].size`.
|
||||
|
||||
To obtain a map of values of a particular argument for _labelled_ nested
|
||||
block types, use a [`for` expression](./for.html):
|
||||
`{for k, device in aws_instance.example.device : k => device.size}`.
|
||||
|
||||
When a resource has the
|
||||
[`count`](/docs/configuration/meta-arguments/count.html)
|
||||
argument set, the resource itself becomes a _list_ of instance objects rather than
|
||||
a single object. In that case, access the attributes of the instances using
|
||||
either [splat expressions](./splat.html) or index syntax:
|
||||
|
||||
* `aws_instance.example[*].id` returns a list of all of the ids of each of the
|
||||
instances.
|
||||
* `aws_instance.example[0].id` returns just the id of the first instance.
|
||||
|
||||
When a resource has the
|
||||
[`for_each`](/docs/configuration/meta-arguments/for_each.html)
|
||||
argument set, the resource itself becomes a _map_ of instance objects rather than
|
||||
a single object, and attributes of instances must be specified by key, or can
|
||||
be accessed using a [`for` expression](./for.html).
|
||||
|
||||
* `aws_instance.example["a"].id` returns the id of the "a"-keyed resource.
|
||||
* `[for value in aws_instance.example: value.id]` returns a list of all of the ids
|
||||
of each of the instances.
|
||||
|
||||
Note that unlike `count`, splat expressions are _not_ directly applicable to resources managed with `for_each`, as splat expressions must act on a list value. However, you can use the `values()` function to extract the instances as a list and use that list value in a splat expression:
|
||||
|
||||
* `values(aws_instance.example)[*].id`
|
||||
|
||||
### Values Not Yet Known
|
||||
|
||||
When Terraform is planning a set of changes that will apply your configuration,
|
||||
some resource attribute values cannot be populated immediately because their
|
||||
values are decided dynamically by the remote system. For example, if a
|
||||
particular remote object type is assigned a generated unique id on creation,
|
||||
Terraform cannot predict the value of this id until the object has been created.
|
||||
|
||||
To allow expressions to still be evaluated during the plan phase, Terraform
|
||||
uses special "unknown value" placeholders for these results. In most cases you
|
||||
don't need to do anything special to deal with these, since the Terraform
|
||||
language automatically handles unknown values during expressions, so that
|
||||
for example adding a known value to an unknown value automatically produces
|
||||
an unknown value as the result.
|
||||
|
||||
However, there are some situations where unknown values _do_ have a significant
|
||||
effect:
|
||||
|
||||
* The `count` meta-argument for resources cannot be unknown, since it must
|
||||
be evaluated during the plan phase to determine how many instances are to
|
||||
be created.
|
||||
|
||||
* If unknown values are used in the configuration of a data resource, that
|
||||
data resource cannot be read during the plan phase and so it will be deferred
|
||||
until the apply phase. In this case, the results of the data resource will
|
||||
_also_ be unknown values.
|
||||
|
||||
* If an unknown value is assigned to an argument inside a `module` block,
|
||||
any references to the corresponding input variable within the child module
|
||||
will use that unknown value.
|
||||
|
||||
* If an unknown value is used in the `value` argument of an output value,
|
||||
any references to that output value in the parent module will use that
|
||||
unknown value.
|
||||
|
||||
* Terraform will attempt to validate that unknown values are of suitable
|
||||
types where possible, but incorrect use of such values may not be detected
|
||||
until the apply phase, causing the apply to fail.
|
||||
|
||||
Unknown values appear in the `terraform plan` output as `(not yet known)`.
|
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Splat Expressions - Configuration Language"
|
||||
---
|
||||
|
||||
# Splat Expressions
|
||||
|
||||
A _splat expression_ provides a more concise way to express a common
|
||||
operation that could otherwise be performed with a `for` expression.
|
||||
|
||||
If `var.list` is a list of objects that all have an attribute `id`, then
|
||||
a list of the ids could be produced with the following `for` expression:
|
||||
|
||||
```hcl
|
||||
[for o in var.list : o.id]
|
||||
```
|
||||
|
||||
This is equivalent to the following _splat expression:_
|
||||
|
||||
```hcl
|
||||
var.list[*].id
|
||||
```
|
||||
|
||||
The special `[*]` symbol iterates over all of the elements of the list given
|
||||
to its left and accesses from each one the attribute name given on its
|
||||
right. A splat expression can also be used to access attributes and indexes
|
||||
from lists of complex types by extending the sequence of operations to the
|
||||
right of the symbol:
|
||||
|
||||
```hcl
|
||||
var.list[*].interfaces[0].name
|
||||
```
|
||||
|
||||
The above expression is equivalent to the following `for` expression:
|
||||
|
||||
```hcl
|
||||
[for o in var.list : o.interfaces[0].name]
|
||||
```
|
||||
|
||||
Splat expressions are for lists only (and thus cannot be used [to reference resources
|
||||
created with `for_each`](/docs/configuration/meta-arguments/for_each.html#referring-to-instances),
|
||||
which are represented as maps in Terraform). However, if a splat expression is applied
|
||||
to a value that is _not_ a list or tuple then the value is automatically wrapped in
|
||||
a single-element list before processing.
|
||||
|
||||
For example, `var.single_object[*].id` is equivalent to `[var.single_object][*].id`,
|
||||
or effectively `[var.single_object.id]`. This behavior is not interesting in most cases,
|
||||
but it is particularly useful when referring to resources that may or may
|
||||
not have `count` set, and thus may or may not produce a tuple value:
|
||||
|
||||
```hcl
|
||||
aws_instance.example[*].id
|
||||
```
|
||||
|
||||
The above will produce a list of ids whether `aws_instance.example` has
|
||||
`count` set or not, avoiding the need to revise various other expressions
|
||||
in the configuration when a particular resource switches to and from
|
||||
having `count` set.
|
||||
|
||||
## Legacy (Attribute-only) Splat Expressions
|
||||
|
||||
An older variant of the splat expression is available for compatibility with
|
||||
code written in older versions of the Terraform language. This is a less useful
|
||||
version of the splat expression, and should be avoided in new configurations.
|
||||
|
||||
An "attribute-only" splat expression is indicated by the sequence `.*` (instead
|
||||
of `[*]`):
|
||||
|
||||
```
|
||||
var.list.*.interfaces[0].name
|
||||
```
|
||||
|
||||
This form has a subtly different behavior, equivalent to the following
|
||||
`for` expression:
|
||||
|
||||
```
|
||||
[for o in var.list : o.interfaces][0].name
|
||||
```
|
||||
|
||||
Notice that with the attribute-only splat expression the index operation
|
||||
`[0]` is applied to the result of the iteration, rather than as part of
|
||||
the iteration itself.
|
|
@ -0,0 +1,208 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Strings and Templates - Configuration Language"
|
||||
---
|
||||
|
||||
# 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".
|
||||
|
||||
### 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.
|
|
@ -0,0 +1,147 @@
|
|||
---
|
||||
layout: "language"
|
||||
page_title: "Types and Values - Configuration Language"
|
||||
---
|
||||
|
||||
# Types and Values
|
||||
|
||||
The result of an expression is a _value_. All values have a _type_, which
|
||||
dictates where that value can be used and what transformations can be
|
||||
applied to it.
|
||||
|
||||
## Types
|
||||
|
||||
The Terraform language uses the following types for its values:
|
||||
|
||||
* `string`: a sequence of Unicode characters representing some text, like
|
||||
`"hello"`.
|
||||
* `number`: a numeric value. The `number` type can represent both whole
|
||||
numbers like `15` and fractional values like `6.283185`.
|
||||
* `bool`: a boolean value, either `true` or `false`. `bool` values can be used in conditional
|
||||
logic.
|
||||
* `list` (or `tuple`): a sequence of values, like
|
||||
`["us-west-1a", "us-west-1c"]`. Elements in a list or tuple are identified by
|
||||
consecutive whole numbers, starting with zero.
|
||||
* `map` (or `object`): a group of values identified by named labels, like
|
||||
`{name = "Mabel", age = 52}`.
|
||||
|
||||
Strings, numbers, and bools are sometimes called _primitive types._ Lists/tuples and maps/objects are sometimes called _complex types,_ _structural types,_ or _collection types._
|
||||
|
||||
Finally, there is one special value that has _no_ type:
|
||||
|
||||
* `null`: a value that represents _absence_ or _omission._ If you set an
|
||||
argument of a resource or module to `null`, Terraform behaves as though you
|
||||
had completely omitted it — it will use the argument's default value if it has
|
||||
one, or raise an error if the argument is mandatory. `null` is most useful in
|
||||
conditional expressions, so you can dynamically omit an argument if a
|
||||
condition isn't met.
|
||||
|
||||
## Literal Expressions
|
||||
|
||||
A _literal expression_ is an expression that directly represents a particular
|
||||
constant value. Terraform has a literal expression syntax for each of the value
|
||||
types described above.
|
||||
|
||||
### Strings
|
||||
|
||||
Strings are usually represented by a double-quoted sequence of Unicode
|
||||
characters, `"like this"`. There is also a "heredoc" syntax for more complex
|
||||
strings.
|
||||
|
||||
String literals are the most complex kind of literal expression in
|
||||
Terraform, and have their own page of documentation. See [Strings](./strings.html)
|
||||
for information about escape sequences, the heredoc syntax, interpolation, and
|
||||
template directives.
|
||||
|
||||
### Numbers
|
||||
|
||||
Numbers are represented by unquoted sequences of digits with or without a
|
||||
decimal point, like `15` or `6.283185`.
|
||||
|
||||
### Bools
|
||||
|
||||
Bools are represented by the unquoted symbols `true` and `false`.
|
||||
|
||||
### Null
|
||||
|
||||
The null value is represented by the unquoted symbol `null`.
|
||||
|
||||
### Lists/Tuples
|
||||
|
||||
Lists/tuples are represented by a pair of square brackets containing a
|
||||
comma-separated sequence of values, like `["a", 15, true]`.
|
||||
|
||||
List literals can be split into multiple lines for readability, but always
|
||||
require a comma between values. A comma after the final value is allowed,
|
||||
but not required. Values in a list can be arbitrary expressions.
|
||||
|
||||
### Maps/Objects
|
||||
|
||||
Maps/objects are represented by a pair of curly braces containing a series of
|
||||
`<KEY> = <VALUE>` pairs:
|
||||
|
||||
```hcl
|
||||
{
|
||||
name = "John"
|
||||
age = 52
|
||||
}
|
||||
```
|
||||
|
||||
Key/value pairs can be separated by either a comma or a line break.
|
||||
|
||||
The values in a map
|
||||
can be arbitrary expressions.
|
||||
|
||||
The keys in a map must be strings; they can be left unquoted if
|
||||
they are a valid [identifier](/docs/configuration/syntax.html#identifiers), but must be quoted
|
||||
otherwise. You can use a non-literal string expression as a key by wrapping it in
|
||||
parentheses, like `(var.business_unit_tag_name) = "SRE"`.
|
||||
|
||||
## Indices and Attributes
|
||||
|
||||
[inpage-index]: #indices-and-attributes
|
||||
|
||||
Elements of list/tuple and map/object values can be accessed using
|
||||
the square-bracket index notation, like `local.list[3]`. The expression within
|
||||
the brackets must be a whole number for list and tuple values or a string
|
||||
for map and object values.
|
||||
|
||||
Map/object attributes with names that are valid identifiers can also be accessed
|
||||
using the dot-separated attribute notation, like `local.object.attrname`.
|
||||
In cases where a map might contain arbitrary user-specified keys, we recommend
|
||||
using only the square-bracket index notation (`local.map["keyname"]`).
|
||||
|
||||
## More About Complex Types
|
||||
|
||||
In most situations, lists and tuples behave identically, as do maps and objects.
|
||||
Whenever the distinction isn't relevant, the Terraform documentation uses each
|
||||
pair of terms interchangeably (with a historical preference for "list" and
|
||||
"map").
|
||||
|
||||
However, module authors and provider developers should understand the
|
||||
differences between these similar types (and the related `set` type), since they
|
||||
offer different ways to restrict the allowed values for input variables and
|
||||
resource arguments.
|
||||
|
||||
For complete details about these types (and an explanation of why the difference
|
||||
usually doesn't matter), see [Type Constraints](/docs/configuration/types.html).
|
||||
|
||||
## Type Conversion
|
||||
|
||||
Expressions are most often used to set values for the arguments of resources and
|
||||
child modules. In these cases, the argument has an expected type and the given
|
||||
expression must produce a value of that type.
|
||||
|
||||
Where possible, Terraform automatically converts values from one type to
|
||||
another in order to produce the expected type. If this isn't possible, Terraform
|
||||
will produce a type mismatch error and you must update the configuration with a
|
||||
more suitable expression.
|
||||
|
||||
Terraform automatically converts number and bool values to strings when needed.
|
||||
It also converts strings to numbers or bools, as long as the string contains a
|
||||
valid representation of a number or bool value.
|
||||
|
||||
* `true` converts to `"true"`, and vice-versa
|
||||
* `false` converts to `"false"`, and vice-versa
|
||||
* `15` converts to `"15"`, and vice-versa
|
||||
|
|
@ -250,7 +250,39 @@
|
|||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions.html">Standard Expressions</a>
|
||||
<a href="/docs/configuration/expressions/types.html">Types and Values</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/strings.html">Strings and Templates</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/references.html">References to Values</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/operators.html">Operators</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/function-calls.html">Function Calls</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/conditionals.html">Conditional Expressions</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/for.html">For Expressions</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/splat.html">Splat Expressions</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/docs/configuration/expressions/dynamic-blocks.html">Dynamic Blocks</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
|
Loading…
Reference in New Issue