website/docs/language/expressions (#225)

Signed-off-by: Marcin Białoń <mbialon@spacelift.io>
This commit is contained in:
Marcin Białoń 2023-08-29 16:30:49 +02:00 committed by GitHub
parent 2752217411
commit 9ca1a27be2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 238 additions and 263 deletions

View File

@ -10,8 +10,6 @@ description: >-
A _conditional expression_ uses the value of a boolean expression to select one of
two values.
> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Syntax
The syntax of a conditional expression is as follows:
@ -45,20 +43,20 @@ You can create conditions that produce custom error messages for several types o
Custom conditions can help capture assumptions, helping future maintainers understand the configuration design and intent. They also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations.
Refer to [Custom Condition Checks](/terraform/language/expressions/custom-conditions#input-variable-validation) for details.
Refer to [Custom Condition Checks](/opentf/language/expressions/custom-conditions#input-variable-validation) for details.
## 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
be of the _same_ type so that OpenTF can determine what type the whole
conditional expression will return without knowing the condition value.
If the two result expressions don't produce the same type then Terraform will
If the two result expressions don't produce the same type then OpenTF will
attempt to find a type that they can both convert to, and make those
conversions automatically if so.
For example, the following expression is valid and will always return a string,
because in Terraform all numbers can convert automatically to a string using
because in OpenTF all numbers can convert automatically to a string using
decimal digits:
```hcl
@ -66,13 +64,13 @@ var.example ? 12 : "hello"
```
Relying on this automatic conversion behavior can be confusing for those who
are not familiar with Terraform's conversion rules though, so we recommend
are not familiar with OpenTF's conversion rules though, so we recommend
being explicit using type conversion functions in any situation where there may
be some uncertainty about the expected result type.
The following example is contrived because it would be easier to write the
constant `"12"` instead of the type conversion in this case, but shows how to
use [`tostring`](/terraform/language/functions/tostring) to explicitly convert a number to
use [`tostring`](/opentf/language/functions/tostring) to explicitly convert a number to
a string.
```hcl

View File

@ -8,32 +8,28 @@ description: >-
You can create conditions that produce custom error messages for several types of objects in a configuration. For example, you can add a condition to an input variable that checks whether incoming image IDs are formatted properly. Custom conditions can capture assumptions, helping future maintainers understand the configuration design and intent. They also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations.
> **Hands On:** Try the [Validate Infrastructure Using Checks](/terraform/tutorials/configuration-language/checks) tutorial to learn how to use `check` blocks. Try the [Validate Modules with Custom Conditions](/terraform/tutorials/configuration-language/custom-conditions) tutorial to learn how to use other custom conditions.
This page explains the following:
- Creating checks with [assertions](#checks-with-assertions) to verify your infrastructure as a whole (Terraform v1.5.0 and later)
- Creating [validation conditions](#input-variable-validation) for input variables (Terraform v0.13.0 and later)
- Creating [preconditions and postconditions](#preconditions-and-postconditions) for resources, data sources, and outputs (Terraform v1.2.0 and later)
- Creating checks with [assertions](#checks-with-assertions) to verify your infrastructure as a whole
- Creating [validation conditions](#input-variable-validation) for input variables
- Creating [preconditions and postconditions](#preconditions-and-postconditions) for resources, data sources, and outputs
- Writing effective [condition expressions](#condition-expressions) and [error messages](#error-messages)
- When Terraform [evaluates custom conditions](#conditions-checked-only-during-apply) during the plan and apply cycle
- When OpenTF [evaluates custom conditions](#conditions-checked-only-during-apply) during the plan and apply cycle
## Selecting a Custom Condition for your use case
Terraform's different custom conditions are best suited to various situations. Use the following broad guidelines to select the best custom condition for your use case:
1. [Check blocks with assertions](#checks-with-assertions) validate your infrastructure as a whole. Additionally, check blocks do not prevent or block the overall execution of Terraform operations.
OpenTF's different custom conditions are best suited to various situations. Use the following broad guidelines to select the best custom condition for your use case:
1. [Check blocks with assertions](#checks-with-assertions) validate your infrastructure as a whole. Additionally, check blocks do not prevent or block the overall execution of OpenTF operations.
1. [Validation conditions](#input-variable-validation) or [output postconditions](#preconditions-and-postconditions) can ensure your configuration's inputs and outputs meet specific requirements.
1. Resource [preconditions and postconditions](#preconditions-and-postconditions) can validate that Terraform produces your configuration with predictable results.
1. Resource [preconditions and postconditions](#preconditions-and-postconditions) can validate that OpenTF produces your configuration with predictable results.
For more information on when to use certain custom conditions, see [Choosing Between Preconditions and Postconditions](#choosing-between-preconditions-and-postconditions) and [Choosing Checks or Other Custom Conditions](/terraform/language/checks#choosing-checks-or-other-custom-conditions).
For more information on when to use certain custom conditions, see [Choosing Between Preconditions and Postconditions](#choosing-between-preconditions-and-postconditions) and [Choosing Checks or Other Custom Conditions](/opentf/language/checks#choosing-checks-or-other-custom-conditions).
## Input Variable Validation
-> **Note:** Input variable validation is available in Terraform v0.13.0 and later.
Add one or more `validation` blocks within the `variable` block to specify custom conditions. Each validation requires a [`condition` argument](#condition-expressions), an expression that must use the value of the variable to return `true` if the value is valid, or `false` if it is invalid. The expression can refer only to the containing variable and must not produce errors.
If the condition evaluates to `false`, Terraform produces an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple validations, Terraform returns error messages for all failed conditions.
If the condition evaluates to `false`, OpenTF produces an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple validations, OpenTF returns error messages for all failed conditions.
The following example checks whether the AMI ID has valid syntax.
@ -49,7 +45,7 @@ variable "image_id" {
}
```
If the failure of an expression determines the validation decision, use the [`can` function](/terraform/language/functions/can) as demonstrated in the following example.
If the failure of an expression determines the validation decision, use the [`can` function](/opentf/language/functions/can) as demonstrated in the following example.
```hcl
variable "image_id" {
@ -67,17 +63,15 @@ variable "image_id" {
## Preconditions and Postconditions
-> **Note:** Preconditions and postconditions are available in Terraform v1.2.0 and later.
Use `precondition` and `postcondition` blocks to create custom rules for resources, data sources, and outputs.
Terraform checks a precondition _before_ evaluating the object it is associated with and checks a postcondition _after_ evaluating the object. Terraform evaluates custom conditions as early as possible, but must defer conditions that depend on unknown values until the apply phase. Refer to [Conditions Checked Only During Apply](#conditions-checked-only-during-apply) for more details.
OpenTF checks a precondition _before_ evaluating the object it is associated with and checks a postcondition _after_ evaluating the object. OpenTF evaluates custom conditions as early as possible, but must defer conditions that depend on unknown values until the apply phase. Refer to [Conditions Checked Only During Apply](#conditions-checked-only-during-apply) for more details.
### Usage
Each precondition and postcondition requires a [`condition` argument](#condition-expressions). This is an expression that must return `true` if the conditition is fufilled or `false` if it is invalid. The expression can refer to any other objects in the same module, as long as the references do not create cyclic dependencies. Resource postconditions can also use the [`self` object](#self-object) to refer to attributes of each instance of the resource where they are configured.
If the condition evaluates to `false`, Terraform will produce an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple preconditions or postconditions, Terraform returns error messages for all failed conditions.
If the condition evaluates to `false`, OpenTF will produce an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple preconditions or postconditions, OpenTF returns error messages for all failed conditions.
The following example uses a postcondition to detect if the caller accidentally provided an AMI intended for the wrong system component.
@ -99,18 +93,18 @@ data "aws_ami" "example" {
The `lifecycle` block inside a `resource` or `data` block can include both `precondition` and `postcondition` blocks.
- Terraform evaluates `precondition` blocks after evaluating existing `count` and `for_each` arguments. This lets Terraform evaluate the precondition separately for each instance and then make `each.key`, `count.index`, etc. available to those conditions. Terraform also evaluates preconditions before evaluating the resource's configuration arguments. Preconditions can take precedence over argument evaluation errors.
- Terraform evaluates `postcondition` blocks after planning and applying changes to a managed resource, or after reading from a data source. Postcondition failures prevent changes to other resources that depend on the failing resource.
- OpenTF evaluates `precondition` blocks after evaluating existing `count` and `for_each` arguments. This lets OpenTF evaluate the precondition separately for each instance and then make `each.key`, `count.index`, etc. available to those conditions. OpenTF also evaluates preconditions before evaluating the resource's configuration arguments. Preconditions can take precedence over argument evaluation errors.
- OpenTF evaluates `postcondition` blocks after planning and applying changes to a managed resource, or after reading from a data source. Postcondition failures prevent changes to other resources that depend on the failing resource.
In most cases, we do not recommend including both a `data` block and a `resource` block that both represent the same object in the same configuration. Doing so can prevent Terraform from understanding that the `data` block result can be affected by changes in the `resource` block. However, when you need to check a result of a `resource` block that the resource itself does not directly export, you can use a `data` block to check that object safely as long as you place the check as a direct `postcondition` of the `data` block. This tells Terraform that the `data` block is serving as a check of an object defined elsewhere, allowing Terraform to perform actions in the correct order.
In most cases, we do not recommend including both a `data` block and a `resource` block that both represent the same object in the same configuration. Doing so can prevent OpenTF from understanding that the `data` block result can be affected by changes in the `resource` block. However, when you need to check a result of a `resource` block that the resource itself does not directly export, you can use a `data` block to check that object safely as long as you place the check as a direct `postcondition` of the `data` block. This tells OpenTF that the `data` block is serving as a check of an object defined elsewhere, allowing OpenTF to perform actions in the correct order.
#### Outputs
An `output` block can include a `precondition` block.
Preconditions can serve a symmetrical purpose to input variable `validation` blocks. Whereas input variable validation checks assumptions the module makes about its inputs, preconditions check guarantees that the module makes about its outputs. You can use preconditions to prevent Terraform from saving an invalid new output value in the state. You can also use them to preserve a valid output value from the previous apply, if applicable.
Preconditions can serve a symmetrical purpose to input variable `validation` blocks. Whereas input variable validation checks assumptions the module makes about its inputs, preconditions check guarantees that the module makes about its outputs. You can use preconditions to prevent OpenTF from saving an invalid new output value in the state. You can also use them to preserve a valid output value from the previous apply, if applicable.
Terraform evaluates output value preconditions before evaluating the `value` expression to finalize the result. Preconditions can take precedence over potential errors in the `value` expression.
OpenTF evaluates output value preconditions before evaluating the `value` expression to finalize the result. Preconditions can take precedence over potential errors in the `value` expression.
### Examples
@ -121,7 +115,7 @@ The following example shows use cases for preconditions and postconditions. The
- **The EC2 instance must be allocated a public DNS hostname.** In Amazon Web Services, EC2 instances are assigned public DNS hostnames only if they belong to a virtual network configured in a certain way. The postcondition would detect if the selected virtual network is not configured correctly, prompting the user to debug the network settings.
- **The EC2 instance will have an encrypted root volume.** The precondition ensures that the root volume is encrypted, even though the software running in this EC2 instance would probably still operate as expected on an unencrypted volume. This lets Terraform produce an error immediately, before any other components rely on the new EC2 instance.
- **The EC2 instance will have an encrypted root volume.** The precondition ensures that the root volume is encrypted, even though the software running in this EC2 instance would probably still operate as expected on an unencrypted volume. This lets OpenTF produce an error immediately, before any other components rely on the new EC2 instance.
```hcl
@ -168,7 +162,7 @@ data "aws_ebs_volume" "example" {
# Whenever a data resource is verifying the result of a managed resource
# declared in the same configuration, you MUST write the checks as
# postconditions of the data resource. This ensures Terraform will wait
# postconditions of the data resource. This ensures OpenTF will wait
# to read the data resource until after any changes to the managed resource
# have completed.
lifecycle {
@ -205,19 +199,17 @@ We recommend using postconditions for guarantees, so that future maintainers can
You should also consider the following questions when creating preconditions and postconditions.
- Which resource or output value would be most helpful to report in the error message? Terraform will always report errors in the location where the condition was declared.
- Which resource or output value would be most helpful to report in the error message? OpenTF will always report errors in the location where the condition was declared.
- Which approach is more convenient? If a particular resource has many dependencies that all make an assumption about that resource, it can be pragmatic to declare that once as a post-condition of the resource, rather than declaring it many times as preconditions on each of the dependencies.
- Is it helpful to declare the same or similar conditions as both preconditions and postconditions? This can be useful if the postcondition is in a different module than the precondition because it lets the modules verify one another as they evolve independently.
## Checks with Assertions
-> **Note:** Check blocks and their assertions are only available in Terraform v1.5.0 and later.
[Check blocks](/terraform/language/checks) can validate your infrastructure outside the usual resource lifecycle. You can add custom conditions via `assert` blocks, which execute at the end of the plan and apply stages and produce warnings to notify you of problems within your infrastructure.
[Check blocks](/opentf/language/checks) can validate your infrastructure outside the usual resource lifecycle. You can add custom conditions via `assert` blocks, which execute at the end of the plan and apply stages and produce warnings to notify you of problems within your infrastructure.
You can add one or more `assert` blocks within a `check` block to verify custom conditions. Each assertion requires a [`condition` argument](#condition-expressions), a boolean expression that should return `true` if the intended assumption or guarantee is fulfilled or `false` if it does not. Your `condition` expression can refer to any resource, data source, or variable available to the surrounding `check` block.
The following example uses a check block with an assertion to verify the Terraform website is healthy.
The following example uses a check block with an assertion to verify the OpenTF website is healthy.
```hcl
check "health_check" {
@ -232,17 +224,17 @@ check "health_check" {
}
```
If the condition evaluates to `false`, Terraform produces an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple assertions, Terraform returns error messages for all failed conditions.
If the condition evaluates to `false`, OpenTF produces an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple assertions, OpenTF returns error messages for all failed conditions.
### Continuous Validation in Terraform Cloud
### Continuous Validation in a cloud backend
Terraform Cloud can automatically check whether the checks in a workspaces configuration continue to pass after Terraform provisions the infrastructure. For example, you can write a `check` to continuously monitor the validity of an API gateway certificate. Continuous validation alerts you when the condition fails, so you can update the certificate and avoid errors the next time you want to update your infrastructure. Refer to [Continuous Validation](/terraform/cloud-docs/workspaces/health#continuous-validation) in the Terraform Cloud documentation for details.
A cloud backend can automatically check whether the checks in a workspaces configuration continue to pass after OpenTF provisions the infrastructure. For example, you can write a `check` to continuously monitor the validity of an API gateway certificate. Continuous validation alerts you when the condition fails, so you can update the certificate and avoid errors the next time you want to update your infrastructure.
## Condition Expressions
Check assertions, input variable validation, preconditions, and postconditions all require a `condition` argument. This is a boolean expression that should return `true` if the intended assumption or guarantee is fulfilled or `false` if it does not.
You can use any of Terraform's built-in functions or language operators
You can use any of OpenTF's built-in functions or language operators
in a condition as long as the expression is valid and returns a boolean result. The following language features are particularly useful when writing condition expressions.
### Logical Operators
@ -253,11 +245,11 @@ Use the logical operators `&&` (AND), `||` (OR), and `!` (NOT) to combine multip
condition = var.name != "" && lower(var.name) == var.name
```
You can also use arithmetic operators (e.g. `a + b`), equality operators (eg., `a == b`) and comparison operators (e.g., `a < b`). Refer to [Arithmetic and Logical Operators](/terraform/language/expressions/operators) for details.
You can also use arithmetic operators (e.g. `a + b`), equality operators (eg., `a == b`) and comparison operators (e.g., `a < b`). Refer to [Arithmetic and Logical Operators](/opentf/language/expressions/operators) for details.
### `contains` Function
Use the [`contains` function](/terraform/language/functions/contains) to test whether a given value is one of a set of predefined valid values.
Use the [`contains` function](/opentf/language/functions/contains) to test whether a given value is one of a set of predefined valid values.
```hcl
condition = contains(["STAGE", "PROD"], var.environment)
@ -265,7 +257,7 @@ Use the [`contains` function](/terraform/language/functions/contains) to test wh
### `length` Function
Use the [`length` function](/terraform/language/functions/length) to test a collection's length and require a non-empty list or map.
Use the [`length` function](/opentf/language/functions/length) to test a collection's length and require a non-empty list or map.
```hcl
condition = length(var.items) != 0
@ -274,7 +266,7 @@ This is a better approach than directly comparing with another collection using
### `for` Expressions
Use [`for` expressions](/terraform/language/expressions/for) in conjunction with the functions `alltrue` and `anytrue` to test whether a condition holds for all or for any elements of a collection.
Use [`for` expressions](/opentf/language/expressions/for) in conjunction with the functions `alltrue` and `anytrue` to test whether a condition holds for all or for any elements of a collection.
```hcl
condition = alltrue([
@ -284,7 +276,7 @@ Use [`for` expressions](/terraform/language/expressions/for) in conjunction with
### `can` Function
Use the [`can` function](/terraform/language/functions/can) to concisely use the validity of an expression as a condition. It returns `true` if its given expression evaluates successfully and `false` if it returns any error, so you can use various other functions that typically return errors as a part of your condition expressions.
Use the [`can` function](/opentf/language/functions/can) to concisely use the validity of an expression as a condition. It returns `true` if its given expression evaluates successfully and `false` if it returns any error, so you can use various other functions that typically return errors as a part of your condition expressions.
For example, you can use `can` with `regex` to test if a string matches a particular pattern because `regex` returns an error when given a non-matching string.
@ -342,7 +334,7 @@ resource "aws_instance" "example" {
### `each` and `count` Objects
In blocks where [`for_each`](/terraform/language/meta-arguments/for_each) or [`count`](/terraform/language/meta-arguments/count) are set, use `each` and `count` objects to refer to other resources that are expanded in a chain.
In blocks where [`for_each`](/opentf/language/meta-arguments/for_each) or [`count`](/opentf/language/meta-arguments/count) are set, use `each` and `count` objects to refer to other resources that are expanded in a chain.
```hcl
variable "vpc_cidrs" {
@ -373,7 +365,7 @@ resource "aws_internet_gateway" "example" {
## Error Messages
Input variable validations, preconditions, and postconditions all must include the `error_message` argument. This contains the text that Terraform will include as part of error messages when it detects an unmet condition.
Input variable validations, preconditions, and postconditions all must include the `error_message` argument. This contains the text that OpenTF will include as part of error messages when it detects an unmet condition.
```
Error: Resource postcondition failed
@ -388,27 +380,26 @@ The selected AMI must be tagged with the Component value "nomad-server".
```
The `error_message` argument can be any expression that evaluates to a string.
This includes literal strings, heredocs, and template expressions. You can use the [`format` function](/terraform/language/functions/format) to convert items of `null`, `list`, or `map` types into a formatted string. Multi-line
This includes literal strings, heredocs, and template expressions. You can use the [`format` function](/opentf/language/functions/format) to convert items of `null`, `list`, or `map` types into a formatted string. Multi-line
error messages are supported, and lines with leading whitespace will not be
word wrapped.
We recommend writing error messages as one or more full sentences in a
style similar to Terraform's own error messages. Terraform will show the
style similar to OpenTF's own error messages. OpenTF will show the
message alongside the name of the resource that detected the problem and any
external values included in the condition expression.
## Conditions Checked Only During Apply
Terraform evaluates custom conditions as early as possible.
OpenTF evaluates custom conditions as early as possible.
Input variable validations can only refer to the variable value, so Terraform always evaluates them immediately. Check assertions, preconditions, and postconditions depend on Terraform evaluating whether the value(s) associated with the condition are known before or after applying the configuration.
Input variable validations can only refer to the variable value, so OpenTF always evaluates them immediately. Check assertions, preconditions, and postconditions depend on OpenTF evaluating whether the value(s) associated with the condition are known before or after applying the configuration.
- **Known before apply:** Terraform checks the condition during the planning phase. For example, Terraform can know the value of an image ID during planning as long as it is not generated from another resource.
- **Known after apply:** Terraform delays checking that condition until the apply phase. For example, AWS only assigns the root volume ID when it starts an EC2 instance, so Terraform cannot know this value until apply.
- **Known before apply:** OpenTF checks the condition during the planning phase. For example, OpenTF can know the value of an image ID during planning as long as it is not generated from another resource.
- **Known after apply:** OpenTF delays checking that condition until the apply phase. For example, AWS only assigns the root volume ID when it starts an EC2 instance, so OpenTF cannot know this value until apply.
During the apply phase, a failed _precondition_
will prevent Terraform from implementing planned actions for the associated resource. However, a failed _postcondition_ will halt processing after Terraform has already implemented these actions. The failed postcondition prevents any further downstream actions that rely on the resource, but does not undo the actions Terraform has already taken.
Terraform typically has less information during the initial creation of a
full configuration than when applying subsequent changes. Therefore, Terraform may check conditions during apply for initial creation and then check them during planning for subsequent updates.
will prevent OpenTF from implementing planned actions for the associated resource. However, a failed _postcondition_ will halt processing after OpenTF has already implemented these actions. The failed postcondition prevents any further downstream actions that rely on the resource, but does not undo the actions OpenTF has already taken.
OpenTF typically has less information during the initial creation of a
full configuration than when applying subsequent changes. Therefore, OpenTF may check conditions during apply for initial creation and then check them during planning for subsequent updates.

View File

@ -44,7 +44,7 @@ resource "aws_elastic_beanstalk_environment" "tfenvtest" {
}
```
A `dynamic` block acts much like a [`for` expression](/terraform/language/expressions/for), but produces
A `dynamic` block acts much like a [`for` expression](/opentf/language/expressions/for), 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.
@ -76,17 +76,17 @@ The iterator object (`setting` in the example above) has two attributes:
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
blocks, since OpenTF must process these before it is safe to evaluate
expressions.
The `for_each` value must be a collection 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.
can use OpenTF expressions and functions to derive a suitable value.
For some common examples of such situations, see the
[`flatten`](/terraform/language/functions/flatten)
[`flatten`](/opentf/language/functions/flatten)
and
[`setproduct`](/terraform/language/functions/setproduct)
[`setproduct`](/opentf/language/functions/setproduct)
functions.
## Multi-level Nested Block Structures
@ -110,7 +110,7 @@ variable "load_balancer_origin_groups" {
If you were defining a resource whose type expects a block for each origin
group and then nested blocks for each origin within a group, you could ask
Terraform to generate that dynamically using the following nested `dynamic`
OpenTF to generate that dynamically using the following nested `dynamic`
blocks:
```hcl
@ -151,5 +151,5 @@ nested blocks using directly-corresponding attributes from an input variable
then that might suggest that your module is not creating a useful abstraction.
It may be better for the calling module to define the resource itself then
pass information about it into your module. For more information on this design
tradeoff, see [When to Write a Module](/terraform/language/modules/develop#when-to-write-a-module)
and [Module Composition](/terraform/language/modules/develop/composition).
tradeoff, see [When to Write a Module](/opentf/language/modules/develop#when-to-write-a-module)
and [Module Composition](/opentf/language/modules/develop/composition).

View File

@ -77,7 +77,7 @@ For example, the resulting value might be as follows:
```
A `for` expression alone can only produce either an object value or a tuple
value, but Terraform's automatic type conversion rules mean that you can
value, but OpenTF's automatic type conversion rules mean that you can
typically use the results in locations where lists, maps, and sets are expected.
## Filtering Elements
@ -118,16 +118,16 @@ locals {
## Element Ordering
Because `for` expressions can convert from unordered types (maps, objects, sets)
to ordered types (lists, tuples), Terraform must choose an implied ordering
to ordered types (lists, tuples), OpenTF must choose an implied ordering
for the elements of an unordered collection.
For maps and objects, Terraform sorts the elements by key or attribute name,
For maps and objects, OpenTF sorts the elements by key or attribute name,
using lexical sorting.
For sets of strings, Terraform sorts the elements by their value, using
For sets of strings, OpenTF sorts the elements by their value, using
lexical sorting.
For sets of other types, Terraform uses an arbitrary ordering that may change in future versions. We recommend converting the expression result into a set to make it clear elsewhere in the configuration that the result is unordered. You can use [the `toset` function](/terraform/language/functions/toset)
For sets of other types, OpenTF uses an arbitrary ordering that may change in future versions. We recommend converting the expression result into a set to make it clear elsewhere in the configuration that the result is unordered. You can use [the `toset` function](/opentf/language/functions/toset)
to concisely convert a `for` expression result to be of a set type.
```hcl
@ -138,10 +138,10 @@ toset([for e in var.set : e.example])
If the result type is an object (using `{` and `}` delimiters) then normally
the given key expression must be unique across all elements in the result,
or Terraform will return an error.
or OpenTF will return an error.
Sometimes the resulting keys are _not_ unique, and so to support that situation
Terraform supports a special _grouping mode_ which changes the result to support
OpenTF supports a special _grouping mode_ which changes the result to support
multiple elements per key.
To activate grouping mode, add the symbol `...` after the value expression.
@ -189,7 +189,7 @@ map of lists of strings, such as the following:
}
```
Due to [the element ordering rules](#element-ordering), Terraform will sort
Due to [the element ordering rules](#element-ordering), OpenTF will sort
the users lexically by username as part of evaluating the `for` expression,
and so the usernames associated with each role will be lexically sorted
after grouping.
@ -204,4 +204,4 @@ Some resource types also define _nested block types_, which typically represent
separate objects that belong to the containing resource in some way. You can't
dynamically generate nested blocks using `for` expressions, but you _can_
generate nested blocks for a resource dynamically using
[`dynamic` blocks](/terraform/language/expressions/dynamic-blocks).
[`dynamic` blocks](/opentf/language/expressions/dynamic-blocks).

View File

@ -1,16 +1,14 @@
---
page_title: Function Calls - Configuration Language
description: >-
Functions transform and combine values. Learn about Terraform's built-in
Functions transform and combine values. Learn about OpenTF's built-in
functions.
---
# Function Calls
> **Hands-on:** Try the [Perform Dynamic Operations with Functions](/terraform/tutorials/configuration-language/functions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
The Terraform language has a number of
[built-in functions](/terraform/language/functions) that can be used
The OpenTF language has a number of
[built-in functions](/opentf/language/functions) that can be used
in expressions to transform and combine values. These
are similar to the operators but all follow a common syntax:
@ -35,7 +33,7 @@ A function call expression evaluates to the function's return value.
## Available Functions
For a full list of available functions, see
[the function reference](/terraform/language/functions).
[the function reference](/opentf/language/functions).
## Expanding Function Arguments
@ -52,8 +50,8 @@ The expansion symbol is three periods (`...`), not a Unicode ellipsis character
## Using Sensitive Data as Function Arguments
When using sensitive data, such as [an input variable](/terraform/language/values/variables#suppressing-values-in-cli-output)
or [an output defined](/terraform/language/values/outputs#sensitive-suppressing-values-in-cli-output) as sensitive
When using sensitive data, such as [an input variable](/opentf/language/values/variables#suppressing-values-in-cli-output)
or [an output defined](/opentf/language/values/outputs#sensitive-suppressing-values-in-cli-output) as sensitive
as function arguments, the result of the function call will be marked as sensitive.
This is a conservative behavior that is true irrespective of the function being
@ -70,45 +68,45 @@ the `keys()` function will result in a list that is sensitive:
(sensitive value)
```
## When Terraform Calls Functions
## When OpenTF Calls Functions
Most of Terraform's built-in functions are, in programming language terms,
Most of OpenTF's built-in functions are, in programming language terms,
[pure functions](https://en.wikipedia.org/wiki/Pure_function). This means that
their result is based only on their arguments and so it doesn't make any
practical difference when Terraform would call them.
practical difference when OpenTF would call them.
However, a small subset of functions interact with outside state and so for
those it can be helpful to know when Terraform will call them in relation to
other events that occur in a Terraform run.
those it can be helpful to know when OpenTF will call them in relation to
other events that occur in a OpenTF run.
The small set of special functions includes
[`file`](/terraform/language/functions/file),
[`templatefile`](/terraform/language/functions/templatefile),
[`timestamp`](/terraform/language/functions/timestamp),
and [`uuid`](/terraform/language/functions/uuid).
[`file`](/opentf/language/functions/file),
[`templatefile`](/opentf/language/functions/templatefile),
[`timestamp`](/opentf/language/functions/timestamp),
and [`uuid`](/opentf/language/functions/uuid).
If you are not working with these functions then you don't need
to read this section, although the information here may still be interesting
background information.
The `file` and `templatefile` functions are intended for reading files that
are included as a static part of the configuration and so Terraform will
are included as a static part of the configuration and so OpenTF will
execute these functions as part of initial configuration validation, before
taking any other actions with the configuration. That means you cannot use
either function to read files that your configuration might generate
dynamically on disk as part of the plan or apply steps.
The `timestamp` function returns a representation of the current system time
at the point when Terraform calls it, and the `uuid` function returns a random
at the point when OpenTF calls it, and the `uuid` function returns a random
result which differs on each call. Without any special behavior, these would
both cause the final configuration during the apply step not to match the
actions shown in the plan, which violates the Terraform execution model.
actions shown in the plan, which violates the OpenTF execution model.
For that reason, Terraform arranges for both of those functions to produce
[unknown value](/terraform/language/expressions/references#values-not-yet-known) results during the
For that reason, OpenTF arranges for both of those functions to produce
[unknown value](/opentf/language/expressions/references#values-not-yet-known) results during the
plan step, with the real result being decided only during the apply step.
For `timestamp` in particular, this means that the recorded time will be
the instant when Terraform began applying the change, rather than when
Terraform _planned_ the change.
the instant when OpenTF began applying the change, rather than when
OpenTF _planned_ the change.
For more details on the behavior of these functions, refer to their own
documentation pages.

View File

@ -1,71 +1,69 @@
---
page_title: Expressions - Configuration Language
description: >-
An overview of expressions to reference or compute values in Terraform
An overview of expressions to reference or compute values in OpenTF
configurations, including types, operators, and functions.
---
# Expressions
> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
_Expressions_ 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
but the OpenTF 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,
Expressions can be used in a number of places in the OpenTF 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](/terraform/language/expressions/references#references-to-resource-attributes).
[references to resource attributes](/opentf/language/expressions/references#references-to-resource-attributes).
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
[the `terraform console` command](/terraform/cli/commands/console).
You can experiment with the behavior of OpenTF's expressions from
the OpenTF expression console, by running
[the `opentf console` command](/opentf/cli/commands/console).
The other pages in this section describe the features of Terraform's
The other pages in this section describe the features of OpenTF's
expression syntax.
- [Types and Values](/terraform/language/expressions/types)
documents the data types that Terraform expressions can resolve to, and the
- [Types and Values](/opentf/language/expressions/types)
documents the data types that OpenTF expressions can resolve to, and the
literal syntaxes for values of those types.
- [Strings and Templates](/terraform/language/expressions/strings)
- [Strings and Templates](/opentf/language/expressions/strings)
documents the syntaxes for string literals, including interpolation sequences
and template directives.
- [References to Values](/terraform/language/expressions/references)
- [References to Values](/opentf/language/expressions/references)
documents how to refer to named values like variables and resource attributes.
- [Operators](/terraform/language/expressions/operators)
- [Operators](/opentf/language/expressions/operators)
documents the arithmetic, comparison, and logical operators.
- [Function Calls](/terraform/language/expressions/function-calls)
documents the syntax for calling Terraform's built-in functions.
- [Function Calls](/opentf/language/expressions/function-calls)
documents the syntax for calling OpenTF's built-in functions.
- [Conditional Expressions](/terraform/language/expressions/conditionals)
- [Conditional Expressions](/opentf/language/expressions/conditionals)
documents the `<CONDITION> ? <TRUE VAL> : <FALSE VAL>` expression, which
chooses between two values based on a bool condition.
- [For Expressions](/terraform/language/expressions/for)
- [For Expressions](/opentf/language/expressions/for)
documents expressions like `[for s in var.list : upper(s)]`, which can
transform a complex type value into another complex type value.
- [Splat Expressions](/terraform/language/expressions/splat)
- [Splat Expressions](/opentf/language/expressions/splat)
documents expressions like `var.list[*].id`, which can extract simpler
collections from more complicated expressions.
- [Dynamic Blocks](/terraform/language/expressions/dynamic-blocks)
- [Dynamic Blocks](/opentf/language/expressions/dynamic-blocks)
documents a way to create multiple repeatable nested blocks within a resource
or other construct.
- [Type Constraints](/terraform/language/expressions/type-constraints)
- [Type Constraints](/opentf/language/expressions/type-constraints)
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](/terraform/language/expressions/version-constraints)
- [Version Constraints](/opentf/language/expressions/version-constraints)
documents the syntax of special strings that define a set of allowed software
versions. Terraform uses version constraints in several places.
versions. OpenTF uses version constraints in several places.

View File

@ -17,7 +17,7 @@ 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,
The OpenTF language has a set of operators for both arithmetic and logic,
which are similar to operators in programming languages such as JavaScript
or Ruby.
@ -33,12 +33,12 @@ in the following order of operations:
1. `||`
Use parentheses to override the default order of operations. Without
parentheses, higher levels will be evaluated first, so Terraform will interpret
parentheses, higher levels will be evaluated first, so OpenTF will interpret
`1 + 2 * 3` 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
given values to be of a particular type. OpenTF will attempt to convert
values to the required type automatically, or will produce an error message
if automatic conversion is impossible.
@ -55,10 +55,10 @@ as results:
generally useful only when used with whole numbers.
* `-a` returns the result of multiplying `a` by `-1`.
Terraform supports some other less-common numeric operations as
[functions](/terraform/language/expressions/function-calls). For example, you can calculate exponents
OpenTF supports some other less-common numeric operations as
[functions](/opentf/language/expressions/function-calls). For example, you can calculate exponents
using
[the `pow` function](/terraform/language/functions/pow).
[the `pow` function](/opentf/language/functions/pow).
## Equality Operators
@ -100,8 +100,8 @@ The logical operators all expect bool values and produce bool values as results.
* `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`.
Terraform does not have an operator for the "exclusive OR" operation. If you
OpenTF does not have an operator for the "exclusive OR" operation. If you
know that both operators are boolean values then exclusive OR is equivalent
to the `!=` ("not equal") operator.
The logical operators in Terraform do not short-circuit, meaning `var.foo || var.foo.bar` will produce an error message if `var.foo` is `null` because both `var.foo` and `var.foo.bar` are evaluated.
The logical operators in OpenTF do not short-circuit, meaning `var.foo || var.foo.bar` will produce an error message if `var.foo` is `null` because both `var.foo` and `var.foo.bar` are evaluated.

View File

@ -8,16 +8,14 @@ description: >-
# References to Named Values
> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
Terraform makes several kinds of named values available. Each of these names is
OpenTF 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:
The main kinds of named values available in OpenTF are:
* Resources
* Input variables
@ -30,7 +28,7 @@ The main kinds of named values available in Terraform are:
The sections below explain each kind of named value in detail.
Although many of these names use dot-separated paths that resemble
[attribute notation](/terraform/language/expressions/types#indices-and-attributes) for elements of object values, they are not
[attribute notation](/opentf/language/expressions/types#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
@ -39,7 +37,7 @@ instance resource.
### Resources
`<RESOURCE TYPE>.<NAME>` represents a [managed resource](/terraform/language/resources) of
`<RESOURCE TYPE>.<NAME>` represents a [managed resource](/opentf/language/resources) of
the given type and name.
The value of a resource reference can vary, depending on whether the resource
@ -47,24 +45,24 @@ 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](/terraform/language/expressions/types#indices-and-attributes).
access them using [dot or square bracket notation](/opentf/language/expressions/types#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.
will be interpreted by OpenTF 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](/terraform/language/values/variables) of the given name.
`var.<NAME>` is the value of the [input variable](/opentf/language/values/variables) of the given name.
If the variable has a type constraint (`type` argument) as part of its
declaration, Terraform will automatically convert the caller's given value
declaration, OpenTF will automatically convert the caller's given value
to conform to the type constraint.
For that reason, you can safely assume that a reference using `var.` will
@ -79,7 +77,7 @@ constraint all of the attributes you intend to use elsewhere in your module.
### Local Values
`local.<NAME>` is the value of the [local value](/terraform/language/values/locals) of the given name.
`local.<NAME>` is the value of the [local value](/opentf/language/values/locals) of the given name.
Local values can refer to other local values, even within the same `locals`
block, as long as you don't introduce circular dependencies.
@ -87,12 +85,12 @@ block, as long as you don't introduce circular dependencies.
### Child Module Outputs
`module.<MODULE NAME>` is an value representing the results of
[a `module` block](/terraform/language/modules/syntax).
[a `module` block](/opentf/language/modules/syntax).
If the corresponding `module` block does not have either `count` nor `for_each`
set then the value will be an object with one attribute for each output value
defined in the child module. To access one of the module's
[output values](/terraform/language/values/outputs), use `module.<MODULE NAME>.<OUTPUT NAME>`.
[output values](/opentf/language/values/outputs), use `module.<MODULE NAME>.<OUTPUT NAME>`.
If the corresponding `module` uses `for_each` then the value will be a map
of objects whose keys correspond with the keys in the `for_each` expression,
@ -106,7 +104,7 @@ elements, each one representing one module instance.
### Data Sources
`data.<DATA TYPE>.<NAME>` is an object representing a
[data resource](/terraform/language/data-sources) of the given data
[data resource](/opentf/language/data-sources) 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.
@ -128,13 +126,13 @@ The following values are available:
unexpected results.
- `path.root` is the filesystem path of the root module of the configuration.
- `path.cwd` is the filesystem path of the original working directory from where you
ran Terraform before applying any `-chdir` argument. This path is an absolute path
ran OpenTF before applying any `-chdir` argument. This path is an absolute path
that includes details about the filesystem structure. It is also useful in some
advanced cases where Terraform is run from a directory other than the root module
advanced cases where OpenTF is run from a directory other than the root module
directory. We recommend using `path.root` or `path.module` over `path.cwd` where
possible.
- `terraform.workspace` is the name of the currently selected
[workspace](/terraform/language/state/workspaces).
- `opentf.workspace` is the name of the currently selected
[workspace](/opentf/language/state/workspaces).
Use the values in this section carefully, because they include information
about the context in which a configuration is being applied and so may
@ -147,7 +145,7 @@ the provider to consider the change of path to be a change to be applied, even
if the path still refers to the same file.
Similarly, if you use any of these values as a form of namespacing in a shared
module, such as using `terraform.workspace` as a prefix for globally-unique
module, such as using `opentf.workspace` as a prefix for globally-unique
object names, it may not be possible to call your module more than once in
the same configuration.
@ -155,14 +153,14 @@ Aside from `path.module`, we recommend using the values in this section only
in the root module of your configuration. If you are writing a shared module
which needs a prefix to help create unique names, define an input variable
for your module and allow the calling module to define the prefix. The
calling module can then use `terraform.workspace` to define it if appropriate,
calling module can then use `opentf.workspace` to define it if appropriate,
or some other value if not:
```hcl
module "example" {
# ...
name_prefix = "app-${terraform.workspace}"
name_prefix = "app-${opentf.workspace}"
}
```
@ -174,19 +172,19 @@ 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](/terraform/language/meta-arguments/count).
[the `count` meta-argument](/opentf/language/meta-arguments/count).
* `each.key` / `each.value`, in resources that use
[the `for_each` meta-argument](/terraform/language/meta-arguments/for_each).
* `self`, in [provisioner](/terraform/language/resources/provisioners/syntax) and
[connection](/terraform/language/resources/provisioners/connection) blocks.
[the `for_each` meta-argument](/opentf/language/meta-arguments/for_each).
* `self`, in [provisioner](/opentf/language/resources/provisioners/syntax) and
[connection](/opentf/language/resources/provisioners/connection) blocks.
-> **Note:** Local names are often referred to as _variables_ or
_temporary variables_ in their documentation. These are not [input
variables](/terraform/language/values/variables); they are just arbitrary names
variables](/opentf/language/values/variables); they are just arbitrary names
that temporarily represent a value.
The names in this section relate to top-level configuration blocks only.
If you use [`dynamic` blocks](/terraform/language/expressions/dynamic-blocks) to dynamically generate
If you use [`dynamic` blocks](/opentf/language/expressions/dynamic-blocks) to dynamically generate
resource-type-specific _nested_ blocks within `resource` and `data` blocks then
you'll refer to the key and value of each element differently. See the
`dynamic` blocks documentation for details.
@ -194,7 +192,7 @@ you'll refer to the key and value of each element differently. See the
## 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
in their block bodies, and OpenTF 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.
@ -235,7 +233,7 @@ for use in references, as follows:
* 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](/terraform/language/expressions/splat). For example, to obtain a list of
a [splat expression](/opentf/language/expressions/splat). 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
@ -261,24 +259,24 @@ for use in references, as follows:
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](/terraform/language/expressions/for):
block types, use a [`for` expression](/opentf/language/expressions/for):
`{for k, device in aws_instance.example.device : k => device.size}`.
When a resource has the
[`count`](/terraform/language/meta-arguments/count)
[`count`](/opentf/language/meta-arguments/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](/terraform/language/expressions/splat) or index syntax:
either [splat expressions](/opentf/language/expressions/splat) 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`](/terraform/language/meta-arguments/for_each)
[`for_each`](/opentf/language/meta-arguments/for_each)
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](/terraform/language/expressions/for).
be accessed using a [`for` expression](/opentf/language/expressions/for).
* `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
@ -291,43 +289,37 @@ Note that unlike `count`, splat expressions are _not_ directly applicable to res
### Sensitive Resource Attributes
When defining the schema for a resource type, a provider developer can mark
certain attributes as _sensitive_, in which case Terraform will show a
certain attributes as _sensitive_, in which case OpenTF will show a
placeholder marker `(sensitive value)` instead of the actual value when rendering
a plan involving that attribute.
A provider attribute marked as sensitive behaves similarly to an
[an input variable declared as sensitive](/terraform/language/values/variables#suppressing-values-in-cli-output),
where Terraform will hide the value in the plan and apply messages and will
[an input variable declared as sensitive](/opentf/language/values/variables#suppressing-values-in-cli-output),
where OpenTF will hide the value in the plan and apply messages and will
also hide any other values you derive from it as sensitive.
However, there are some limitations to that behavior as described in
[Cases where Terraform may disclose a sensitive variable](/terraform/language/values/variables#cases-where-terraform-may-disclose-a-sensitive-variable).
[Cases where OpenTF may disclose a sensitive variable](/opentf/language/values/variables#cases-where-opentf-may-disclose-a-sensitive-variable).
If you use a sensitive value from a resource attribute as part of an
[output value](/terraform/language/values/outputs) then Terraform will require
[output value](/opentf/language/values/outputs) then OpenTF will require
you to also mark the output value itself as sensitive, to confirm that you
intended to export it.
Terraform will still record sensitive values in the [state](/terraform/language/state),
OpenTF will still record sensitive values in the [state](/opentf/language/state),
and so anyone who can access the state data will have access to the sensitive
values in cleartext. For more information, see
[_Sensitive Data in State_](/terraform/language/state/sensitive-data).
-> **Note:** Treating values derived from a sensitive resource attribute as
sensitive themselves was introduced in Terraform v0.15. Earlier versions of
Terraform will obscure the direct value of a sensitive resource attribute,
but will _not_ automatically obscure other values derived from sensitive
resource attributes.
[_Sensitive Data in State_](/opentf/language/state/sensitive-data).
### Values Not Yet Known
When Terraform is planning a set of changes that will apply your configuration,
When OpenTF 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.
OpenTF cannot predict the value of this id until the object has been created.
Terraform uses special unknown value placeholders for information that it
cannot predict during the plan phase. The Terraform language automatically
OpenTF uses special unknown value placeholders for information that it
cannot predict during the plan phase. The OpenTF language automatically
handles unknown values in expressions. For example, adding a known value to an
unknown value automatically produces an unknown value as a result.
@ -351,8 +343,8 @@ effect:
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
* OpenTF 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 `(known after apply)`.
Unknown values appear in the `opentf plan` output as `(known after apply)`.

View File

@ -7,8 +7,6 @@ description: >-
# Splat Expressions
> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
A _splat expression_ provides a more concise way to express a common
operation that could otherwise be performed with a `for` expression.
@ -45,12 +43,12 @@ The above expression is equivalent to the following `for` expression:
The splat expression patterns shown above apply only to lists, sets, and
tuples. To get a similar result with a map or object value you must use
[`for` expressions](/terraform/language/expressions/for).
[`for` expressions](/opentf/language/expressions/for).
Resources that use the `for_each` argument will appear in expressions as a map
of objects, so you can't use splat expressions with those resources.
For more information, see
[Referring to Resource Instances](/terraform/language/meta-arguments/for_each#referring-to-instances).
[Referring to Resource Instances](/opentf/language/meta-arguments/for_each#referring-to-instances).
## Single Values as Lists
@ -63,7 +61,7 @@ tuple value. If the value is _null_ then the splat expression will return an
empty tuple.
This special behavior can be useful for modules that accept optional input
variables whose default value is `null` to represent the absence of any value. This allows the module to adapt the variable value for Terraform language features designed to work with collections. For example:
variables whose default value is `null` to represent the absence of any value. This allows the module to adapt the variable value for OpenTF language features designed to work with collections. For example:
```
variable "website_setting" {
@ -87,7 +85,7 @@ resource "aws_s3_bucket" "example" {
}
```
The above example uses a [`dynamic` block](/terraform/language/expressions/dynamic-blocks), which
The above example uses a [`dynamic` block](/opentf/language/expressions/dynamic-blocks), which
generates zero or more nested blocks based on a collection value. The input
variable `var.website_setting` is defined as a single object that might be null,
so the `dynamic` block's `for_each` expression uses `[*]` to ensure that
@ -101,8 +99,8 @@ the meaning of the expression may be unclear to future readers.
## Legacy (Attribute-only) Splat Expressions
Earlier versions of the Terraform language had a slightly different version
of splat expressions, which Terraform continues to support for backward
Earlier versions of the OpenTF language had a slightly different version
of splat expressions, which OpenTF continues to support for backward
compatibility. This older variant is less useful than the modern form described
above, and so we recommend against using it in new configurations.
@ -124,5 +122,5 @@ 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. Only the attribute lookups apply to each element of
the input. This limitation was confusing some people using older versions of
Terraform and so we recommend always using the new-style splat expressions,
OpenTF and so we recommend always using the new-style splat expressions,
with `[*]`, to get the more consistent behavior.

View File

@ -8,9 +8,9 @@ description: >-
# Strings and Templates
String literals are the most complex kind of literal expression in
Terraform, and also the most commonly used.
OpenTF, and also the most commonly used.
Terraform supports both a quoted syntax and a "heredoc" syntax for strings.
OpenTF supports both a quoted syntax and a "heredoc" syntax for strings.
Both of these syntaxes support template sequences for interpolating values and
manipulating text.
@ -47,7 +47,7 @@ There are also two special escape sequences that do not use backslashes:
## Heredoc Strings
Terraform also supports a "heredoc" style of string literal inspired by Unix
OpenTF also supports a "heredoc" style of string literal inspired by Unix
shell languages, which allows multi-line strings to be expressed more clearly.
```hcl
@ -67,7 +67,7 @@ A heredoc string consists of:
- 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
sequence. OpenTF 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
@ -77,8 +77,8 @@ allowed, but conventionally this identifier is in all-uppercase and begins with
### Generating JSON or YAML
Don't use "heredoc" strings to generate JSON or YAML. Instead, use
[the `jsonencode` function](/terraform/language/functions/jsonencode) or
[the `yamlencode` function](/terraform/language/functions/yamlencode) so that Terraform
[the `jsonencode` function](/opentf/language/functions/jsonencode) or
[the `yamlencode` function](/opentf/language/functions/yamlencode) so that OpenTF
can be responsible for guaranteeing valid JSON or YAML syntax.
```hcl
@ -104,7 +104,7 @@ EOT
}
```
To improve on this, Terraform also accepts an _indented_ heredoc string variant
To improve on this, OpenTF also accepts an _indented_ heredoc string variant
that is introduced by the `<<-` sequence:
```hcl
@ -116,7 +116,7 @@ block {
}
```
In this case, Terraform analyses the lines in the sequence to find the one
In this case, OpenTF 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:

View File

@ -7,9 +7,9 @@ description: >-
# Type Constraints
Terraform module authors and provider developers can use detailed type
OpenTF module authors and provider developers can use detailed type
constraints to validate user-provided values for their input variables and
resource arguments. This requires some additional knowledge about Terraform's
resource arguments. This requires some additional knowledge about OpenTF's
type system, but allows you to build a more resilient user interface for your
modules and resources.
@ -24,15 +24,15 @@ function-like constructs called _type constructors._
the type. Without its argument, a type constructor does not fully
represent a type; instead, it represents a _kind_ of similar types.
Type constraints look like other kinds of Terraform
[expressions](/terraform/language/expressions), but are a special syntax. Within the
Terraform language, they are only valid in the `type` argument of an
[input variable](/terraform/language/values/variables).
Type constraints look like other kinds of OpenTF
[expressions](/opentf/language/expressions), but are a special syntax. Within the
OpenTF language, they are only valid in the `type` argument of an
[input variable](/opentf/language/values/variables).
## Primitive Types
A _primitive_ type is a simple type that isn't made from any other types. All
primitive types in Terraform are represented by a type keyword. The available
primitive types in OpenTF are represented by a type keyword. The available
primitive types are:
* `string`: a sequence of Unicode characters representing some text, such
@ -44,7 +44,7 @@ primitive types are:
### Conversion of Primitive Types
The Terraform language will automatically convert `number` and `bool` values
The OpenTF language will automatically convert `number` and `bool` values
to `string` values when needed, and vice-versa as long as the string contains
a valid representation of a number or boolean value.
@ -73,7 +73,7 @@ For example, the type `list(string)` means "list of strings", which is a
different type than `list(number)`, a list of numbers. All elements of a
collection must always be of the same type.
The three kinds of collection type in the Terraform language are:
The three kinds of collection type in the OpenTF language are:
* `list(...)`: a sequence of values identified by consecutive whole numbers
starting with zero.
@ -96,7 +96,7 @@ The three kinds of collection type in the Terraform language are:
for single line maps. A newline between key/value pairs is sufficient
in multi-line maps.
-> **Note:** Although colons are valid delimiters between keys and values, `terraform fmt` ignores them. In contrast, `terraform fmt` attempts to vertically align equals signs.
-> **Note:** Although colons are valid delimiters between keys and values, `opentf fmt` ignores them. In contrast, `opentf fmt` attempts to vertically align equals signs.
* `set(...)`: a collection of unique values that do not have any secondary
identifiers or ordering.
@ -107,7 +107,7 @@ A _structural_ type allows multiple values of _several distinct types_ to be
grouped together as a single value. Structural types require a _schema_ as an
argument, to specify which types are allowed for which elements.
The two kinds of structural type in the Terraform language are:
The two kinds of structural type in the OpenTF language are:
* `object(...)`: a collection of named attributes that each have their own type.
@ -150,26 +150,26 @@ like the following:
### Complex Type Literals
The Terraform language has literal expressions for creating tuple and object
The OpenTF language has literal expressions for creating tuple and object
values, which are described in
[Expressions: Literal Expressions](/terraform/language/expressions/types#literal-expressions) as
[Expressions: Literal Expressions](/opentf/language/expressions/types#literal-expressions) as
"list/tuple" literals and "map/object" literals, respectively.
Terraform does _not_ provide any way to directly represent lists, maps, or sets.
OpenTF does _not_ provide any way to directly represent lists, maps, or sets.
However, due to the automatic conversion of complex types (described below), the
difference between similar complex types is almost never relevant to a normal
user, and most of the Terraform documentation conflates lists with tuples and
user, and most of the OpenTF documentation conflates lists with tuples and
maps with objects. The distinctions are only useful when restricting input
values for a module or resource.
### Conversion of Complex Types
Similar kinds of complex types (list/tuple/set and map/object) can usually be
used interchangeably within the Terraform language, and most of Terraform's
used interchangeably within the OpenTF language, and most of OpenTF's
documentation glosses over the differences between the kinds of complex type.
This is due to two conversion behaviors:
* Whenever possible, Terraform converts values between similar kinds of complex
* Whenever possible, OpenTF converts values between similar kinds of complex
types if the provided value is not the exact type requested. "Similar kinds"
is defined as follows:
* Objects and maps are similar.
@ -187,23 +187,23 @@ This is due to two conversion behaviors:
in an arbitrary order. If the set's elements were strings, they will
be in lexicographical order; sets of other element types do not
guarantee any particular order of elements.
* Whenever possible, Terraform converts _element values_ within a complex type,
* Whenever possible, OpenTF converts _element values_ within a complex type,
either by converting complex-typed elements recursively or as described above
in [Conversion of Primitive Types](#conversion-of-primitive-types).
For example: if a module argument requires a value of type `list(string)` and a
user provides the tuple `["a", 15, true]`, Terraform will internally transform
user provides the tuple `["a", 15, true]`, OpenTF will internally transform
the value to `["a", "15", "true"]` by converting the elements to the required
`string` element type. Later, if the module uses those elements to set different
resource arguments that require a string, a number, and a bool (respectively),
Terraform will automatically convert the second and third strings back to the
OpenTF will automatically convert the second and third strings back to the
required types at that time, since they contain valid representations of a
number and a bool.
On the other hand, automatic conversion will fail if the provided value
(including any of its element values) is incompatible with the required type. If
an argument requires a type of `map(string)` and a user provides the object
`{name = ["Kristy", "Claudia", "Mary Anne", "Stacey"], age = 12}`, Terraform
`{name = ["Kristy", "Claudia", "Mary Anne", "Stacey"], age = 12}`, OpenTF
will raise a type mismatch error, since a tuple cannot be converted to a string.
## Dynamic Types: The "any" Constraint
@ -214,7 +214,7 @@ exact type constraint unless you are truly handling dynamic data.
The keyword `any` is a special construct that serves as a placeholder for a
type yet to be decided. `any` is not _itself_ a type: when interpreting a
value against a type constraint containing `any`, Terraform will attempt to
value against a type constraint containing `any`, OpenTF will attempt to
find a single actual type that could replace the `any` keyword to produce
a valid result.
@ -248,16 +248,16 @@ instead.
### `any` with Collection Types
All of the elements of a collection must have the same type, so if you use
`any` as the placeholder for the element type of a collection then Terraform
`any` as the placeholder for the element type of a collection then OpenTF
will attempt to find a single exact element type to use for the resulting
collection.
For example, given the type constraint `list(any)`, Terraform will examine
For example, given the type constraint `list(any)`, OpenTF will examine
the given value and try to choose a replacement for the `any` that would
make the result valid.
If the given value were `["a", "b", "c"]` -- whose physical type is
`tuple([string, string, string])` -- Terraform analyzes this as follows:
`tuple([string, string, string])` -- OpenTF analyzes this as follows:
* Tuple types and list types are _similar_ per the previous section, so the
tuple-to-list conversion rule applies.
@ -266,17 +266,17 @@ If the given value were `["a", "b", "c"]` -- whose physical type is
* Therefore in this case the `any` argument is replaced with `string`,
and the final concrete value type is `list(string)`.
If the elements of the given tuple are not all of the same type then Terraform
will attempt to find a single type that they can all convert to. Terraform
If the elements of the given tuple are not all of the same type then OpenTF
will attempt to find a single type that they can all convert to. OpenTF
will consider various conversion rules as described in earlier sections.
* If the given value were instead `["a", 1, "b"]` then Terraform would still
* If the given value were instead `["a", 1, "b"]` then OpenTF would still
select `list(string)`, because of the primitive type conversion rules, and
the resulting value would be `["a", "1", "b"]` due to the string conversion
implied by that type constraint.
* If the given value were instead `["a", [], "b"]` then the value cannot
conform to the type constraint: there is no single type that both a string
and an empty tuple can convert to. Terraform would reject this value,
and an empty tuple can convert to. OpenTF would reject this value,
complaining that all elements must have the same type.
Although the above examples use `list(any)`, a similar principle applies to
@ -284,7 +284,7 @@ Although the above examples use `list(any)`, a similar principle applies to
## Optional Object Type Attributes
Terraform typically returns an error when it does not receive a value for specified object attributes. When you mark an attribute as optional, Terraform instead inserts a default value for the missing attribute. This allows the receiving module to describe an appropriate fallback behavior.
OpenTF typically returns an error when it does not receive a value for specified object attributes. When you mark an attribute as optional, OpenTF instead inserts a default value for the missing attribute. This allows the receiving module to describe an appropriate fallback behavior.
To mark attributes as optional, use the `optional` modifier in the object type constraint. The following example creates optional attribute `b` and optional attribute with a default value `c`.
@ -301,11 +301,11 @@ variable "with_optional_attribute" {
The `optional` modifier takes one or two arguments.
- **Type:** (Required) The first argument
specifies the type of the attribute.
- **Default:** (Optional) The second argument defines the default value that Terraform should use if the attribute is not present. This must be compatible with the attribute type. If not specified, Terraform uses a `null` value of the appropriate type as the default.
- **Default:** (Optional) The second argument defines the default value that OpenTF should use if the attribute is not present. This must be compatible with the attribute type. If not specified, OpenTF uses a `null` value of the appropriate type as the default.
An optional attribute with a non-`null` default value is guaranteed to never have the value `null` within the receiving module. Terraform will substitute the default value both when a caller omits the attribute altogether and when a caller explicitly sets it to `null`, thereby avoiding the need for additional checks to handle a possible null value.
An optional attribute with a non-`null` default value is guaranteed to never have the value `null` within the receiving module. OpenTF will substitute the default value both when a caller omits the attribute altogether and when a caller explicitly sets it to `null`, thereby avoiding the need for additional checks to handle a possible null value.
Terraform applies object attribute defaults top-down in nested variable types. This means that Terraform applies the default value you specify in the `optional` modifier first and then later applies any nested default values to that attribute.
OpenTF applies object attribute defaults top-down in nested variable types. This means that OpenTF applies the default value you specify in the `optional` modifier first and then later applies any nested default values to that attribute.
### Example: Nested Structures with Optional Attributes and Defaults
@ -331,7 +331,7 @@ The following example `terraform.tfvars` file specifies three bucket configurati
- `archived` uses default configuration, but is disabled
- `docs` overrides the index and error documents to use text files
The `production` bucket does not specify the index and error documents, and the `archived` bucket omits the website configuration entirely. Terraform will use the default values specified in the `bucket` type constraint.
The `production` bucket does not specify the index and error documents, and the `archived` bucket omits the website configuration entirely. OpenTF will use the default values specified in the `bucket` type constraint.
```hcl
buckets = [
@ -364,9 +364,9 @@ buckets = [
This configuration produces the following variable values.
- For the `production` and `docs` buckets, Terraform sets `enabled` to `true`. Terraform also supplies default values for `website`, and then the values specified in `docs` override those defaults.
- For the `archived` and `docs` buckets, Terraform sets `routing_rules` to a `null` value. When Terraform does not receive optional attributes and there are no specified defaults, Terraform populates those attributes with a `null` value.
- For the `archived` bucket, Terraform populates the `website` attribute with the default values specified in the `buckets` type constraint.
- For the `production` and `docs` buckets, OpenTF sets `enabled` to `true`. OpenTF also supplies default values for `website`, and then the values specified in `docs` override those defaults.
- For the `archived` and `docs` buckets, OpenTF sets `routing_rules` to a `null` value. When OpenTF does not receive optional attributes and there are no specified defaults, OpenTF populates those attributes with a `null` value.
- For the `archived` bucket, OpenTF populates the `website` attribute with the default values specified in the `buckets` type constraint.
```hcl
tolist([

View File

@ -13,7 +13,7 @@ applied to it.
## Types
The Terraform language uses the following types for its values:
The OpenTF language uses the following types for its values:
* `string`: a sequence of Unicode characters representing some text, like
`"hello"`.
@ -32,7 +32,7 @@ Strings, numbers, and bools are sometimes called _primitive types._ Lists/tuples
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 to `null`, Terraform behaves as though you
argument of a resource to `null`, OpenTF 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
@ -41,7 +41,7 @@ Finally, there is one special value that has _no_ type:
## 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
constant value. OpenTF has a literal expression syntax for each of the value
types described above.
### Strings
@ -51,7 +51,7 @@ 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](/terraform/language/expressions/strings)
OpenTF, and have their own page of documentation. See [Strings](/opentf/language/expressions/strings)
for information about escape sequences, the heredoc syntax, interpolation, and
template directives.
@ -95,7 +95,7 @@ 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](/terraform/language/syntax/configuration#identifiers), but must be quoted
they are a valid [identifier](/opentf/language/syntax/configuration#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"`.
@ -116,7 +116,7 @@ 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
Whenever the distinction isn't relevant, the OpenTF documentation uses each
pair of terms interchangeably (with a historical preference for "list" and
"map").
@ -126,7 +126,7 @@ 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](/terraform/language/expressions/type-constraints).
usually doesn't matter), see [Type Constraints](/opentf/language/expressions/type-constraints).
## Type Conversion
@ -134,12 +134,12 @@ 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
Where possible, OpenTF automatically converts values from one type to
another in order to produce the expected type. If this isn't possible, OpenTF
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.
OpenTF 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.

View File

@ -2,29 +2,29 @@
page_title: Version Constraints - Configuration Language
description: >-
Version constraint strings specify a range of acceptable versions for modules,
providers, and Terraform itself. Learn version constraint syntax and behavior.
providers, and OpenTF itself. Learn version constraint syntax and behavior.
---
# Version Constraints
Anywhere that Terraform lets you specify a range of acceptable versions for
Anywhere that OpenTF lets you specify a range of acceptable versions for
something, it expects a specially formatted string known as a version
constraint. Version constraints are used when configuring:
- [Modules](/terraform/language/modules)
- [Provider requirements](/terraform/language/providers/requirements)
- [The `required_version` setting](/terraform/language/settings#specifying-a-required-terraform-version) in the `terraform` block.
- [Modules](/opentf/language/modules)
- [Provider requirements](/opentf/language/providers/requirements)
- [The `required_version` setting](/opentf/language/settings#specifying-a-required-opentf-version) in the `opentf` block.
## Version Constraint Syntax
Terraform's syntax for version constraints is very similar to the syntax used by
OpenTF's syntax for version constraints is very similar to the syntax used by
other dependency management systems like Bundler and NPM.
```hcl
version = ">= 1.2.0, < 2.0.0"
```
A version constraint is a [string literal](/terraform/language/expressions/strings)
A version constraint is a [string literal](/opentf/language/expressions/strings)
containing one or more conditions, which are separated by commas.
Each condition consists of an operator and a version number.
@ -52,21 +52,21 @@ The following operators are valid:
A version number that meets every applicable constraint is considered acceptable.
Terraform consults version constraints to determine whether it has acceptable
OpenTF consults version constraints to determine whether it has acceptable
versions of itself, any required provider plugins, and any required modules. For
plugins and modules, it will use the newest installed version that meets the
applicable constraints.
If Terraform doesn't have an acceptable version of a required plugin or module,
If OpenTF doesn't have an acceptable version of a required plugin or module,
it will attempt to download the newest version that meets the applicable
constraints.
If Terraform isn't able to obtain acceptable versions of external dependencies,
If OpenTF isn't able to obtain acceptable versions of external dependencies,
or if it doesn't have an acceptable version of itself, it won't proceed with any
plans, applies, or state manipulation actions.
Both the root module and any child module can constrain the acceptable versions
of Terraform and any providers they use. Terraform considers these constraints
of OpenTF and any providers they use. OpenTF considers these constraints
equal, and will only proceed if all of them can be met.
A prerelease version is a version number that contains a suffix introduced by
@ -85,12 +85,12 @@ versions do not match inexact operators such as `>=`, `~>`, etc.
may be appropriate if semantic versioning is used consistently or if there is
a well-defined release process that avoids unwanted updates.
### Terraform Core and Provider Versions
### OpenTF Core and Provider Versions
- Reusable modules should constrain only their minimum allowed versions of
Terraform and providers, such as `>= 0.12.0`. This helps avoid known
OpenTF and providers, such as `>= 0.12.0`. This helps avoid known
incompatibilities, while allowing the user of the module flexibility to
upgrade to newer versions of Terraform without altering the module.
upgrade to newer versions of OpenTF without altering the module.
- Root modules should use a `~>` constraint to set both a lower and upper bound
on versions for each provider they depend on.