From a446ecb7b784f9aaf0cf639fd890eee185c02db2 Mon Sep 17 00:00:00 2001 From: Nick Fagerlund Date: Thu, 12 Nov 2020 18:01:48 -0800 Subject: [PATCH] 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. --- .../docs/configuration/expressions.html.md | 924 ++---------------- .../expressions/conditionals.html.md | 41 + .../expressions/dynamic-blocks.html.md | 95 ++ .../configuration/expressions/for.html.md | 71 ++ .../expressions/function-calls.html.md | 48 + .../configuration/expressions/index.html.md | 44 +- .../expressions/operators.html.md | 82 ++ .../expressions/references.html.md | 247 +++++ .../configuration/expressions/splat.html.md | 82 ++ .../configuration/expressions/strings.html.md | 208 ++++ .../configuration/expressions/types.html.md | 147 +++ website/layouts/language.erb | 34 +- 12 files changed, 1168 insertions(+), 855 deletions(-) create mode 100644 website/docs/configuration/expressions/conditionals.html.md create mode 100644 website/docs/configuration/expressions/dynamic-blocks.html.md create mode 100644 website/docs/configuration/expressions/for.html.md create mode 100644 website/docs/configuration/expressions/function-calls.html.md create mode 100644 website/docs/configuration/expressions/operators.html.md create mode 100644 website/docs/configuration/expressions/references.html.md create mode 100644 website/docs/configuration/expressions/splat.html.md create mode 100644 website/docs/configuration/expressions/strings.html.md create mode 100644 website/docs/configuration/expressions/types.html.md diff --git a/website/docs/configuration/expressions.html.md b/website/docs/configuration/expressions.html.md index c7f9a4000..560b5c014 100644 --- a/website/docs/configuration/expressions.html.md +++ b/website/docs/configuration/expressions.html.md @@ -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. + + + + + -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 + + + + + + -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 - ` = ` 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: - -* `.` 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.` is the value of the - [input variable](./variables.html) of the given name. -* `local.` is the value of the - [local value](./locals.html) of the given name. -* `module..` is the value of the specified - [output value](./outputs.html) from a - [child module](./modules.html) called by the current module. -* `data..` 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)`. + + + + ## 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. + + ## 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 -(, ) -``` +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). + ## `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). + + ## 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] -``` + + -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 -``` + + + + -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 <`/`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 in ` / `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 - <` 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). diff --git a/website/docs/configuration/expressions/function-calls.html.md b/website/docs/configuration/expressions/function-calls.html.md new file mode 100644 index 000000000..771b75f72 --- /dev/null +++ b/website/docs/configuration/expressions/function-calls.html.md @@ -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 +(, ) +``` + +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). + diff --git a/website/docs/configuration/expressions/index.html.md b/website/docs/configuration/expressions/index.html.md index 9bfb15e28..0de96564c 100644 --- a/website/docs/configuration/expressions/index.html.md +++ b/website/docs/configuration/expressions/index.html.md @@ -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 ` ? : ` 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. diff --git a/website/docs/configuration/expressions/operators.html.md b/website/docs/configuration/expressions/operators.html.md new file mode 100644 index 000000000..37906831c --- /dev/null +++ b/website/docs/configuration/expressions/operators.html.md @@ -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`. diff --git a/website/docs/configuration/expressions/references.html.md b/website/docs/configuration/expressions/references.html.md new file mode 100644 index 000000000..a1cb91781 --- /dev/null +++ b/website/docs/configuration/expressions/references.html.md @@ -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 + +`.` 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.` is the value of the [input variable](/docs/configuration/variables.html) of the given name. + +### Local Values + +`local.` is the value of the [local value](/docs/configuration/locals.html) of the given name. + +### Child Module Outputs + +* `module..` 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..` 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)`. diff --git a/website/docs/configuration/expressions/splat.html.md b/website/docs/configuration/expressions/splat.html.md new file mode 100644 index 000000000..d0fa27f08 --- /dev/null +++ b/website/docs/configuration/expressions/splat.html.md @@ -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. diff --git a/website/docs/configuration/expressions/strings.html.md b/website/docs/configuration/expressions/strings.html.md new file mode 100644 index 000000000..4841a39e7 --- /dev/null +++ b/website/docs/configuration/expressions/strings.html.md @@ -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 +<}`/`%{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 in }` / `%{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 + < = ` 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 + diff --git a/website/layouts/language.erb b/website/layouts/language.erb index 4f66e333f..d4c1fd054 100644 --- a/website/layouts/language.erb +++ b/website/layouts/language.erb @@ -250,7 +250,39 @@
  • - Standard Expressions + Types and Values +
  • + +
  • + Strings and Templates +
  • + +
  • + References to Values +
  • + +
  • + Operators +
  • + +
  • + Function Calls +
  • + +
  • + Conditional Expressions +
  • + +
  • + For Expressions +
  • + +
  • + Splat Expressions +
  • + +
  • + Dynamic Blocks