mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-25 01:00:16 -05:00
website: Language: Move files to match new URL structure
This commit is contained in:
@@ -1,168 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Backend Configuration - Configuration Language"
|
||||
---
|
||||
|
||||
# Backend Configuration
|
||||
|
||||
|
||||
Each Terraform configuration can specify a backend, which defines exactly where
|
||||
and how operations are performed, where [state](/docs/state/index.html)
|
||||
snapshots are stored, etc. Most non-trivial Terraform configurations configure
|
||||
a remote backend so that multiple people can work with the same infrastructure.
|
||||
|
||||
## Using a Backend Block
|
||||
|
||||
Backends are configured with a nested `backend` block within the top-level
|
||||
`terraform` block:
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
backend "remote" {
|
||||
organization = "example_corp"
|
||||
|
||||
workspaces {
|
||||
name = "my-app-prod"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are some important limitations on backend configuration:
|
||||
|
||||
- A configuration can only provide one backend block.
|
||||
- A backend block cannot refer to named values (like input variables, locals, or data source attributes).
|
||||
|
||||
### Backend Types
|
||||
|
||||
The block label of the backend block (`"remote"`, in the example above) indicates which backend type to use. Terraform has a built-in selection of backends, and the configured backend must be available in the version of Terraform you are using.
|
||||
|
||||
The arguments used in the block's body are specific to the chosen backend type; they configure where and how the backend will store the configuration's state, and in some cases configure other behavior.
|
||||
|
||||
Some backends allow providing access credentials directly as part of the configuration for use in unusual situations, for pragmatic reasons. However, in normal use we _do not_ recommend including access credentials as part of the backend configuration. Instead, leave those arguments completely unset and provide credentials via the credentials files or environment variables that are conventional for the target system, as described in the documentation for each backend.
|
||||
|
||||
See _[Backend Types](/docs/backends/types/index.html)_ for details about each supported backend type and its configuration arguments.
|
||||
|
||||
### Default Backend
|
||||
|
||||
If a configuration includes no backend block, Terraform defaults to using the `local` backend, which performs operations on the local system and stores state as a plain file in the current working directory.
|
||||
|
||||
## Initialization
|
||||
|
||||
Whenever a configuration's backend changes, you must run `terraform init` again
|
||||
to validate and configure the backend before you can perform any plans, applies,
|
||||
or state operations.
|
||||
|
||||
When changing backends, Terraform will give you the option to migrate
|
||||
your state to the new backend. This lets you adopt backends without losing
|
||||
any existing state.
|
||||
|
||||
To be extra careful, we always recommend manually backing up your state
|
||||
as well. You can do this by simply copying your `terraform.tfstate` file
|
||||
to another location. The initialization process should create a backup
|
||||
as well, but it never hurts to be safe!
|
||||
|
||||
## Partial Configuration
|
||||
|
||||
You do not need to specify every required argument in the backend configuration.
|
||||
Omitting certain arguments may be desirable if some arguments are provided
|
||||
automatically by an automation script running Terraform. When some or all of
|
||||
the arguments are omitted, we call this a _partial configuration_.
|
||||
|
||||
With a partial configuration, the remaining configuration arguments must be
|
||||
provided as part of
|
||||
[the initialization process](/docs/backends/init.html#backend-initialization).
|
||||
There are several ways to supply the remaining arguments:
|
||||
|
||||
* **File**: A configuration file may be specified via the `init` command line.
|
||||
To specify a file, use the `-backend-config=PATH` option when running
|
||||
`terraform init`. If the file contains secrets it may be kept in
|
||||
a secure data store, such as
|
||||
[Vault](https://www.vaultproject.io/), in which case it must be downloaded
|
||||
to the local disk before running Terraform.
|
||||
|
||||
* **Command-line key/value pairs**: Key/value pairs can be specified via the
|
||||
`init` command line. Note that many shells retain command-line flags in a
|
||||
history file, so this isn't recommended for secrets. To specify a single
|
||||
key/value pair, use the `-backend-config="KEY=VALUE"` option when running
|
||||
`terraform init`.
|
||||
|
||||
* **Interactively**: Terraform will interactively ask you for the required
|
||||
values, unless interactive input is disabled. Terraform will not prompt for
|
||||
optional values.
|
||||
|
||||
If backend settings are provided in multiple locations, the top-level
|
||||
settings are merged such that any command-line options override the settings
|
||||
in the main configuration and then the command-line options are processed
|
||||
in order, with later options overriding values set by earlier options.
|
||||
|
||||
The final, merged configuration is stored on disk in the `.terraform`
|
||||
directory, which should be ignored from version control. This means that
|
||||
sensitive information can be omitted from version control, but it will be
|
||||
present in plain text on local disk when running Terraform.
|
||||
|
||||
When using partial configuration, Terraform requires at a minimum that
|
||||
an empty backend configuration is specified in one of the root Terraform
|
||||
configuration files, to specify the backend type. For example:
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
backend "consul" {}
|
||||
}
|
||||
```
|
||||
|
||||
A backend configuration file has the contents of the `backend` block as
|
||||
top-level attributes, without the need to wrap it in another `terraform`
|
||||
or `backend` block:
|
||||
|
||||
```hcl
|
||||
address = "demo.consul.io"
|
||||
path = "example_app/terraform_state"
|
||||
scheme = "https"
|
||||
```
|
||||
|
||||
The same settings can alternatively be specified on the command line as
|
||||
follows:
|
||||
|
||||
```
|
||||
$ terraform init \
|
||||
-backend-config="address=demo.consul.io" \
|
||||
-backend-config="path=example_app/terraform_state" \
|
||||
-backend-config="scheme=https"
|
||||
```
|
||||
|
||||
The Consul backend also requires a Consul access token. Per the recommendation
|
||||
above of omitting credentials from the configuration and using other mechanisms,
|
||||
the Consul token would be provided by setting either the `CONSUL_HTTP_TOKEN`
|
||||
or `CONSUL_HTTP_AUTH` environment variables. See the documentation of your
|
||||
chosen backend to learn how to provide credentials to it outside of its main
|
||||
configuration.
|
||||
|
||||
## Changing Configuration
|
||||
|
||||
You can change your backend configuration at any time. You can change
|
||||
both the configuration itself as well as the type of backend (for example
|
||||
from "consul" to "s3").
|
||||
|
||||
Terraform will automatically detect any changes in your configuration
|
||||
and request a [reinitialization](/docs/backends/init.html). As part of
|
||||
the reinitialization process, Terraform will ask if you'd like to migrate
|
||||
your existing state to the new configuration. This allows you to easily
|
||||
switch from one backend to another.
|
||||
|
||||
If you're using multiple [workspaces](/docs/state/workspaces.html),
|
||||
Terraform can copy all workspaces to the destination. If Terraform detects
|
||||
you have multiple workspaces, it will ask if this is what you want to do.
|
||||
|
||||
If you're just reconfiguring the same backend, Terraform will still ask if you
|
||||
want to migrate your state. You can respond "no" in this scenario.
|
||||
|
||||
## Unconfiguring a Backend
|
||||
|
||||
If you no longer want to use any backend, you can simply remove the
|
||||
configuration from the file. Terraform will detect this like any other
|
||||
change and prompt you to [reinitialize](/docs/backends/init.html).
|
||||
|
||||
As part of the reinitialization, Terraform will ask if you'd like to migrate
|
||||
your state back down to normal local state. Once this is complete then
|
||||
Terraform is back to behaving as it does by default.
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Backend Overview - Configuration Language"
|
||||
---
|
||||
|
||||
# Backends
|
||||
|
||||
Each Terraform configuration can specify a backend, which defines where
|
||||
and how operations are performed, where [state](/docs/state/index.html)
|
||||
snapshots are stored, etc.
|
||||
|
||||
The rest of this page introduces the concept of backends; the other pages in
|
||||
this section document how to configure and use backends.
|
||||
|
||||
- [Backend Configuration](/docs/configuration/backend.html) documents the form
|
||||
of a `backend` block, which selects and configures a backend for a
|
||||
Terraform configuration.
|
||||
- This section also includes a page for each of Terraform's built-in backends,
|
||||
documenting its behavior and available settings. See the navigation sidebar
|
||||
for a complete list.
|
||||
|
||||
## Recommended Backends
|
||||
|
||||
- If you are still learning how to use Terraform, we recommend using the default
|
||||
`local` backend, which requires no configuration.
|
||||
- If you and your team are using Terraform to manage meaningful infrastructure,
|
||||
we recommend using the `remote` backend with [Terraform Cloud](/docs/cloud/index.html)
|
||||
or [Terraform Enterprise](/docs/enterprise/index.html).
|
||||
|
||||
## Where Backends are Used
|
||||
|
||||
Backend configuration is only used by [Terraform CLI](/docs/cli-index.html).
|
||||
Terraform Cloud and Terraform Enterprise always use their own state storage when
|
||||
performing Terraform runs, so they ignore any backend block in the
|
||||
configuration.
|
||||
|
||||
But since it's common to
|
||||
[use Terraform CLI alongside Terraform Cloud](/docs/cloud/run/cli.html)
|
||||
(and since certain state operations, like [tainting](/docs/commands/taint.html),
|
||||
can only be performed on the CLI), we recommend that Terraform Cloud users
|
||||
include a backend block in their configurations and configure the `remote`
|
||||
backend to use the relevant Terraform Cloud workspace(s).
|
||||
|
||||
## Where Backends Come From
|
||||
|
||||
Terraform includes a built-in selection of backends; this selection has changed
|
||||
over time, but does not change very often.
|
||||
|
||||
The built-in backends are the only backends. You cannot load additional backends
|
||||
as plugins.
|
||||
|
||||
## What Backends Do
|
||||
|
||||
There are two areas of Terraform's behavior that are determined by the backend:
|
||||
|
||||
- Where state is stored.
|
||||
- Where operations are performed.
|
||||
|
||||
### State
|
||||
|
||||
Terraform uses persistent [state](/docs/state/index.html) data to keep track of
|
||||
the resources it manages. Since it needs the state in order to know which
|
||||
real-world infrastructure objects correspond to the resources in a
|
||||
configuration, everyone working with a given collection of infrastructure
|
||||
resources must be able to access the same state data.
|
||||
|
||||
The `local` backend stores state as a local file on disk, but every other
|
||||
backend stores state in a remote service of some kind, which allows multiple
|
||||
people to access it. Accessing state in a remote service generally requires some
|
||||
kind of access credentials, since state data contains extremely sensitive
|
||||
information.
|
||||
|
||||
Some backends act like plain "remote disks" for state files; others support
|
||||
_locking_ the state while operations are being performed, which helps prevent
|
||||
conflicts and inconsistencies.
|
||||
|
||||
### Operations
|
||||
|
||||
"Operations" refers to performing API requests against infrastructure services
|
||||
in order to create, read, update, or destroy resources. Not every `terraform`
|
||||
subcommand performs API operations; many of them only operate on state data.
|
||||
|
||||
Only two backends actually perform operations: `local` and `remote`.
|
||||
|
||||
The `local` backend performs API operations directly from the machine where the
|
||||
`terraform` command is run. Whenever you use a backend other than `local` or
|
||||
`remote`, Terraform uses the `local` backend for operations; it only uses the
|
||||
configured backend for state storage.
|
||||
|
||||
The `remote` backend can perform API operations remotely, using Terraform Cloud
|
||||
or Terraform Enterprise. When running remote operations, the local `terraform`
|
||||
command displays the output of the remote actions as though they were being
|
||||
performed locally, but only the remote system requires cloud credentials or
|
||||
network access to the resources being managed.
|
||||
|
||||
Remote operations are optional for the `remote` backend; the settings for the
|
||||
target Terraform Cloud workspace determine whether operations run remotely or
|
||||
locally. If local operations are configured, Terraform uses the `remote` backend
|
||||
for state and the `local` backend for operations, like with the other state
|
||||
backends.
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Modules Overview - Configuration Language"
|
||||
---
|
||||
|
||||
# Modules
|
||||
|
||||
> **Hands-on:** Try the [Reuse Configuration with Modules](https://learn.hashicorp.com/collections/terraform/modules?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) collection on HashiCorp Learn.
|
||||
|
||||
_Modules_ are containers for multiple resources that are used together. A module
|
||||
consists of a collection of `.tf` and/or `.tf.json` files kept together in a
|
||||
directory.
|
||||
|
||||
Modules are the main way to package and reuse resource configurations with
|
||||
Terraform.
|
||||
|
||||
## The Root Module
|
||||
|
||||
Every Terraform configuration has at least one module, known as its
|
||||
_root module_, which consists of the resources defined in the `.tf` files in
|
||||
the main working directory.
|
||||
|
||||
## Child Modules
|
||||
|
||||
A Terraform module (usually the root module of a configuration) can _call_ other
|
||||
modules to include their resources into the configuration. A module that has
|
||||
been called by another module is often referred to as a _child module._
|
||||
|
||||
Child modules can be called multiple times within the same configuration, and
|
||||
multiple configurations can use the same child module.
|
||||
|
||||
## Published Modules
|
||||
|
||||
In addition to modules from the local filesystem, Terraform can load modules
|
||||
from a public or private registry. This makes it possible to publish modules for
|
||||
others to use, and to use modules that others have published.
|
||||
|
||||
The [Terraform Registry](https://registry.terraform.io/browse/modules) hosts a
|
||||
broad collection of publicly available Terraform modules for configuring many
|
||||
kinds of common infrastructure. These modules are free to use, and Terraform can
|
||||
download them automatically if you specify the appropriate source and version in
|
||||
a module call block.
|
||||
|
||||
Also, members of your organization might produce modules specifically crafted
|
||||
for your own infrastructure needs. [Terraform Cloud](/docs/cloud/index.html) and
|
||||
[Terraform Enterprise](/docs/enterprise/index.html) both include a private
|
||||
module registry for sharing modules internally within your organization.
|
||||
|
||||
## Using Modules
|
||||
|
||||
- [Module Blocks](/docs/configuration/blocks/modules/syntax.html) documents the syntax for
|
||||
calling a child module from a parent module, including meta-arguments like
|
||||
`for_each`.
|
||||
|
||||
- [Module Sources](/docs/modules/sources.html) documents what kinds of paths,
|
||||
addresses, and URIs can be used in the `source` argument of a module block.
|
||||
|
||||
- The Meta-Arguments section documents special arguments that can be used with
|
||||
every module, including
|
||||
[`providers`](/docs/configuration/meta-arguments/module-providers.html),
|
||||
[`depends_on`](/docs/configuration/meta-arguments/depends_on.html),
|
||||
[`count`](/docs/configuration/meta-arguments/count.html),
|
||||
and [`for_each`](/docs/configuration/meta-arguments/for_each.html).
|
||||
|
||||
## Developing Modules
|
||||
|
||||
For information about developing reusable modules, see
|
||||
[Module Development](/docs/modules/index.html).
|
||||
@@ -1,197 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Modules - Configuration Language"
|
||||
sidebar_current: "docs-config-modules"
|
||||
description: |-
|
||||
Modules allow multiple resources to be grouped together and encapsulated.
|
||||
---
|
||||
|
||||
# Module Blocks
|
||||
|
||||
> **Hands-on:** Try the [Reuse Configuration with Modules](https://learn.hashicorp.com/collections/terraform/modules?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) collection on HashiCorp Learn.
|
||||
|
||||
A _module_ is a container for multiple resources that are used together.
|
||||
|
||||
Every Terraform configuration has at least one module, known as its
|
||||
_root module_, which consists of the resources defined in the `.tf` files in
|
||||
the main working directory.
|
||||
|
||||
A module can call other modules, which lets you include the child module's
|
||||
resources into the configuration in a concise way. Modules
|
||||
can also be called multiple times, either within the same configuration or
|
||||
in separate configurations, allowing resource configurations to be packaged
|
||||
and re-used.
|
||||
|
||||
This page describes how to call one module from another. For more information
|
||||
about creating re-usable child modules, see [Module Development](/docs/modules/index.html).
|
||||
|
||||
## Calling a Child Module
|
||||
|
||||
To _call_ a module means to include the contents of that module into the
|
||||
configuration with specific values for its
|
||||
[input variables](/docs/configuration/variables.html). Modules are called
|
||||
from within other modules using `module` blocks:
|
||||
|
||||
```hcl
|
||||
module "servers" {
|
||||
source = "./app-cluster"
|
||||
|
||||
servers = 5
|
||||
}
|
||||
```
|
||||
|
||||
A module that includes a `module` block like this is the _calling module_ of the
|
||||
child module.
|
||||
|
||||
The label immediately after the `module` keyword is a local name, which the
|
||||
calling module can use to refer to this instance of the module.
|
||||
|
||||
Within the block body (between `{` and `}`) are the arguments for the module.
|
||||
Module calls use the following kinds of arguments:
|
||||
|
||||
- The `source` argument is mandatory for all modules.
|
||||
|
||||
- The `version` argument is recommended for modules from a registry.
|
||||
|
||||
- Most other arguments correspond to [input variables](/docs/configuration/variables.html)
|
||||
defined by the module. (The `servers` argument in the example above is one of
|
||||
these.)
|
||||
|
||||
- Terraform defines a few other meta-arguments that can be used with all
|
||||
modules, including `for_each` and `depends_on`.
|
||||
|
||||
### Source
|
||||
|
||||
All modules **require** a `source` argument, which is a meta-argument defined by
|
||||
Terraform. Its value is either the path to a local directory containing the
|
||||
module's configuration files, or a remote module source that Terraform should
|
||||
download and use. This value must be a literal string with no template
|
||||
sequences; arbitrary expressions are not allowed. For more information on
|
||||
possible values for this argument, see [Module Sources](/docs/modules/sources.html).
|
||||
|
||||
The same source address can be specified in multiple `module` blocks to create
|
||||
multiple copies of the resources defined within, possibly with different
|
||||
variable values.
|
||||
|
||||
After adding, removing, or modifying `module` blocks, you must re-run
|
||||
`terraform init` to allow Terraform the opportunity to adjust the installed
|
||||
modules. By default this command will not upgrade an already-installed module;
|
||||
use the `-upgrade` option to instead upgrade to the newest available version.
|
||||
|
||||
### Version
|
||||
|
||||
When using modules installed from a module registry, we recommend explicitly
|
||||
constraining the acceptable version numbers to avoid unexpected or unwanted
|
||||
changes.
|
||||
|
||||
Use the `version` argument in the `module` block to specify versions:
|
||||
|
||||
```shell
|
||||
module "consul" {
|
||||
source = "hashicorp/consul/aws"
|
||||
version = "0.0.5"
|
||||
|
||||
servers = 3
|
||||
}
|
||||
```
|
||||
|
||||
The `version` argument accepts a [version constraint string](/docs/configuration/version-constraints.html).
|
||||
Terraform will use the newest installed version of the module that meets the
|
||||
constraint; if no acceptable versions are installed, it will download the newest
|
||||
version that meets the constraint.
|
||||
|
||||
Version constraints are supported only for modules installed from a module
|
||||
registry, such as the public [Terraform Registry](https://registry.terraform.io/)
|
||||
or [Terraform Cloud's private module registry](/docs/cloud/registry/index.html).
|
||||
Other module sources can provide their own versioning mechanisms within the
|
||||
source string itself, or might not support versions at all. In particular,
|
||||
modules sourced from local file paths do not support `version`; since
|
||||
they're loaded from the same source repository, they always share the same
|
||||
version as their caller.
|
||||
|
||||
### Meta-arguments
|
||||
|
||||
Along with `source` and `version`, Terraform defines a few more
|
||||
optional meta-arguments that have special meaning across all modules,
|
||||
described in more detail in the following pages:
|
||||
|
||||
- `count` - Creates multiple instances of a module from a single `module` block.
|
||||
See [the `count` page](/docs/configuration/meta-arguments/count.html)
|
||||
for details.
|
||||
|
||||
- `for_each` - Creates multiple instances of a module from a single `module`
|
||||
block. See
|
||||
[the `for_each` page](/docs/configuration/meta-arguments/for_each.html)
|
||||
for details.
|
||||
|
||||
- `providers` - Passes provider configurations to a child module. See
|
||||
[the `providers` page](/docs/configuration/meta-arguments/module-providers.html)
|
||||
for details. If not specified, the child module inherits all of the default
|
||||
(un-aliased) provider configurations from the calling module.
|
||||
|
||||
- `depends_on` - Creates explicit dependencies between the entire
|
||||
module and the listed targets. See
|
||||
[the `depends_on` page](/docs/configuration/meta-arguments/depends_on.html)
|
||||
for details.
|
||||
|
||||
In addition to the above, the `lifecycle` argument is not currently used by
|
||||
Terraform but is reserved for planned future features.
|
||||
|
||||
## Accessing Module Output Values
|
||||
|
||||
The resources defined in a module are encapsulated, so the calling module
|
||||
cannot access their attributes directly. However, the child module can
|
||||
declare [output values](/docs/configuration/outputs.html) to selectively
|
||||
export certain values to be accessed by the calling module.
|
||||
|
||||
For example, if the `./app-cluster` module referenced in the example above
|
||||
exported an output value named `instance_ids` then the calling module
|
||||
can reference that result using the expression `module.servers.instance_ids`:
|
||||
|
||||
```hcl
|
||||
resource "aws_elb" "example" {
|
||||
# ...
|
||||
|
||||
instances = module.servers.instance_ids
|
||||
}
|
||||
```
|
||||
|
||||
For more information about referring to named values, see
|
||||
[Expressions](/docs/configuration/expressions/index.html).
|
||||
|
||||
## Transferring Resource State Into Modules
|
||||
|
||||
When refactoring an existing configuration to split code into child modules,
|
||||
moving resource blocks between modules causes Terraform to see the new location
|
||||
as an entirely different resource from the old. Always check the execution plan
|
||||
after moving code across modules to ensure that no resources are deleted by
|
||||
surprise.
|
||||
|
||||
If you want to make sure an existing resource is preserved, use
|
||||
[the `terraform state mv` command](/docs/commands/state/mv.html) to inform
|
||||
Terraform that it has moved to a different module.
|
||||
|
||||
When passing resource addresses to `terraform state mv`, resources within child
|
||||
modules must be prefixed with `module.<MODULE NAME>.`. If a module was called with
|
||||
[`count`](/docs/configuration/meta-arguments/count.html) or
|
||||
[`for_each`](/docs/configuration/meta-arguments/for_each.html),
|
||||
its resource addresses must be prefixed with `module.<MODULE NAME>[<INDEX>].`
|
||||
instead, where `<INDEX>` matches the `count.index` or `each.key` value of a
|
||||
particular module instance.
|
||||
|
||||
Full resource addresses for module contents are used within the UI and on the
|
||||
command line, but cannot be used within a Terraform configuration. Only
|
||||
[outputs](/docs/configuration/outputs.html) from a module can be referenced from
|
||||
elsewhere in your configuration.
|
||||
|
||||
## Tainting resources within a module
|
||||
|
||||
The [taint command](/docs/commands/taint.html) can be used to _taint_ specific
|
||||
resources within a module:
|
||||
|
||||
```shell
|
||||
$ terraform taint module.salt_master.aws_instance.salt_master
|
||||
```
|
||||
|
||||
It is not possible to taint an entire module. Instead, each resource within
|
||||
the module must be tainted separately.
|
||||
@@ -1,122 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Providers - Configuration Language"
|
||||
---
|
||||
|
||||
# Providers
|
||||
|
||||
Terraform relies on plugins called "providers" to interact with remote systems.
|
||||
|
||||
Terraform configurations must declare which providers they require so that
|
||||
Terraform can install and use them. Additionally, some providers require
|
||||
configuration (like endpoint URLs or cloud regions) before they can be used.
|
||||
|
||||
## What Providers Do
|
||||
|
||||
Each provider adds a set of [resource types](/docs/configuration/blocks/resources/index.html)
|
||||
and/or [data sources](/docs/configuration/data-sources.html) that Terraform can
|
||||
manage.
|
||||
|
||||
Every resource type is implemented by a provider; without providers, Terraform
|
||||
can't manage any kind of infrastructure.
|
||||
|
||||
Most providers configure a specific infrastructure platform (either cloud or
|
||||
self-hosted). Providers can also offer local utilities for tasks like
|
||||
generating random numbers for unique resource names.
|
||||
|
||||
## Where Providers Come From
|
||||
|
||||
Providers are distributed separately from Terraform itself, and each provider
|
||||
has its own release cadence and version numbers.
|
||||
|
||||
The [Terraform Registry](https://registry.terraform.io/browse/providers)
|
||||
is the main directory of publicly available Terraform providers, and hosts
|
||||
providers for most major infrastructure platforms.
|
||||
|
||||
## How to Use Providers
|
||||
|
||||
To use resources from a given provider, you need to include some information
|
||||
about it in your configuration. See the following pages for details:
|
||||
|
||||
- [Provider Requirements](/docs/configuration/provider-requirements.html)
|
||||
documents how to declare providers so Terraform can install them.
|
||||
|
||||
- [Provider Configuration](/docs/configuration/providers.html)
|
||||
documents how to configure settings for providers.
|
||||
|
||||
- [Dependency Lock File](/docs/configuration/dependency-lock.html)
|
||||
documents an additional HCL file that can be included with a configuration,
|
||||
which tells Terraform to always use a specific set of provider versions.
|
||||
|
||||
## Provider Installation
|
||||
|
||||
- Terraform Cloud and Terraform Enterprise install providers as part of every run.
|
||||
|
||||
- Terraform CLI finds and installs providers when
|
||||
[initializing a working directory](/docs/cli/init/index.html). It can
|
||||
automatically download providers from a Terraform registry, or load them from
|
||||
a local mirror or cache. If you are using a persistent working directory, you
|
||||
must reinitialize whenever you change a configuration's providers.
|
||||
|
||||
To save time and bandwidth, Terraform CLI supports an optional plugin
|
||||
cache. You can enable the cache using the `plugin_cache_dir` setting in
|
||||
[the CLI configuration file](/docs/commands/cli-config.html).
|
||||
|
||||
To ensure Terraform always installs the same provider versions for a given
|
||||
configuration, you can use Terraform CLI to create a
|
||||
[dependency lock file](/docs/configuration/dependency-lock.html)
|
||||
and commit it to version control along with your configuration. If a lock file
|
||||
is present, Terraform Cloud, CLI, and Enterprise will all obey it when
|
||||
installing providers.
|
||||
|
||||
> **Hands-on:** Try the [Lock and Upgrade Provider Versions](https://learn.hashicorp.com/tutorials/terraform/provider-versioning?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
## How to Find Providers
|
||||
|
||||
To find providers for the infrastructure platforms you use, browse
|
||||
[the providers section of the Terraform Registry](https://registry.terraform.io/browse/providers).
|
||||
|
||||
Some providers on the Registry are developed and published by HashiCorp, some
|
||||
are published by platform maintainers, and some are published by users and
|
||||
volunteers. The provider listings use the following badges to indicate who
|
||||
develops and maintains a given provider.
|
||||
|
||||
<table border="0" style="border-collapse: collapse; width: 100%;">
|
||||
<tbody>
|
||||
<tr style="height: 21px;">
|
||||
<td style="width: 12.4839%; height: 21px;"><strong>Tier</strong></td>
|
||||
<td style="width: 55.7271%; height: 21px;"><strong>Description</strong></td>
|
||||
<td style="width: 31.7889%; height: 21px;"><strong>Namespace</strong></td>
|
||||
</tr>
|
||||
<tr style="height: 21px;">
|
||||
<td style="width: 12.4839%; height: 21px;"><img src="/docs/registry/providers/images/official-tier.png" alt="" /></td>
|
||||
<td style="width: 55.7271%; height: 21px;"><i><span style="font-weight: 400;">Official providers are owned and maintained by HashiCorp </span></i></td>
|
||||
<td style="width: 31.7889%; height: 21px;"><code><span style="font-weight: 400;">hashicorp</span></code></td>
|
||||
</tr>
|
||||
<tr style="height: 21px;">
|
||||
<td style="width: 12.4839%; height: 21px;"><img src="/docs/registry/providers/images/verified-tier.png" alt="" /></td>
|
||||
<td style="width: 55.7271%; height: 21px;"><i><span style="font-weight: 400;">Verified providers are owned and maintained by third-party technology partners. Providers in this tier indicate HashiCorp has verified the authenticity of the Provider’s publisher, and that the partner is a member of the </span></i><a href="https://www.hashicorp.com/ecosystem/become-a-partner/"><i><span style="font-weight: 400;">HashiCorp Technology Partner Program</span></i></a><i><span style="font-weight: 400;">.</span></i></td>
|
||||
<td style="width: 31.7889%; height: 21px;"><span style="font-weight: 400;">Third-party organization, e.g. </span><code><span style="font-weight: 400;">mongodb/mongodbatlas</span></code></td>
|
||||
</tr>
|
||||
<tr style="height: 21px;">
|
||||
<td style="width: 12.4839%; height: 21px;"><img src="/docs/registry/providers/images/community-tier.png" alt="" /></td>
|
||||
<td style="width: 55.7271%; height: 21px;">Community providers are published to the Terraform Registry by individual maintainers, groups of maintainers, or other members of the Terraform community.</td>
|
||||
<td style="width: 31.7889%; height: 21px;"><br />Maintainer’s individual or organization account, e.g. <code>DeviaVir/gsuite</code></td>
|
||||
</tr>
|
||||
<tr style="height: 21px;">
|
||||
<td style="width: 12.4839%; height: 21px;"><img src="/docs/registry/providers/images/archived-tier.png" alt="" /></td>
|
||||
<td style="width: 55.7271%; height: 21px;">Archived Providers are Official or Verified Providers that are no longer maintained by HashiCorp or the community. This may occur if an API is deprecated or interest was low.</td>
|
||||
<td style="width: 31.7889%; height: 21px;"><code>hashicorp</code> or third-party</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## How to Develop Providers
|
||||
|
||||
Providers are written in Go, using the Terraform Plugin SDK. For more
|
||||
information on developing providers, see:
|
||||
|
||||
- The [Extending Terraform](/docs/extend/index.html) documentation
|
||||
- The [Call APIs with Terraform Providers](https://learn.hashicorp.com/collections/terraform/providers?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS)
|
||||
collection on HashiCorp Learn
|
||||
@@ -1,108 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Resource Behavior - Configuration Language"
|
||||
---
|
||||
|
||||
# Resource Behavior
|
||||
|
||||
A `resource` block declares that you want a particular infrastructure object
|
||||
to exist with the given settings. If you are writing a new configuration for
|
||||
the first time, the resources it defines will exist _only_ in the configuration,
|
||||
and will not yet represent real infrastructure objects in the target platform.
|
||||
|
||||
_Applying_ a Terraform configuration is the process of creating, updating,
|
||||
and destroying real infrastructure objects in order to make their settings
|
||||
match the configuration.
|
||||
|
||||
## How Terraform Applies a Configuration
|
||||
|
||||
When Terraform creates a new infrastructure object represented by a `resource`
|
||||
block, the identifier for that real object is saved in Terraform's
|
||||
[state](/docs/state/index.html), allowing it to be updated and destroyed
|
||||
in response to future changes. For resource blocks that already have an
|
||||
associated infrastructure object in the state, Terraform compares the
|
||||
actual configuration of the object with the arguments given in the
|
||||
configuration and, if necessary, updates the object to match the configuration.
|
||||
|
||||
In summary, applying a Terraform configuration will:
|
||||
|
||||
- _Create_ resources that exist in the configuration but are not associated with a real infrastructure object in the state.
|
||||
- _Destroy_ resources that exist in the state but no longer exist in the configuration.
|
||||
- _Update in-place_ resources whose arguments have changed.
|
||||
- _Destroy and re-create_ resources whose arguments have changed but which cannot be updated in-place due to remote API limitations.
|
||||
|
||||
This general behavior applies for all resources, regardless of type. The
|
||||
details of what it means to create, update, or destroy a resource are different
|
||||
for each resource type, but this standard set of verbs is common across them
|
||||
all.
|
||||
|
||||
The meta-arguments within `resource` blocks, documented in the
|
||||
sections below, allow some details of this standard resource behavior to be
|
||||
customized on a per-resource basis.
|
||||
|
||||
## Accessing Resource Attributes
|
||||
|
||||
[Expressions](/docs/configuration/expressions/index.html) within a Terraform module can access
|
||||
information about resources in the same module, and you can use that information
|
||||
to help configure other resources. Use the `<RESOURCE TYPE>.<NAME>.<ATTRIBUTE>`
|
||||
syntax to reference a resource attribute in an expression.
|
||||
|
||||
In addition to arguments specified in the configuration, resources often provide
|
||||
read-only attributes with information obtained from the remote API; this often
|
||||
includes things that can't be known until the resource is created, like the
|
||||
resource's unique random ID.
|
||||
|
||||
Many providers also include [data sources](/docs/configuration/data-sources.html),
|
||||
which are a special type of resource used only for looking up information.
|
||||
|
||||
For a list of the attributes a resource or data source type provides, consult
|
||||
its documentation; these are generally included in a second list below its list
|
||||
of configurable arguments.
|
||||
|
||||
For more information about referencing resource attributes in expressions, see
|
||||
[Expressions: References to Resource Attributes](/docs/configuration/expressions/references.html#references-to-resource-attributes).
|
||||
|
||||
## Resource Dependencies
|
||||
|
||||
Most resources in a configuration don't have any particular relationship, and
|
||||
Terraform can make changes to several unrelated resources in parallel.
|
||||
|
||||
However, some resources must be processed after other specific resources;
|
||||
sometimes this is because of how the resource works, and sometimes the
|
||||
resource's configuration just requires information generated by another
|
||||
resource.
|
||||
|
||||
Most resource dependencies are handled automatically. Terraform analyses any
|
||||
[expressions](/docs/configuration/expressions/index.html) within a `resource` block to find references
|
||||
to other objects, and treats those references as implicit ordering requirements
|
||||
when creating, updating, or destroying resources. Since most resources with
|
||||
behavioral dependencies on other resources also refer to those resources' data,
|
||||
it's usually not necessary to manually specify dependencies between resources.
|
||||
|
||||
However, some dependencies cannot be recognized implicitly in configuration. For
|
||||
example, if Terraform must manage access control policies _and_ take actions
|
||||
that require those policies to be present, there is a hidden dependency between
|
||||
the access policy and a resource whose creation depends on it. In these rare
|
||||
cases,
|
||||
[the `depends_on` meta-argument](/docs/configuration/meta-arguments/depends_on.html)
|
||||
can explicitly specify a dependency.
|
||||
|
||||
## Local-only Resources
|
||||
|
||||
While most resource types correspond to an infrastructure object type that
|
||||
is managed via a remote network API, there are certain specialized resource
|
||||
types that operate only within Terraform itself, calculating some results and
|
||||
saving those results in the state for future use.
|
||||
|
||||
For example, local-only resource types exist for
|
||||
[generating private keys](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key),
|
||||
[issuing self-signed TLS certificates](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/self_signed_cert),
|
||||
and even [generating random ids](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id).
|
||||
While these resource types often have a more marginal purpose than those
|
||||
managing "real" infrastructure objects, they can be useful as glue to help
|
||||
connect together other resources.
|
||||
|
||||
The behavior of local-only resources is the same as all other resources, but
|
||||
their result data exists only within the Terraform state. "Destroying" such
|
||||
a resource means only to remove it from the state, discarding its data.
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Resources Overview - Configuration Language"
|
||||
---
|
||||
|
||||
# Resources
|
||||
|
||||
> **Hands-on:** Try the [Terraform: Get Started](https://learn.hashicorp.com/collections/terraform/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) collection on HashiCorp Learn.
|
||||
|
||||
_Resources_ are the most important element in the Terraform language.
|
||||
Each resource block describes one or more infrastructure objects, such
|
||||
as virtual networks, compute instances, or higher-level components such
|
||||
as DNS records.
|
||||
|
||||
- [Resource Blocks](/docs/configuration/blocks/resources/syntax.html) documents
|
||||
the syntax for declaring resources.
|
||||
|
||||
- [Resource Behavior](/docs/configuration/blocks/resources/behavior.html) explains in
|
||||
more detail how Terraform handles resource declarations when applying a
|
||||
configuration.
|
||||
|
||||
- The Meta-Arguments section documents special arguments that can be used with
|
||||
every resource type, including
|
||||
[`depends_on`](/docs/configuration/meta-arguments/depends_on.html),
|
||||
[`count`](/docs/configuration/meta-arguments/count.html),
|
||||
[`for_each`](/docs/configuration/meta-arguments/for_each.html),
|
||||
[`provider`](/docs/configuration/meta-arguments/resource-provider.html),
|
||||
and [`lifecycle`](/docs/configuration/meta-arguments/lifecycle.html).
|
||||
|
||||
- [Provisioners](/docs/configuration/blocks/resources/provisioners/index.html)
|
||||
documents configuring post-creation actions for a resource using the
|
||||
`provisioner` and `connection` blocks. Since provisioners are non-declarative
|
||||
and potentially unpredictable, we strongly recommend that you treat them as a
|
||||
last resort.
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Provisioners Overview - Configuration Language"
|
||||
---
|
||||
|
||||
# Provisioners
|
||||
|
||||
Provisioners can be used to model specific actions on the local machine or on a
|
||||
remote machine in order to prepare servers or other infrastructure objects for
|
||||
service.
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Resources - Configuration Language"
|
||||
sidebar_current: "docs-config-resources"
|
||||
description: |-
|
||||
Resources are the most important element in a Terraform configuration.
|
||||
Each resource corresponds to an infrastructure object, such as a virtual
|
||||
network or compute instance.
|
||||
---
|
||||
|
||||
# Resource Blocks
|
||||
|
||||
> **Hands-on:** Try the [Terraform: Get Started](https://learn.hashicorp.com/collections/terraform/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) collection on HashiCorp Learn.
|
||||
|
||||
_Resources_ are the most important element in the Terraform language.
|
||||
Each resource block describes one or more infrastructure objects, such
|
||||
as virtual networks, compute instances, or higher-level components such
|
||||
as DNS records.
|
||||
|
||||
## Resource Syntax
|
||||
|
||||
Resource declarations can include a number of advanced features, but only
|
||||
a small subset are required for initial use. More advanced syntax features,
|
||||
such as single resource declarations that produce multiple similar remote
|
||||
objects, are described later in this page.
|
||||
|
||||
```hcl
|
||||
resource "aws_instance" "web" {
|
||||
ami = "ami-a1b2c3d4"
|
||||
instance_type = "t2.micro"
|
||||
}
|
||||
```
|
||||
|
||||
A `resource` block declares a resource of a given type ("aws_instance")
|
||||
with a given local name ("web"). The name is used to refer to this resource
|
||||
from elsewhere in the same Terraform module, but has no significance outside
|
||||
that module's scope.
|
||||
|
||||
The resource type and name together serve as an identifier for a given
|
||||
resource and so must be unique within a module.
|
||||
|
||||
Within the block body (between `{` and `}`) are the configuration arguments
|
||||
for the resource itself. Most arguments in this section depend on the
|
||||
resource type, and indeed in this example both `ami` and `instance_type` are
|
||||
arguments defined specifically for [the `aws_instance` resource type](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance).
|
||||
|
||||
-> **Note:** Resource names must start with a letter or underscore, and may
|
||||
contain only letters, digits, underscores, and dashes.
|
||||
|
||||
## Resource Types
|
||||
|
||||
Each resource is associated with a single _resource type_, which determines
|
||||
the kind of infrastructure object it manages and what arguments and other
|
||||
attributes the resource supports.
|
||||
|
||||
### Providers
|
||||
|
||||
Each resource type is implemented by a [provider](/docs/configuration/provider-requirements.html),
|
||||
which is a plugin for Terraform that offers a collection of resource types. A
|
||||
provider usually provides resources to manage a single cloud or on-premises
|
||||
infrastructure platform. Providers are distributed separately from Terraform
|
||||
itself, but Terraform can automatically install most providers when initializing
|
||||
a working directory.
|
||||
|
||||
In order to manage resources, a Terraform module must specify which providers it
|
||||
requires. Additionally, most providers need some configuration in order to
|
||||
access their remote APIs, and the root module must provide that configuration.
|
||||
|
||||
For more information, see:
|
||||
|
||||
- [Provider Requirements](/docs/configuration/provider-requirements.html), for declaring which
|
||||
providers a module uses.
|
||||
- [Provider Configuration](/docs/configuration/providers.html), for configuring provider settings.
|
||||
|
||||
Terraform usually automatically determines which provider to use based on a
|
||||
resource type's name. (By convention, resource type names start with their
|
||||
provider's preferred local name.) When using multiple configurations of a
|
||||
provider (or non-preferred local provider names), you must use the `provider`
|
||||
meta-argument to manually choose an alternate provider configuration. See
|
||||
[the `provider` meta-argument](/docs/configuration/meta-arguments/resource-provider.html) for more details.
|
||||
|
||||
### Resource Arguments
|
||||
|
||||
Most of the arguments within the body of a `resource` block are specific to the
|
||||
selected resource type. The resource type's documentation lists which arguments
|
||||
are available and how their values should be formatted.
|
||||
|
||||
The values for resource arguments can make full use of
|
||||
[expressions](/docs/configuration/expressions/index.html) and other dynamic Terraform
|
||||
language features.
|
||||
|
||||
There are also some _meta-arguments_ that are defined by Terraform itself
|
||||
and apply across all resource types. (See [Meta-Arguments](#meta-arguments) below.)
|
||||
|
||||
### Documentation for Resource Types
|
||||
|
||||
Every Terraform provider has its own documentation, describing its resource
|
||||
types and their arguments.
|
||||
|
||||
Most publicly available providers are distributed on the
|
||||
[Terraform Registry](https://registry.terraform.io/browse/providers), which also
|
||||
hosts their documentation. When viewing a provider's page on the Terraform
|
||||
Registry, you can click the "Documentation" link in the header to browse its
|
||||
documentation. Provider documentation on the registry is versioned, and you can
|
||||
use the dropdown version menu in the header to switch which version's
|
||||
documentation you are viewing.
|
||||
|
||||
To browse the publicly available providers and their documentation, see
|
||||
[the providers section of the Terraform Registry](https://registry.terraform.io/browse/providers).
|
||||
|
||||
-> **Note:** Provider documentation used to be hosted directly on terraform.io,
|
||||
as part of Terraform's core documentation. Although some provider documentation
|
||||
might still be hosted here, the Terraform Registry is now the main home for all
|
||||
public provider docs. (The exception is the built-in
|
||||
[`terraform` provider](/docs/providers/terraform/index.html) for reading state
|
||||
data, since it is not available on the Terraform Registry.)
|
||||
|
||||
## Resource Behavior
|
||||
|
||||
For more information about how Terraform manages resources when applying a
|
||||
configuration, see
|
||||
[Resource Behavior](/docs/configuration/blocks/resources/behavior.html).
|
||||
|
||||
## Meta-Arguments
|
||||
|
||||
The Terraform language defines several meta-arguments, which can be used with
|
||||
any resource type to change the behavior of resources.
|
||||
|
||||
The following meta-arguments are documented on separate pages:
|
||||
|
||||
- [`depends_on`, for specifying hidden dependencies](/docs/configuration/meta-arguments/depends_on.html)
|
||||
- [`count`, for creating multiple resource instances according to a count](/docs/configuration/meta-arguments/count.html)
|
||||
- [`for_each`, to create multiple instances according to a map, or set of strings](/docs/configuration/meta-arguments/for_each.html)
|
||||
- [`provider`, for selecting a non-default provider configuration](/docs/configuration/meta-arguments/resource-provider.html)
|
||||
- [`lifecycle`, for lifecycle customizations](/docs/configuration/meta-arguments/lifecycle.html)
|
||||
- [`provisioner` and `connection`, for taking extra actions after resource creation](/docs/configuration/blocks/resources/provisioners/index.html)
|
||||
|
||||
## Operation Timeouts
|
||||
|
||||
Some resource types provide a special `timeouts` nested block argument that
|
||||
allows you to customize how long certain operations are allowed to take
|
||||
before being considered to have failed.
|
||||
For example, [`aws_db_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance)
|
||||
allows configurable timeouts for `create`, `update` and `delete` operations.
|
||||
|
||||
Timeouts are handled entirely by the resource type implementation in the
|
||||
provider, but resource types offering these features follow the convention
|
||||
of defining a child block called `timeouts` that has a nested argument
|
||||
named after each operation that has a configurable timeout value.
|
||||
Each of these arguments takes a string representation of a duration, such
|
||||
as `"60m"` for 60 minutes, `"10s"` for ten seconds, or `"2h"` for two hours.
|
||||
|
||||
```hcl
|
||||
resource "aws_db_instance" "example" {
|
||||
# ...
|
||||
|
||||
timeouts {
|
||||
create = "60m"
|
||||
delete = "2h"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The set of configurable operations is chosen by each resource type. Most
|
||||
resource types do not support the `timeouts` block at all. Consult the
|
||||
documentation for each resource type to see which operations it offers
|
||||
for configuration, if any.
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Variables and Outputs"
|
||||
---
|
||||
|
||||
# Variables and Outputs
|
||||
|
||||
The Terraform language includes a few kinds of blocks for requesting or
|
||||
publishing named values.
|
||||
|
||||
- [Input Variables](/docs/configuration/variables.html) serve as parameters for
|
||||
a Terraform module, so users can customize behavior without editing the source.
|
||||
|
||||
- [Output Values](/docs/configuration/outputs.html) are like return values for a
|
||||
Terraform module.
|
||||
|
||||
- [Local Values](/docs/configuration/locals.html) are a convenience feature for
|
||||
assigning a short name to an expression.
|
||||
@@ -1,229 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Data Sources - Configuration Language"
|
||||
sidebar_current: "docs-config-data-sources"
|
||||
description: |-
|
||||
Data sources allow data to be fetched or computed for use elsewhere in Terraform configuration.
|
||||
---
|
||||
|
||||
# Data Sources
|
||||
|
||||
_Data sources_ allow data to be fetched or computed for use elsewhere
|
||||
in Terraform configuration. Use of data sources allows a Terraform
|
||||
configuration to make use of information defined outside of Terraform,
|
||||
or defined by another separate Terraform configuration.
|
||||
|
||||
Each [provider](./providers.html) may offer data sources
|
||||
alongside its set of [resource](/docs/configuration/blocks/resources/index.html)
|
||||
types.
|
||||
|
||||
## Using Data Sources
|
||||
|
||||
A data source is accessed via a special kind of resource known as a
|
||||
_data resource_, declared using a `data` block:
|
||||
|
||||
```hcl
|
||||
data "aws_ami" "example" {
|
||||
most_recent = true
|
||||
|
||||
owners = ["self"]
|
||||
tags = {
|
||||
Name = "app-server"
|
||||
Tested = "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A `data` block requests that Terraform read from a given data source ("aws_ami")
|
||||
and export the result under the given local name ("example"). The name is used
|
||||
to refer to this resource from elsewhere in the same Terraform module, but has
|
||||
no significance outside of the scope of a module.
|
||||
|
||||
The data source and name together serve as an identifier for a given
|
||||
resource and so must be unique within a module.
|
||||
|
||||
Within the block body (between `{` and `}`) are query constraints defined by
|
||||
the data source. Most arguments in this section depend on the
|
||||
data source, and indeed in this example `most_recent`, `owners` and `tags` are
|
||||
all arguments defined specifically for [the `aws_ami` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami).
|
||||
|
||||
When distinguishing from data resources, the primary kind of resource (as declared
|
||||
by a `resource` block) is known as a _managed resource_. Both kinds of resources
|
||||
take arguments and export attributes for use in configuration, but while
|
||||
managed resources cause Terraform to create, update, and delete infrastructure
|
||||
objects, data resources cause Terraform only to _read_ objects. For brevity,
|
||||
managed resources are often referred to just as "resources" when the meaning
|
||||
is clear from context.
|
||||
|
||||
## Data Source Arguments
|
||||
|
||||
Each data resource is associated with a single data source, which determines
|
||||
the kind of object (or objects) it reads and what query constraint arguments
|
||||
are available.
|
||||
|
||||
Each data source in turn belongs to a [provider](./providers.html),
|
||||
which is a plugin for Terraform that offers a collection of resource types and
|
||||
data sources that most often belong to a single cloud or on-premises
|
||||
infrastructure platform.
|
||||
|
||||
Most of the items within the body of a `data` block are defined by and
|
||||
specific to the selected data source, and these arguments can make full
|
||||
use of [expressions](/docs/configuration/expressions/index.html) and other dynamic
|
||||
Terraform language features.
|
||||
|
||||
However, there are some "meta-arguments" that are defined by Terraform itself
|
||||
and apply across all data sources. These arguments often have additional
|
||||
restrictions on what language features can be used with them, and are described
|
||||
in more detail in the following sections.
|
||||
|
||||
## Data Resource Behavior
|
||||
|
||||
If the query constraint arguments for a data resource refer only to constant
|
||||
values or values that are already known, the data resource will be read and its
|
||||
state updated during Terraform's "refresh" phase, which runs prior to creating a plan.
|
||||
This ensures that the retrieved data is available for use during planning and
|
||||
so Terraform's plan will show the actual values obtained.
|
||||
|
||||
Query constraint arguments may refer to values that cannot be determined until
|
||||
after configuration is applied, such as the id of a managed resource that has
|
||||
not been created yet. In this case, reading from the data source is deferred
|
||||
until the apply phase, and any references to the results of the data resource
|
||||
elsewhere in configuration will themselves be unknown until after the
|
||||
configuration has been applied.
|
||||
|
||||
## Local-only Data Sources
|
||||
|
||||
While many data sources correspond to an infrastructure object type that
|
||||
is accessed via a remote network API, some specialized data sources operate
|
||||
only within Terraform itself, calculating some results and exposing them
|
||||
for use elsewhere.
|
||||
|
||||
For example, local-only data sources exist for
|
||||
[rendering templates](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file),
|
||||
[reading local files](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file), and
|
||||
[rendering AWS IAM policies](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document).
|
||||
|
||||
The behavior of local-only data sources is the same as all other data
|
||||
sources, but their result data exists only temporarily during a Terraform
|
||||
operation, and is re-calculated each time a new plan is created.
|
||||
|
||||
## Data Resource Dependencies
|
||||
|
||||
Data resources have the same dependency resolution behavior
|
||||
[as defined for managed resources](/docs/configuration/blocks/resources/behavior.html#resource-dependencies).
|
||||
Setting the `depends_on` meta-argument within `data` blocks defers reading of
|
||||
the data source until after all changes to the dependencies have been applied.
|
||||
|
||||
In order to ensure that data sources are accessing the most up to date
|
||||
information possible in a wide variety of use cases, arguments directly
|
||||
referencing managed resources are treated the same as if the resource was
|
||||
listed in `depends_on`. This behavior can be avoided when desired by indirectly
|
||||
referencing the managed resource values through a `local` value.
|
||||
|
||||
~> **NOTE:** **In Terraform 0.12 and earlier**, due to the data resource behavior of deferring the read until the apply phase when depending on values that are not yet known, using `depends_on` with `data` resources will force the read to always be deferred to the apply phase, and therefore a configuration that uses `depends_on` with a `data` resource can never converge. Due to this behavior, we do not recommend using `depends_on` with data resources.
|
||||
|
||||
|
||||
## Multiple Resource Instances
|
||||
|
||||
Data resources support [`count`](/docs/configuration/meta-arguments/count.html)
|
||||
and [`for_each`](/docs/configuration/meta-arguments/for_each.html)
|
||||
meta-arguments as defined for managed resources, with the same syntax and behavior.
|
||||
|
||||
As with managed resources, when `count` or `for_each` is present it is important to
|
||||
distinguish the resource itself from the multiple resource _instances_ it
|
||||
creates. Each instance will separately read from its data source with its
|
||||
own variant of the constraint arguments, producing an indexed result.
|
||||
|
||||
## Selecting a Non-default Provider Configuration
|
||||
|
||||
Data resources support [the `provider` meta-argument](/docs/configuration/meta-arguments/resource-provider.html)
|
||||
as defined for managed resources, with the same syntax and behavior.
|
||||
|
||||
## Lifecycle Customizations
|
||||
|
||||
Data resources do not currently have any customization settings available
|
||||
for their lifecycle, but the `lifecycle` nested block is reserved in case
|
||||
any are added in future versions.
|
||||
|
||||
## Example
|
||||
|
||||
A data source configuration looks like the following:
|
||||
|
||||
```hcl
|
||||
# Find the latest available AMI that is tagged with Component = web
|
||||
data "aws_ami" "web" {
|
||||
filter {
|
||||
name = "state"
|
||||
values = ["available"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "tag:Component"
|
||||
values = ["web"]
|
||||
}
|
||||
|
||||
most_recent = true
|
||||
}
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
The `data` block creates a data instance of the given _type_ (first
|
||||
block label) and _name_ (second block label). The combination of the type
|
||||
and name must be unique.
|
||||
|
||||
Within the block (the `{ }`) is configuration for the data instance. The
|
||||
configuration is dependent on the type, and is documented for each
|
||||
data source in the [providers section](/docs/providers/index.html).
|
||||
|
||||
Each data instance will export one or more attributes, which can be
|
||||
used in other resources as reference expressions of the form
|
||||
`data.<TYPE>.<NAME>.<ATTRIBUTE>`. For example:
|
||||
|
||||
```hcl
|
||||
resource "aws_instance" "web" {
|
||||
ami = data.aws_ami.web.id
|
||||
instance_type = "t1.micro"
|
||||
}
|
||||
```
|
||||
|
||||
## Meta-Arguments
|
||||
|
||||
As data sources are essentially a read only subset of resources, they also
|
||||
support the same [meta-arguments](/docs/configuration/blocks/resources/syntax.html#meta-arguments) of resources
|
||||
with the exception of the
|
||||
[`lifecycle` configuration block](/docs/configuration/meta-arguments/lifecycle.html).
|
||||
|
||||
### Non-Default Provider Configurations
|
||||
|
||||
Similarly to [resources](/docs/configuration/blocks/resources/index.html), when
|
||||
a module has multiple configurations for the same provider you can specify which
|
||||
configuration to use with the `provider` meta-argument:
|
||||
|
||||
```hcl
|
||||
data "aws_ami" "web" {
|
||||
provider = aws.west
|
||||
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
See
|
||||
[The Resource `provider` Meta-Argument](/docs/configuration/meta-arguments/resource-provider.html)
|
||||
for more information.
|
||||
|
||||
## Data Source Lifecycle
|
||||
|
||||
If the arguments of a data instance contain no references to computed values,
|
||||
such as attributes of resources that have not yet been created, then the
|
||||
data instance will be read and its state updated during Terraform's "refresh"
|
||||
phase, which by default runs prior to creating a plan. This ensures that the
|
||||
retrieved data is available for use during planning and the diff will show
|
||||
the real values obtained.
|
||||
|
||||
Data instance arguments may refer to computed values, in which case the
|
||||
attributes of the instance itself cannot be resolved until all of its
|
||||
arguments are defined. In this case, refreshing the data instance will be
|
||||
deferred until the "apply" phase, and all interpolations of the data instance
|
||||
attributes will show as "computed" in the plan since the values are not yet
|
||||
known.
|
||||
@@ -1,363 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Dependency Lock File (.terraform.lock.hcl) - Configuration Language"
|
||||
---
|
||||
|
||||
# Dependency Lock File
|
||||
|
||||
-> **Note:** This page is about a feature of Terraform 0.14 and later. Prior
|
||||
versions of Terraform did not track dependency selections at all, so the
|
||||
information here is not relevant to those versions.
|
||||
|
||||
> **Hands-on:** Try the [Lock and Upgrade Provider Versions](https://learn.hashicorp.com/tutorials/terraform/provider-versioning?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
A Terraform configuration may refer to two different kinds of external
|
||||
dependency that come from outside of its own codebase:
|
||||
|
||||
* [Providers](./provider-requirements.html), which are plugins for Terraform
|
||||
that extend it with support for interacting with various external systems.
|
||||
* [Modules](/docs/configuration/blocks/modules/index.html), which allow
|
||||
splitting out groups of Terraform configuration constructs (written in the
|
||||
Terraform language) into reusable abstractions.
|
||||
|
||||
Both of these dependency types can be published and updated independently from
|
||||
Terraform itself and from the configurations that depend on them. For that
|
||||
reason, Terraform must determine which versions of those dependencies are
|
||||
potentially compatible with the current configuration and which versions are
|
||||
currently selected for use.
|
||||
|
||||
[Version constraints](./version-constraints.html) within the configuration
|
||||
itself determine which versions of dependencies are _potentially_ compatible,
|
||||
but after selecting a specific version of each dependency Terraform remembers
|
||||
the decisions it made in a _dependency lock file_ so that it can (by default)
|
||||
make the same decisions again in future.
|
||||
|
||||
At present, the dependency lock file tracks only _provider_ dependencies.
|
||||
Terraform does not remember version selections for remote modules, and so
|
||||
Terraform will always select the newest available module version that meets
|
||||
the specified version constraints. You can use an _exact_ version constraint
|
||||
to ensure that Terraform will always select the same module version.
|
||||
|
||||
## Lock File Location
|
||||
|
||||
The dependency lock file is a file that belongs to the configuration as a
|
||||
whole, rather than to each separate module in the configuration. For that reason
|
||||
Terraform creates it and expects to find it in your current working directory
|
||||
when you run Terraform, which is also the directory containing the `.tf` files
|
||||
for the root module of your configuration.
|
||||
|
||||
The lock file is always named `.terraform.lock.hcl`, and this name is intended
|
||||
to signify that it is a lock file for various items that Terraform caches in
|
||||
the `.terraform` subdirectory of your working directory.
|
||||
|
||||
Terraform automatically creates or updates the dependency lock file each time
|
||||
you run [the `terraform init` command](/docs/commands/init.html). You should
|
||||
include this file in your version control repository so that you can discuss
|
||||
potential changes to your external dependencies via code review, just as you
|
||||
would discuss potential changes to your configuration itself.
|
||||
|
||||
The dependency lock file uses the same low-level syntax as the main Terraform
|
||||
language, but the dependency lock file is not itself a Terraform language
|
||||
configuration file. It is named with the suffix `.hcl` instead of `.tf` in
|
||||
order to signify that difference.
|
||||
|
||||
## Dependency Installation Behavior
|
||||
|
||||
When `terraform init` is working on installing all of the providers needed for
|
||||
a configuration, Terraform considers both the version constraints in the
|
||||
configuration _and_ the version selections recorded in the lock file.
|
||||
|
||||
If a particular provider has no existing recorded selection, Terraform will
|
||||
select the newest available version that matches the given version constraint,
|
||||
and then update the lock file to include that selection.
|
||||
|
||||
If a particular provider already has a selection recorded in the lock file,
|
||||
Terraform will always re-select that version for installation, even if a
|
||||
newer version has become available. You can override that behavior by adding
|
||||
the `-upgrade` option when you run `terraform init`, in which case Terraform
|
||||
will disregard the existing selections and once again select the newest
|
||||
available version matching the version constraint.
|
||||
|
||||
If a particular `terraform init` call makes changes to the lock file, Terraform
|
||||
will mention that as part of its output:
|
||||
|
||||
```
|
||||
Terraform has made some changes to the provider dependency selections recorded
|
||||
in the .terraform.lock.hcl file. Review those changes and commit them to your
|
||||
version control system if they represent changes you intended to make.
|
||||
```
|
||||
|
||||
When you see this message, you can use your version control system to
|
||||
[review the changes Terraform has proposed in the file](#understanding-lock-file-changes),
|
||||
and if they represent changes you made intentionally you can send the change
|
||||
through your team's usual code review process.
|
||||
|
||||
### Checksum verification
|
||||
|
||||
Terraform will also verify that each package it installs matches at least one
|
||||
of the checksums it previously recorded in the lock file, if any, returning an
|
||||
error if none of the checksums match:
|
||||
|
||||
```
|
||||
Error: Failed to install provider
|
||||
|
||||
Error while installing hashicorp/azurerm v2.1.0: the current package for
|
||||
registry.terraform.io/hashicorp/azurerm 2.1.0 doesn't match any of the
|
||||
checksums previously recorded in the dependency lock file.
|
||||
```
|
||||
|
||||
This checksum verification is intended to represent a
|
||||
_[trust on first use](https://en.wikipedia.org/wiki/Trust_on_first_use)_
|
||||
approach. When you add a new provider for the first time you can verify it
|
||||
in whatever way you choose or any way you are required to by relevant
|
||||
regulations, and then trust that Terraform will raise an error if a future
|
||||
run of `terraform init` encounters a non-matching package for the same
|
||||
provider version.
|
||||
|
||||
There are two special considerations with the "trust on first use" model:
|
||||
|
||||
* If you install a provider from an origin registry which provides checksums
|
||||
that are signed with a cryptographic signature, Terraform will treat all
|
||||
of the signed checksums as valid as long as one checksum matches. The lock
|
||||
file will therefore include checksums for both the package you installed for
|
||||
your current platform _and_ any other packages that might be available for
|
||||
other platforms.
|
||||
|
||||
In this case, the `terraform init` output will include the fingerprint of
|
||||
the key that signed the checksums, with a message like
|
||||
`(signed by a HashiCorp partner, key ID DC9FC6B1FCE47986)`. You may wish to
|
||||
confirm that you trust the holder of the given key before committing the
|
||||
lock file containing the signed checksums, or to retrieve and verify the
|
||||
full set of available packages for the given provider version.
|
||||
|
||||
* If you install a provider for the first time using an alternative
|
||||
installation method, such as a filesystem or network mirror, Terraform will
|
||||
not be able to verify the checksums for any platform other than the one
|
||||
where you ran `terraform init`, and so it will not record the checksums
|
||||
for other platforms and so the configuration will not be usable on any other
|
||||
platform.
|
||||
|
||||
To avoid this problem you can pre-populate checksums for a variety of
|
||||
different platforms in your lock file using
|
||||
[the `terraform providers lock` command](/docs/commands/providers/lock.html),
|
||||
which will then allow future calls to `terraform init` to verify that the
|
||||
packages available in your chosen mirror match the official packages from
|
||||
the provider's origin registry.
|
||||
|
||||
## Understanding Lock File Changes
|
||||
|
||||
Because the dependency lock file is primarily maintained automatically by
|
||||
Terraform itself, rather than being updated manually by you or your team,
|
||||
your version control system may show you that the file has changed.
|
||||
|
||||
There are a few different types of changes that Terraform can potentially make
|
||||
to your lock file, which you may need to understand in order to review the
|
||||
propsed changes. The following sections will describe these common situations.
|
||||
|
||||
### Dependency on a new provider
|
||||
|
||||
If you add a new entry to the
|
||||
[provider requirements](./provider-requirements.html) for any module in your
|
||||
configuration, or if you add an external module that includes a new provider
|
||||
dependency itself, `terraform init` will respond to that by selecting the
|
||||
newest version of that provider which meets all of the version constraints
|
||||
in the configuration, and it will record its decision as a new `provider`
|
||||
block in the dependency lock file.
|
||||
|
||||
```diff
|
||||
--- .terraform.lock.hcl 2020-10-07 16:12:07.539570634 -0700
|
||||
+++ .terraform.lock.hcl 2020-10-07 16:12:15.267487237 -0700
|
||||
@@ -6,6 +6,26 @@
|
||||
]
|
||||
}
|
||||
|
||||
+provider "registry.terraform.io/hashicorp/azurerm" {
|
||||
+ version = "2.30.0"
|
||||
+ constraints = "~> 2.12"
|
||||
+ hashes = [
|
||||
+ "h1:FJwsuowaG5CIdZ0WQyFZH9r6kIJeRKts9+GcRsTz1+Y=",
|
||||
+ "h1:c/ntSXrDYM1mUir2KufijYebPcwKqS9CRGd3duDSGfY=",
|
||||
+ "h1:yre4Ph76g9H84MbuhZ2z5MuldjSA4FsrX6538O7PCcY=",
|
||||
+ "zh:04f0a50bb2ba92f3bea6f0a9e549ace5a4c13ef0cbb6975494cac0ef7d4acb43",
|
||||
+ "zh:2082e12548ebcdd6fd73580e83f626ed4ed13f8cdfd51205d8696ffe54f30734",
|
||||
+ "zh:246bcc449e9a92679fb30f3c0a77f05513886565e2dcc66b16c4486f51533064",
|
||||
+ "zh:24de3930625ac9014594d79bfa42d600eca65e9022b9668b54bfd0d924e21d14",
|
||||
+ "zh:2a22893a576ff6f268d9bf81cf4a56406f7ba79f77826f6df51ee787f6d2840a",
|
||||
+ "zh:2b27485e19c2aaa9f15f29c4cff46154a9720647610171e30fc6c18ddc42ec28",
|
||||
+ "zh:435f24ce1fb2b63f7f02aa3c84ac29c5757cd29ec4d297ed0618423387fe7bd4",
|
||||
+ "zh:7d99725923de5240ff8b34b5510569aa4ebdc0bdb27b7bac2aa911a8037a3893",
|
||||
+ "zh:7e3b5d0af3b7411dd9dc65ec9ab6caee8c191aee0fa7f20fc4f51716e67f50c0",
|
||||
+ "zh:da0af4552bef5a29b88f6a0718253f3bf71ce471c959816eb7602b0dadb469ca",
|
||||
+ ]
|
||||
+}
|
||||
+
|
||||
provider "registry.terraform.io/newrelic/newrelic" {
|
||||
version = "2.1.2"
|
||||
constraints = "~> 2.1.1"
|
||||
```
|
||||
|
||||
The new lock file entry records several pieces of information:
|
||||
|
||||
* `version`: the exact version that Terraform selected based on the version
|
||||
constraints in the configuration.
|
||||
* `constraints`: all of the version constraints that Terraform considered when
|
||||
making this selection. (Terraform doesn't actually use this information to
|
||||
make installation decisions, but includes it to help explain to human readers
|
||||
how the previous decision was made.)
|
||||
* `hashes`: a number of checksums that are all considered to be valid for
|
||||
packages implementing the selected version of this provider on different
|
||||
platforms. The meaning of these hashes is explained more under
|
||||
_[New provider package checksums](#new-provider-package-checksums)_ below.
|
||||
|
||||
### New version of an existing provider
|
||||
|
||||
If you run `terraform init -upgrade` to ask Terraform to consider newer provider
|
||||
versions that still match the configured version constraints, Terraform may
|
||||
then select a newer version for a provider and update its existing `provider`
|
||||
block to reflect that change.
|
||||
|
||||
```diff
|
||||
--- .terraform.lock.hcl 2020-10-07 16:44:25.819579509 -0700
|
||||
+++ .terraform.lock.hcl 2020-10-07 16:43:42.785665945 -0700
|
||||
@@ -7,22 +7,22 @@
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/azurerm" {
|
||||
- version = "2.1.0"
|
||||
- constraints = "~> 2.1.0"
|
||||
+ version = "2.0.0"
|
||||
+ constraints = "2.0.0"
|
||||
hashes = [
|
||||
- "h1:EOJImaEaVThWasdqnJjfYc6/P8N/MRAq1J7avx5ZbV4=",
|
||||
- "zh:0015b491cf9151235e57e35ea6b89381098e61bd923f56dffc86026d58748880",
|
||||
- "zh:4c5682ba1e0fc7e2e602d3f103af1638f868c31fe80cc1a884a97f6dad6e1c11",
|
||||
- "zh:57bac885b108c91ade4a41590062309c832c9ab6bf6a68046161636fcaef1499",
|
||||
- "zh:5810d48f574c0e363c969b3f45276369c8f0a35b34d6202fdfceb7b85b3ac597",
|
||||
- "zh:5c6e37a44462b8662cf9bdd29ce30523712a45c27c5d4711738705be0785db41",
|
||||
- "zh:64548940a3387aa3a752e709ee9eb9982fa820fe60eb60e5f212cc1d2c58549e",
|
||||
- "zh:7f46749163da17330bbb5293dc825333c86304baa0a7c6256650ac536b4567c8",
|
||||
- "zh:8f8970f2df75ac43ffdd112055ee069d8bd1030f7eb4367cc4cf494a1fa802c3",
|
||||
- "zh:9ad693d00dc5d7d455d06faba70e716bce727c6706f7293288e87fd7956b8fe0",
|
||||
- "zh:b6e3cb55e6aec62b47edd0d2bd5e14bd6a2bcfdac65930a6e9e819934734c57b",
|
||||
- "zh:d6a3f3b9b05c28ecf3919e9e7afa185805a6d7442fc4b3eedba749c2731d1f0e",
|
||||
- "zh:d81fb624a357c57c7ea457ce543d865b39b12f26c2edd58a2f7cd43326c91010",
|
||||
+ "h1:bigGXBoRbp7dv79bEEn+aaju8575qEXHQ57XHVPJeB8=",
|
||||
+ "zh:09c603c8904ca4a5bc19e82335afbc2837dcc4bee81e395f9daccef2f2cba1c8",
|
||||
+ "zh:194a919d4836d6c6d4ce598d0c66cce00ddc0d0b5c40d01bb32789964d818b42",
|
||||
+ "zh:1f269627df4e266c4e0ef9ee2486534caa3c8bea91a201feda4bca525005aa0a",
|
||||
+ "zh:2bae3071bd5f8e553355c4b3a547d6efe1774a828142b762e9a4e85f79be7f63",
|
||||
+ "zh:6c98dfa5c3468e8d02e2b3af7c4a8a14a5d469ce5a642909643b413a17ca338b",
|
||||
+ "zh:7af78f61666fd45fbf428161c061ea2623162d601b79dc71d6a5158756853ffa",
|
||||
+ "zh:883c2df86ae9ba2a5c167cf5c2c7deca0239171a224d6d335f0fd6dd9c283830",
|
||||
+ "zh:a2028379078577d8ff5ecfca6e8a8b25a25ffb1686de0ee52a7fe8011783488b",
|
||||
+ "zh:abe6ef399552fd3861a454a839cd978c1d15735658fdc00f9054435aff0f4620",
|
||||
+ "zh:c30b1bf14077913c3cdf34979b1434dbb1353cb5995eb3956b191c50538b64a9",
|
||||
+ "zh:ca64ae2ad9793e5631e3b0b9327f7cb22cb5d8e9de57be7d85821791b1d5a375",
|
||||
+ "zh:fffe56904a38109bb8d613b02808a177c3ddfac19f03b3aac799281fea38f475",
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The primary effect of selecting a new provider version is to change the
|
||||
value of `version` in the `provider` block. If the upgrade came along with
|
||||
a change to the configured version constraints, Terraform will also record
|
||||
that change in the `constraints` value.
|
||||
|
||||
Because each version has its own set of distribution packages, switching to
|
||||
a new version will also tend to replace all of the values in `hashes`, to
|
||||
reflect the checksums of the packages for the new version.
|
||||
|
||||
### New provider package checksums
|
||||
|
||||
A more subtle change you may see in a `provider` block is the addition of
|
||||
new checksums that were not previously recorded, even though nothing else
|
||||
in the `provider` block has changed:
|
||||
|
||||
```diff
|
||||
--- .terraform.lock.hcl 2020-10-07 17:24:23.397892140 -0700
|
||||
+++ .terraform.lock.hcl 2020-10-07 17:24:57.423130253 -0700
|
||||
@@ -10,6 +10,7 @@
|
||||
version = "2.1.0"
|
||||
constraints = "~> 2.1.0"
|
||||
hashes = [
|
||||
+ "h1:1xvaS5D8B8t6J6XmXxX8spo97tAzjhacjedFX1B47Fk=",
|
||||
"h1:EOJImaEaVThWasdqnJjfYc6/P8N/MRAq1J7avx5ZbV4=",
|
||||
"zh:0015b491cf9151235e57e35ea6b89381098e61bd923f56dffc86026d58748880",
|
||||
"zh:4c5682ba1e0fc7e2e602d3f103af1638f868c31fe80cc1a884a97f6dad6e1c11",
|
||||
```
|
||||
|
||||
The addition of a new checksum into the `hashes` value represents Terraform
|
||||
gradually transitioning between different _hashing schemes_. The `h1:` and
|
||||
`zh:` prefixes on these values represent different hashing schemes, each
|
||||
of which represents calculating a checksum using a different algorithm.
|
||||
We may occasionally introduce new hashing schemes if we learn of limitations
|
||||
in the existing schemes or if a new scheme offers some considerable
|
||||
additional benefit.
|
||||
|
||||
The two hashing schemes currently supported are:
|
||||
|
||||
* `zh:`: a mnemonic for "zip hash", this is a legacy hash format which is
|
||||
part of the Terraform provider registry protocol and is therefore used for
|
||||
providers that you install directly from an origin registry.
|
||||
|
||||
This hashing scheme captures a SHA256 hash of each of the official `.zip`
|
||||
packages indexed in the origin registry. This is an effective scheme for
|
||||
verifying the official release packages when installed from a registry, but
|
||||
it's not suitable for verifying packages that come from other
|
||||
[provider installation methods](/docs/commands/cli-config.html#provider-installation),
|
||||
such as filesystem mirrors using the unpacked directory layout.
|
||||
|
||||
* `h1:`: a mnemonic for "hash scheme 1", which is the current preferred hashing
|
||||
scheme.
|
||||
|
||||
Hash scheme 1 is also a SHA256 hash, but is one computed from the _contents_
|
||||
of the provider distribution package, rather than of the `.zip` archive
|
||||
it's contained within. This scheme therefore has the advantage that it can
|
||||
be calculated for an official `.zip` file, an unpacked directory with the
|
||||
same contents, or a recompressed `.zip` file which contains the same files
|
||||
but potentially different metadata or compression schemes.
|
||||
|
||||
Due to the limited scope of the `zh:` scheme, Terraform will
|
||||
opportunistically add in the corresponding `h1:` checksums as it learns
|
||||
of them, which is what caused the addition of a second `h1:` checksum
|
||||
in the example change shown above.
|
||||
|
||||
Terraform will add a new hash to an existing provider only if the hash is
|
||||
calculated from a package that _also_ matches one of the existing hashes. In
|
||||
the above example, Terraform installed a `hashicorp/azurerm` package for a
|
||||
different platform than that which produced the original `h1:` checksum, but was
|
||||
able to match it against one of the `zh:` checksums recorded previously.
|
||||
After confirming the `zh:` checksum match, Terraform then recorded the
|
||||
corresponding `h1:` checksum in order to gradually migrate from the old scheme
|
||||
to the new scheme.
|
||||
|
||||
When installing a particular provider for the first time (where there is no
|
||||
existing `provider` block for it), Terraform will pre-populate the `hashes`
|
||||
value with any checksums that are covered by the provider developer's
|
||||
cryptographic signature, which usually covers all of the available packages
|
||||
for that provider version across all supported platforms. However, because
|
||||
the provider registry protocol still uses the `zh:` scheme, the initial set
|
||||
will consist primarily of hashes using that scheme, which Terraform will then
|
||||
upgrade opportunistically as you install the packages on different platforms.
|
||||
|
||||
If you wish to avoid ongoing additions of new `h1:` hashes as you work with
|
||||
your configuration on new target platforms, or if you are installing providers
|
||||
from a mirror that therefore can't provide official signed checksums, you
|
||||
can ask Terraform to pre-populate hashes for a chosen set of platforms
|
||||
using
|
||||
[the `terraform providers lock` command](/docs/commands/providers/lock.html):
|
||||
|
||||
```
|
||||
terraform providers lock \
|
||||
-platform=linux_arm64 \
|
||||
-platform=linux_amd64 \
|
||||
-platform=darwin_amd64 \
|
||||
-platform=windows_amd64
|
||||
```
|
||||
|
||||
The above command will download and verify the official packages for all of
|
||||
the required providers across all four of the given platforms, and then record
|
||||
both `zh:` and `h1:` checksums for each of them in the lock file, thus avoiding
|
||||
the case where Terraform will learn about a `h1:` equivalent only at a later
|
||||
time. See the `terraform providers lock` documentation for more information on
|
||||
this command.
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Conditional Expressions - Configuration Language"
|
||||
---
|
||||
|
||||
# Conditional Expressions
|
||||
|
||||
> **Hands-on:** Try the [Create Dynamic Expressions](https://learn.hashicorp.com/tutorials/terraform/expressions?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
A _conditional expression_ uses the value of a bool expression to select one of
|
||||
two values.
|
||||
|
||||
The syntax of a conditional expression is as follows:
|
||||
|
||||
```hcl
|
||||
condition ? true_val : false_val
|
||||
```
|
||||
|
||||
If `condition` is `true` then the result is `true_val`. If `condition` is
|
||||
`false` then the result is `false_val`.
|
||||
|
||||
A common use of conditional expressions is to define defaults to replace
|
||||
invalid values:
|
||||
|
||||
```
|
||||
var.a != "" ? var.a : "default-a"
|
||||
```
|
||||
|
||||
If `var.a` is an empty string then the result is `"default-a"`, but otherwise
|
||||
it is the actual value of `var.a`.
|
||||
|
||||
## Conditions
|
||||
|
||||
The condition can be any expression that resolves to a boolean value. This will
|
||||
usually be an expression that uses the equality, comparison, or logical
|
||||
operators.
|
||||
|
||||
## Result Types
|
||||
|
||||
The two result values may be of any type, but they must both
|
||||
be of the _same_ type so that Terraform can determine what type the whole
|
||||
conditional expression will return without knowing the condition value.
|
||||
|
||||
If the two result expressions don't produce the same type then Terraform 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
|
||||
decimal digits:
|
||||
|
||||
```hcl
|
||||
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
|
||||
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`](../functions/tostring.html) to explicitly convert a number to
|
||||
a string.
|
||||
|
||||
```hcl
|
||||
var.example ? tostring(12) : "hello"
|
||||
```
|
||||
@@ -1,154 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Dynamic Blocks - Configuration Language"
|
||||
---
|
||||
|
||||
|
||||
# `dynamic` Blocks
|
||||
|
||||
Within top-level block constructs like resources, expressions can usually be
|
||||
used only when assigning a value to an argument using the `name = expression`
|
||||
form. This covers many uses, but some resource types include repeatable _nested
|
||||
blocks_ in their arguments, which typically represent separate objects that
|
||||
are related to (or embedded within) the containing object:
|
||||
|
||||
```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](for.html), 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.
|
||||
|
||||
## Multi-level Nested Block Structures
|
||||
|
||||
Some providers define resource types that include multiple levels of blocks
|
||||
nested inside one another. You can generate these nested structures dynamically
|
||||
when necessary by nesting `dynamic` blocks in the `content` portion of other
|
||||
`dynamic` blocks.
|
||||
|
||||
For example, a module might accept a complex data structure like the following:
|
||||
|
||||
```hcl
|
||||
variable "load_balancer_origin_groups" {
|
||||
type = map(object({
|
||||
origins = set(object({
|
||||
hostname = string
|
||||
}))
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
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`
|
||||
blocks:
|
||||
|
||||
```hcl
|
||||
dynamic "origin_group" {
|
||||
for_each = var.load_balancer_origin_groups
|
||||
content {
|
||||
name = origin_group.key
|
||||
|
||||
dynamic "origin" {
|
||||
for_each = origin_group.value.origins
|
||||
content {
|
||||
hostname = origin.value.hostname
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When using nested `dynamic` blocks it's particularly important to pay attention
|
||||
to the iterator symbol for each block. In the above example,
|
||||
`origin_group.value` refers to the current element of the outer block, while
|
||||
`origin.value` refers to the current element of the inner block.
|
||||
|
||||
If a particular resource type defines nested blocks that have the same type
|
||||
name as one of their parents, you can use the `iterator` argument in each of
|
||||
`dynamic` blocks to choose a different iterator symbol that makes the two
|
||||
easier to distinguish.
|
||||
|
||||
## 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.
|
||||
|
||||
If you find yourself defining most or all of a `resource` block's arguments and
|
||||
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](/docs/modules/#when-to-write-a-module)
|
||||
and [Module Composition](/docs/modules/composition.html).
|
||||
@@ -1,209 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "For Expressions - Configuration Language"
|
||||
---
|
||||
|
||||
# `for` Expressions
|
||||
|
||||
A _`for` expression_ creates a complex type value by transforming
|
||||
another complex type value. Each element in the input value
|
||||
can correspond to either one or zero values in the result, and an arbitrary
|
||||
expression can be used to transform each input element into an output element.
|
||||
|
||||
For example, if `var.list` were a list of strings, then the following expression
|
||||
would produce a tuple of strings with all-uppercase letters:
|
||||
|
||||
```hcl
|
||||
[for s in var.list : upper(s)]
|
||||
```
|
||||
|
||||
This `for` expression iterates over each element of `var.list`, and then
|
||||
evaluates the expression `upper(s)` with `s` set to each respective element.
|
||||
It then builds a new tuple value with all of the results of executing that
|
||||
expression in the same order.
|
||||
|
||||
## Input Types
|
||||
|
||||
A `for` expression's input (given after the `in` keyword) can be a list,
|
||||
a set, a tuple, a map, or an object.
|
||||
|
||||
The above example showed a `for` expression with only a single temporary
|
||||
symbol `s`, but a `for` expression can optionally declare a pair of temporary
|
||||
symbols in order to use the key or index of each item too:
|
||||
|
||||
```hcl
|
||||
[for k, v in var.map : length(k) + length(v)]
|
||||
```
|
||||
|
||||
For a map or object type, like above, the `k` symbol refers to the key or
|
||||
attribute name of the current element. You can also use the two-symbol form
|
||||
with lists and tuples, in which case the additional symbol is the index
|
||||
of each element starting from zero, which conventionally has the symbol name
|
||||
`i` or `idx` unless it's helpful to choose a more specific name:
|
||||
|
||||
```hcl
|
||||
[for i, v in var.list : "${i} is ${v}"]
|
||||
```
|
||||
|
||||
The index or key symbol is always optional. If you specify only a single
|
||||
symbol after the `for` keyword then that symbol will always represent the
|
||||
_value_ of each element of the input collection.
|
||||
|
||||
## Result Types
|
||||
|
||||
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 you use `{` and
|
||||
`}` instead, the result is an object and you must provide two result
|
||||
expressions that are 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.
|
||||
For example, the resulting value might be as follows:
|
||||
|
||||
```hcl
|
||||
{
|
||||
foo = "FOO"
|
||||
bar = "BAR"
|
||||
baz = "BAZ"
|
||||
}
|
||||
```
|
||||
|
||||
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
|
||||
typically use the results in locations where lists, maps, and sets are expected.
|
||||
|
||||
## Filtering Elements
|
||||
|
||||
A `for` expression can also include an optional `if` clause to filter elements
|
||||
from the source collection, producing a value with fewer elements than
|
||||
the source value:
|
||||
|
||||
```
|
||||
[for s in var.list : upper(s) if s != ""]
|
||||
```
|
||||
|
||||
One common reason for filtering collections in `for` expressions is to split
|
||||
a single source collection into two separate collections based on some
|
||||
criteria. For example, if the input `var.users` is a map of objects where the
|
||||
objects each have an attribute `is_admin` then you may wish to produce separate
|
||||
maps with admin vs non-admin objects:
|
||||
|
||||
```hcl
|
||||
variable "users" {
|
||||
type = map(object({
|
||||
is_admin = boolean
|
||||
}))
|
||||
}
|
||||
|
||||
locals {
|
||||
admin_users = {
|
||||
for name, user in var.users : name => user
|
||||
if user.is_admin
|
||||
}
|
||||
regular_users = {
|
||||
for name, user in var.users : name => user
|
||||
if !user.is_admin
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Element Ordering
|
||||
|
||||
Because `for` expressions can convert from unordered types (maps, objects, sets)
|
||||
to unordered types (lists, tuples), Terraform 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,
|
||||
using lexical sorting.
|
||||
|
||||
For sets of strings, Terraform 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 of Terraform. For that reason, we recommend converting the
|
||||
result of such an expression to itself be a set so that it's clear elsewhere
|
||||
in the configuration that the result is unordered. You can use
|
||||
[the `toset` function](../functions/toset.html)
|
||||
to concisely convert a `for` expression result to be of a set type.
|
||||
|
||||
```hcl
|
||||
toset([for e in var.set : e.example])
|
||||
```
|
||||
|
||||
## Grouping Results
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
multiple elements per key.
|
||||
|
||||
To activate grouping mode, add the symbol `...` after the value expression.
|
||||
For example:
|
||||
|
||||
```hcl
|
||||
variable "users" {
|
||||
type = map(object({
|
||||
role = string
|
||||
}))
|
||||
}
|
||||
|
||||
locals {
|
||||
users_by_role = {
|
||||
for name, user in var.users : user.role => name...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The above represents a situation where a module expects a map describing
|
||||
various users who each have a single "role", where the map keys are usernames.
|
||||
The usernames are guaranteed unique because they are map keys in the input,
|
||||
but many users may all share a single role name.
|
||||
|
||||
The `local.users_by_role` expression inverts the input map so that the keys
|
||||
are the role names and the values are usernames, but the expression is in
|
||||
grouping mode (due to the `...` after `name`) and so the result will be a
|
||||
map of lists of strings, such as the following:
|
||||
|
||||
```hcl
|
||||
{
|
||||
"admin": [
|
||||
"ps",
|
||||
],
|
||||
"maintainer": [
|
||||
"am",
|
||||
"jb",
|
||||
"kl",
|
||||
"ma",
|
||||
],
|
||||
"viewer": [
|
||||
"st",
|
||||
"zq",
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
Due to [the element ordering rules](#element-ordering), Terraform 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.
|
||||
|
||||
## Repeated Configuration Blocks
|
||||
|
||||
The `for` expressions mechanism is for constructing collection values from
|
||||
other collection values within expressions, which you can then assign to
|
||||
individual resource arguments that expect complex values.
|
||||
|
||||
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 generated nested blocks using `for` expressions, but you _can_
|
||||
generate nested blocks for a resource dynamically using
|
||||
[`dynamic` blocks](dynamic-blocks.html).
|
||||
@@ -1,112 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Function Calls - Configuration Language"
|
||||
---
|
||||
|
||||
# Function Calls
|
||||
|
||||
> **Hands-on:** Try the [Perform Dynamic Operations with Functions](https://learn.hashicorp.com/tutorials/terraform/functions?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
The Terraform language has a number of
|
||||
[built-in functions](/docs/configuration/functions.html) that can be used
|
||||
in expressions to transform and combine values. These
|
||||
are similar to the operators but all follow a common syntax:
|
||||
|
||||
```hcl
|
||||
<FUNCTION NAME>(<ARGUMENT 1>, <ARGUMENT 2>)
|
||||
```
|
||||
|
||||
The function name specifies which function to call. Each defined function
|
||||
expects a specific number of arguments with specific value types, and returns a
|
||||
specific value type as a result.
|
||||
|
||||
Some functions take an arbitrary number of arguments. For example, the `min`
|
||||
function takes any amount of number arguments and returns the one that is
|
||||
numerically smallest:
|
||||
|
||||
```hcl
|
||||
min(55, 3453, 2)
|
||||
```
|
||||
|
||||
A function call expression evaluates to the function's return value.
|
||||
|
||||
## Available Functions
|
||||
|
||||
For a full list of available functions, see
|
||||
[the function reference](/docs/configuration/functions.html).
|
||||
|
||||
## 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.
|
||||
|
||||
## Using Sensitive Data as Function Arguments
|
||||
|
||||
When using sensitive data, such as [an input variable](https://www.terraform.io/docs/configuration/variables.html#suppressing-values-in-cli-output)
|
||||
or [an output defined](https://www.terraform.io/docs/configuration/outputs.html#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
|
||||
called. For example, passing an object containing a sensitive input variable to
|
||||
the `keys()` function will result in a list that is sensitive:
|
||||
|
||||
```shell
|
||||
> local.baz
|
||||
{
|
||||
"a" = (sensitive)
|
||||
"b" = "dog"
|
||||
}
|
||||
> keys(local.baz)
|
||||
(sensitive)
|
||||
```
|
||||
|
||||
## When Terraform Calls Functions
|
||||
|
||||
Most of Terraform'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.
|
||||
|
||||
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.
|
||||
|
||||
The small set of special functions includes
|
||||
[`file`](../functions/file.html),
|
||||
[`templatefile`](../functions/templatefile.html),
|
||||
[`timestamp`](../functions/timestamp.html),
|
||||
and [`uuid`](../functions/uuid.html).
|
||||
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
|
||||
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
|
||||
result which differs on each call. Without any special behavior these would
|
||||
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.
|
||||
|
||||
For that reason, Terraform arranges for both of those functions to produce
|
||||
[unknown value](references.html#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.
|
||||
|
||||
For more details on the behavior of these functions, refer to their own
|
||||
documentation pages.
|
||||
@@ -1,69 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Expressions - Configuration Language"
|
||||
---
|
||||
|
||||
# Expressions
|
||||
|
||||
> **Hands-on:** Try the [Create Dynamic Expressions](https://learn.hashicorp.com/tutorials/terraform/expressions?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
_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/references.html#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](/docs/commands/console.html).
|
||||
|
||||
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/operators.html)
|
||||
documents the arithmetic, comparison, and logical operators.
|
||||
|
||||
- [Function Calls](/docs/configuration/expressions/function-calls.html)
|
||||
documents the syntax for calling Terraform's built-in functions.
|
||||
|
||||
- [Conditional Expressions](/docs/configuration/expressions/conditionals.html)
|
||||
documents the `<CONDITION> ? <TRUE VAL> : <FALSE VAL>` expression, which
|
||||
chooses between two values based on a bool condition.
|
||||
|
||||
- [For Expressions](/docs/configuration/expressions/for.html)
|
||||
documents expressions like `[for s in var.list : upper(s)]`, which can
|
||||
transform a complex type value into another complex type value.
|
||||
|
||||
- [Splat Expressions](/docs/configuration/expressions/splat.html)
|
||||
documents expressions like `var.list[*].id`, which can extract simpler
|
||||
collections from more complicated expressions.
|
||||
|
||||
- [Dynamic Blocks](/docs/configuration/expressions/dynamic-blocks.html)
|
||||
documents a way to create multiple repeatable nested blocks within a resource
|
||||
or other construct.
|
||||
|
||||
- [Type Constraints](/docs/configuration/types.html)
|
||||
documents the syntax for referring to a type, rather than a value of that
|
||||
type. Input variables expect this syntax in their `type` argument.
|
||||
|
||||
- [Version Constraints](/docs/configuration/version-constraints.html)
|
||||
documents the syntax of special strings that define a set of allowed software
|
||||
versions. Terraform uses version constraints in several places.
|
||||
@@ -1,103 +0,0 @@
|
||||
---
|
||||
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. `||`
|
||||
|
||||
Use parentheses to override the default order of operations. Without
|
||||
parentheses, higher levels will be evaluated first, so Terraform 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
|
||||
values to the required type automatically, or will produce an error message
|
||||
if automatic conversion is impossible.
|
||||
|
||||
## 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`.
|
||||
|
||||
Terraform supports some other less-common numeric operations as
|
||||
[functions](function-calls.html). For example, you can calculate exponents
|
||||
using
|
||||
[the `pow` function](../functions/pow.html).
|
||||
|
||||
## 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`.
|
||||
|
||||
Because the equality operators require both arguments to be of exactly the
|
||||
same type in order to decide equality, we recommend using these operators only
|
||||
with values of primitive types or using explicit type conversion functions
|
||||
to indicate which type you are intending to use for comparison.
|
||||
|
||||
Comparisons between structural types may produce surprising results if you
|
||||
are not sure about the types of each of the arguments. For example,
|
||||
`var.list == []` may seem like it would return `true` if `var.list` were an
|
||||
empty list, but `[]` actually builds a value of type `tuple([])` and so the
|
||||
two values can never match. In this situation it's often clearer to write
|
||||
`length(var.list) == 0` instead.
|
||||
|
||||
## 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`.
|
||||
|
||||
Terraform 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.
|
||||
@@ -1,359 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "References to Values - Configuration Language"
|
||||
---
|
||||
|
||||
# References to Named Values
|
||||
|
||||
> **Hands-on:** Try the [Create Dynamic Expressions](https://learn.hashicorp.com/tutorials/terraform/expressions?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
Terraform makes several kinds of named values available. Each of these names is
|
||||
an expression that references the associated value; you can use them as
|
||||
standalone expressions, or combine them with other expressions to compute new
|
||||
values.
|
||||
|
||||
## Types of Named Values
|
||||
|
||||
The main kinds of named values available in Terraform are:
|
||||
|
||||
- Resources
|
||||
- Input variables
|
||||
- Local values
|
||||
- Child module outputs
|
||||
- Data sources
|
||||
- Filesystem and workspace info
|
||||
- Block-local values
|
||||
|
||||
The sections below explain each kind of named value in detail.
|
||||
|
||||
Although many of these names use dot-separated paths that resemble
|
||||
[attribute notation](./types.html#indices-and-attributes) for elements of object values, they are not
|
||||
implemented as real objects. This means you must use them exactly as written:
|
||||
you cannot use square-bracket notation to replace the dot-separated paths, and
|
||||
you cannot iterate over the "parent object" of a named entity; for example, you
|
||||
cannot use `aws_instance` in a `for` expression to iterate over every AWS
|
||||
instance resource.
|
||||
|
||||
### Resources
|
||||
|
||||
`<RESOURCE TYPE>.<NAME>` represents a [managed resource](/docs/configuration/blocks/resources/index.html) of
|
||||
the given type and name.
|
||||
|
||||
The value of a resource reference can vary, depending on whether the resource
|
||||
uses `count` or `for_each`:
|
||||
|
||||
- If the resource doesn't use `count` or `for_each`, the reference's value is an
|
||||
object. The resource's attributes are elements of the object, and you can
|
||||
access them using [dot or square bracket notation](./types.html#indices-and-attributes).
|
||||
- If the resource has the `count` argument set, the reference's value is a
|
||||
_list_ of objects representing its instances.
|
||||
- If the resource has the `for_each` argument set, the reference's value is a
|
||||
_map_ of objects representing its instances.
|
||||
|
||||
Any named value that does not match another pattern listed below
|
||||
will be interpreted by Terraform as a reference to a managed resource.
|
||||
|
||||
For more information about how to use resource references, see
|
||||
[references to resource attributes](#references-to-resource-attributes) below.
|
||||
|
||||
### Input Variables
|
||||
|
||||
`var.<NAME>` is the value of the [input variable](/docs/configuration/variables.html) of the given name.
|
||||
|
||||
If the variable has a type constraint (`type` argument) as part of its
|
||||
declaration, Terraform 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
|
||||
always produce a value that conforms to the type constraint, even if the caller
|
||||
provided a value of a different type that was automatically converted.
|
||||
|
||||
In particular, note that if you define a variable as being of an object type
|
||||
with particular attributes then only _those specific attributes_ will be
|
||||
available in expressions elsewhere in the module, even if the caller actually
|
||||
passed in a value with additional attributes. You must define in the type
|
||||
constraint all of the attributes you intend to use elsewhere in your module.
|
||||
|
||||
### Local Values
|
||||
|
||||
`local.<NAME>` is the value of the [local value](/docs/configuration/locals.html) 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.
|
||||
|
||||
### Child Module Outputs
|
||||
|
||||
`module.<MODULE NAME>` is an value representing the results of
|
||||
[a `module` block](../blocks/modules/).
|
||||
|
||||
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](../outputs.html), 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,
|
||||
and whose values are each objects with one attribute for each output value
|
||||
defined in the child module, each representing one module instance.
|
||||
|
||||
If the corresponding module uses `count` then the result is similar to for
|
||||
`for_each` except that the value is a _list_ with the requested number of
|
||||
elements, each one representing one module instance.
|
||||
|
||||
### Data Sources
|
||||
|
||||
`data.<DATA TYPE>.<NAME>` is an object representing a
|
||||
[data resource](/docs/configuration/data-sources.html) of the given data
|
||||
source type and name. If the resource has the `count` argument set, the value
|
||||
is a list of objects representing its instances. If the resource has the `for_each`
|
||||
argument set, the value is a map of objects representing its instances.
|
||||
|
||||
For more information, see
|
||||
[References to Resource Attributes](#references-to-resource-attributes), which
|
||||
also applies to data resources aside from the addition of the `data.` prefix
|
||||
to mark the reference as for a data resource.
|
||||
|
||||
### 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).
|
||||
|
||||
Use the values in this section carefully, because they include information
|
||||
about the context in which a configuration is being applied and so may
|
||||
inadvertently hurt the portability or composability of a module.
|
||||
|
||||
For example, if you use `path.cwd` directly to populate a path into a resource
|
||||
argument then later applying the same configuration from a different directory
|
||||
or on a different computer with a different directory structure will cause
|
||||
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
|
||||
object names, it may not be possible to call your module more than once in
|
||||
the same configuration.
|
||||
|
||||
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,
|
||||
or some other value if not:
|
||||
|
||||
```hcl
|
||||
module "example" {
|
||||
# ...
|
||||
|
||||
name_prefix = "app-${terraform-workspace}"
|
||||
}
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
The names in this section relate to top-level configuration blocks only.
|
||||
If you use [`dynamic` blocks](dynamic-blocks.html) 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.
|
||||
|
||||
## 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`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
|
||||
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)`.
|
||||
|
||||
### 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
|
||||
placeholder marker `(sensitive)` instead of the actual value when rendering
|
||||
a plan involving that attribute.
|
||||
|
||||
The treatment of these particular sensitive values is currently different than
|
||||
for values in
|
||||
[input variables](/docs/configuration/variables.html)
|
||||
and
|
||||
[output values](/docs/configuration/outputs.html)
|
||||
that have `sensitive = true` set. Sensitive resource attributes will be
|
||||
obscured in the plan when they appear directly, but other values that you
|
||||
_derive_ from a sensitive resource attribute will not themselves be considered
|
||||
sensitive, and so Terraform will include those derived values in its output
|
||||
without redacting them.
|
||||
|
||||
Terraform v0.14.0 and later has an
|
||||
[experimental feature](/docs/configuration/terraform.html#experimental-language-features)
|
||||
to treat resource attributes that are marked as sensitive in the same way as
|
||||
sensitive input variables and output values, so that Terraform will consider
|
||||
any derived values as sensitive too. You can activate that experiment for your
|
||||
module using the `provider_sensitive_attrs` experiment keyword:
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
experiments = [provider_sensitive_attrs]
|
||||
}
|
||||
```
|
||||
|
||||
The behavior of this experiment might change even in future patch releases of
|
||||
Terraform, so we don't recommend using this experiment in modules you use
|
||||
to describe production infrastructure.
|
||||
|
||||
If you enable this experiment and you have exported any sensitive resource
|
||||
attributes via your module's output values then you will see an error unless
|
||||
you also mark the output value as `sensitive = true`, confirming your intent
|
||||
to export it.
|
||||
@@ -1,128 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Splat Expressions - Configuration Language"
|
||||
---
|
||||
|
||||
# Splat Expressions
|
||||
|
||||
> **Hands-on:** Try the [Create Dynamic Expressions](https://learn.hashicorp.com/tutorials/terraform/expressions?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
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 with Maps
|
||||
|
||||
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](for.html).
|
||||
|
||||
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](/docs/configuration/meta-arguments/for_each.html#referring-to-instances).
|
||||
|
||||
## Single Values as Lists
|
||||
|
||||
Splat expressions have a special behavior when you apply them to a value that
|
||||
isn't a list, set, or tuple.
|
||||
|
||||
If the value is anything other than a null value then the splat expression will
|
||||
transform it into a single-element list, or more accurately a single-element
|
||||
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 absense of any value,
|
||||
to adapt the variable value to work with other Terraform language features that
|
||||
are designed to work with collections. For example:
|
||||
|
||||
```
|
||||
variable "website" {
|
||||
type = object({
|
||||
index_document = string
|
||||
error_document = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "example" {
|
||||
# ...
|
||||
|
||||
dynamic "website" {
|
||||
for_each = var.website[*]
|
||||
content {
|
||||
index_document = website.value.index_document
|
||||
error_document = website.value.error_document
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The above example uses a [`dynamic` block](dynamic-blocks.html), which
|
||||
generates zero or more nested blocks based on a collection value. The input
|
||||
variable `var.website` is defined as a single object that might be null,
|
||||
so the `dynamic` block's `for_each` expression uses `[*]` to ensure that
|
||||
there will be one block if the module caller sets the website argument, or
|
||||
zero blocks if the caller leaves it set to null.
|
||||
|
||||
This special behavior of splat expressions is not obvious to an unfamiliar
|
||||
reader, so we recommend using it only in `for_each` arguments and similar
|
||||
situations where the context implies working with a collection. Otherwise,
|
||||
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
|
||||
compatibility. This older variant is less useful than the modern form described
|
||||
above, and so we recommend against using it in new configurations.
|
||||
|
||||
The legacy "attribute-only" splat expressions use 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. 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,
|
||||
with `[*]`, to get the more consistent behavior.
|
||||
@@ -1,222 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Strings and Templates - Configuration Language"
|
||||
---
|
||||
|
||||
# Strings and Templates
|
||||
|
||||
String literals are the most complex kind of literal expression in
|
||||
Terraform, and also the most commonly used.
|
||||
|
||||
Terraform supports both a quoted syntax and a "heredoc" syntax for strings.
|
||||
Both of these syntaxes support template sequences for interpolating values and
|
||||
manipulating text.
|
||||
|
||||
## Quoted Strings
|
||||
|
||||
A quoted string is a series of characters delimited by straight double-quote
|
||||
characters (`"`).
|
||||
|
||||
```
|
||||
"hello"
|
||||
```
|
||||
|
||||
### Escape Sequences
|
||||
|
||||
In quoted strings, the backslash character serves as an escape
|
||||
sequence, with the following characters selecting the escape behavior:
|
||||
|
||||
| Sequence | Replacement |
|
||||
| ------------ | ----------------------------------------------------------------------------- |
|
||||
| `\n` | Newline |
|
||||
| `\r` | Carriage Return |
|
||||
| `\t` | Tab |
|
||||
| `\"` | Literal quote (without terminating the string) |
|
||||
| `\\` | Literal backslash |
|
||||
| `\uNNNN` | Unicode character from the basic multilingual plane (NNNN is four hex digits) |
|
||||
| `\UNNNNNNNN` | Unicode character from supplementary planes (NNNNNNNN is eight hex digits) |
|
||||
|
||||
There are also two special escape sequences that do not use backslashes:
|
||||
|
||||
| Sequence | Replacement |
|
||||
| --- | ---- |
|
||||
| `$${` | Literal `${`, without beginning an interpolation sequence. |
|
||||
| `%%{` | Literal `%{`, without beginning a template directive sequence. |
|
||||
|
||||
## Heredoc Strings
|
||||
|
||||
Terraform also supports a "heredoc" style of string literal inspired by Unix
|
||||
shell languages, which allows multi-line strings to be expressed more clearly.
|
||||
|
||||
```hcl
|
||||
<<EOT
|
||||
hello
|
||||
world
|
||||
EOT
|
||||
```
|
||||
|
||||
A heredoc string consists of:
|
||||
|
||||
- An opening sequence consisting of:
|
||||
- A heredoc marker (`<<` or `<<-` — two less-than signs, with an optional hyphen for indented heredocs)
|
||||
- A delimiter word of your own choosing
|
||||
- A line break
|
||||
- The contents of the string, which can span any number of lines
|
||||
- The delimiter word you chose, alone on its own line (with indentation allowed for indented heredocs)
|
||||
|
||||
The `<<` marker followed by any identifier at the end of a line introduces the
|
||||
sequence. Terraform then processes the following lines until it finds one that
|
||||
consists entirely of the identifier given in the introducer.
|
||||
|
||||
In the above example, `EOT` is the identifier selected. Any identifier is
|
||||
allowed, but conventionally this identifier is in all-uppercase and begins with
|
||||
`EO`, meaning "end of". `EOT` in this case stands for "end of text".
|
||||
|
||||
### Generating JSON or YAML
|
||||
|
||||
Don't use "heredoc" strings to generate JSON or YAML. Instead, use
|
||||
[the `jsonencode` function](../functions/jsonencode.html) or
|
||||
[the `yamlencode` function](../functions/yamlencode.html) so that Terraform
|
||||
can be responsible for guaranteeing valid JSON or YAML syntax.
|
||||
|
||||
```hcl
|
||||
example = jsonencode({
|
||||
a = 1
|
||||
b = "hello"
|
||||
})
|
||||
```
|
||||
|
||||
### Indented Heredocs
|
||||
|
||||
The standard heredoc form (shown above) treats all space characters as literal
|
||||
spaces. If you don't want each line to begin with spaces, then each line must be
|
||||
flush with the left margin, which can be awkward for expressions in an
|
||||
indented block:
|
||||
|
||||
```hcl
|
||||
block {
|
||||
value = <<EOT
|
||||
hello
|
||||
world
|
||||
EOT
|
||||
}
|
||||
```
|
||||
|
||||
To improve on this, Terraform also accepts an _indented_ heredoc string variant
|
||||
that is introduced by the `<<-` sequence:
|
||||
|
||||
```hcl
|
||||
block {
|
||||
value = <<-EOT
|
||||
hello
|
||||
world
|
||||
EOT
|
||||
}
|
||||
```
|
||||
|
||||
In this case, Terraform analyses the lines in the sequence to find the one
|
||||
with the smallest number of leading spaces, and then trims that many spaces
|
||||
from the beginning of all of the lines, leading to the following result:
|
||||
|
||||
```
|
||||
hello
|
||||
world
|
||||
```
|
||||
|
||||
### Escape Sequences
|
||||
|
||||
Backslash sequences are not interpreted as escapes in a heredoc string
|
||||
expression. Instead, the backslash character is interpreted literally.
|
||||
|
||||
Heredocs support two special escape sequences that do not use backslashes:
|
||||
|
||||
| Sequence | Replacement |
|
||||
| --- | ---- |
|
||||
| `$${` | Literal `${`, without beginning an interpolation sequence. |
|
||||
| `%%{` | Literal `%{`, without beginning a template directive sequence. |
|
||||
|
||||
|
||||
## String Templates
|
||||
|
||||
Within quoted and heredoc string expressions, the sequences `${` and `%{` begin
|
||||
_template sequences_. Templates let you directly embed expressions into a string
|
||||
literal, to dynamically construct strings from other values.
|
||||
|
||||
### Interpolation
|
||||
|
||||
A `${ ... }` sequence is an _interpolation,_ which evaluates the expression
|
||||
given between the markers, converts the result to a string if necessary, and
|
||||
then inserts it into the final string:
|
||||
|
||||
```hcl
|
||||
"Hello, ${var.name}!"
|
||||
```
|
||||
|
||||
In the above example, the named object `var.name` is accessed and its value
|
||||
inserted into the string, producing a result like "Hello, Juan!".
|
||||
|
||||
### Directives
|
||||
|
||||
A `%{ ... }` sequence is a _directive_, which allows for conditional
|
||||
results and iteration over collections, similar to conditional
|
||||
and `for` expressions.
|
||||
|
||||
The following directives are supported:
|
||||
|
||||
* The `%{if <BOOL>}`/`%{else}`/`%{endif}` directive chooses between two templates based
|
||||
on the value of a bool expression:
|
||||
|
||||
```hcl
|
||||
"Hello, %{ if var.name != "" }${var.name}%{ else }unnamed%{ endif }!"
|
||||
```
|
||||
|
||||
The `else` portion may be omitted, in which case the result is an empty
|
||||
string if the condition expression returns `false`.
|
||||
|
||||
* The `%{for <NAME> in <COLLECTION>}` / `%{endfor}` directive iterates over the
|
||||
elements of a given collection or structural value and evaluates a given
|
||||
template once for each element, concatenating the results together:
|
||||
|
||||
```hcl
|
||||
<<EOT
|
||||
%{ for ip in aws_instance.example.*.private_ip }
|
||||
server ${ip}
|
||||
%{ endfor }
|
||||
EOT
|
||||
```
|
||||
|
||||
The name given immediately after the `for` keyword is used as a temporary
|
||||
variable name which can then be referenced from the nested template.
|
||||
|
||||
### Whitespace Stripping
|
||||
|
||||
To allow template directives to be formatted for readability without adding
|
||||
unwanted spaces and newlines to the result, all template sequences can include
|
||||
optional _strip markers_ (`~`), immediately after the opening characters or
|
||||
immediately before the end. When a strip marker is present, the template
|
||||
sequence consumes all of the literal whitespace (spaces and newlines) either
|
||||
before the sequence (if the marker appears at the beginning) or after (if the
|
||||
marker appears at the end):
|
||||
|
||||
```hcl
|
||||
<<EOT
|
||||
%{ for ip in aws_instance.example.*.private_ip ~}
|
||||
server ${ip}
|
||||
%{ endfor ~}
|
||||
EOT
|
||||
```
|
||||
|
||||
In the above example, the newline after each of the directives is not included
|
||||
in the output, but the newline after the `server ${ip}` sequence is retained,
|
||||
causing only one line to be generated for each element:
|
||||
|
||||
```
|
||||
server 10.1.16.154
|
||||
server 10.1.16.1
|
||||
server 10.1.16.34
|
||||
```
|
||||
|
||||
When using template directives, we recommend always using the "heredoc" string
|
||||
literal form and then formatting the template over multiple lines for
|
||||
readability. Quoted string literals should usually include only interpolation
|
||||
sequences.
|
||||
@@ -1,147 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Types and Values - Configuration Language"
|
||||
---
|
||||
|
||||
# Types and Values
|
||||
|
||||
The result of an expression is a _value_. All values have a _type_, which
|
||||
dictates where that value can be used and what transformations can be
|
||||
applied to it.
|
||||
|
||||
## Types
|
||||
|
||||
The Terraform language uses the following types for its values:
|
||||
|
||||
* `string`: a sequence of Unicode characters representing some text, like
|
||||
`"hello"`.
|
||||
* `number`: a numeric value. The `number` type can represent both whole
|
||||
numbers like `15` and fractional values like `6.283185`.
|
||||
* `bool`: a boolean value, either `true` or `false`. `bool` values can be used in conditional
|
||||
logic.
|
||||
* `list` (or `tuple`): a sequence of values, like
|
||||
`["us-west-1a", "us-west-1c"]`. Elements in a list or tuple are identified by
|
||||
consecutive whole numbers, starting with zero.
|
||||
* `map` (or `object`): a group of values identified by named labels, like
|
||||
`{name = "Mabel", age = 52}`.
|
||||
|
||||
Strings, numbers, and bools are sometimes called _primitive types._ Lists/tuples and maps/objects are sometimes called _complex types,_ _structural types,_ or _collection types._
|
||||
|
||||
Finally, there is one special value that has _no_ type:
|
||||
|
||||
* `null`: a value that represents _absence_ or _omission._ If you set an
|
||||
argument of a resource or module to `null`, Terraform behaves as though you
|
||||
had completely omitted it — it will use the argument's default value if it has
|
||||
one, or raise an error if the argument is mandatory. `null` is most useful in
|
||||
conditional expressions, so you can dynamically omit an argument if a
|
||||
condition isn't met.
|
||||
|
||||
## Literal Expressions
|
||||
|
||||
A _literal expression_ is an expression that directly represents a particular
|
||||
constant value. Terraform has a literal expression syntax for each of the value
|
||||
types described above.
|
||||
|
||||
### Strings
|
||||
|
||||
Strings are usually represented by a double-quoted sequence of Unicode
|
||||
characters, `"like this"`. There is also a "heredoc" syntax for more complex
|
||||
strings.
|
||||
|
||||
String literals are the most complex kind of literal expression in
|
||||
Terraform, and have their own page of documentation. See [Strings](./strings.html)
|
||||
for information about escape sequences, the heredoc syntax, interpolation, and
|
||||
template directives.
|
||||
|
||||
### Numbers
|
||||
|
||||
Numbers are represented by unquoted sequences of digits with or without a
|
||||
decimal point, like `15` or `6.283185`.
|
||||
|
||||
### Bools
|
||||
|
||||
Bools are represented by the unquoted symbols `true` and `false`.
|
||||
|
||||
### Null
|
||||
|
||||
The null value is represented by the unquoted symbol `null`.
|
||||
|
||||
### Lists/Tuples
|
||||
|
||||
Lists/tuples are represented by a pair of square brackets containing a
|
||||
comma-separated sequence of values, like `["a", 15, true]`.
|
||||
|
||||
List literals can be split into multiple lines for readability, but always
|
||||
require a comma between values. A comma after the final value is allowed,
|
||||
but not required. Values in a list can be arbitrary expressions.
|
||||
|
||||
### Maps/Objects
|
||||
|
||||
Maps/objects are represented by a pair of curly braces containing a series of
|
||||
`<KEY> = <VALUE>` pairs:
|
||||
|
||||
```hcl
|
||||
{
|
||||
name = "John"
|
||||
age = 52
|
||||
}
|
||||
```
|
||||
|
||||
Key/value pairs can be separated by either a comma or a line break.
|
||||
|
||||
The values in a map
|
||||
can be arbitrary expressions.
|
||||
|
||||
The keys in a map must be strings; they can be left unquoted if
|
||||
they are a valid [identifier](/docs/configuration/syntax.html#identifiers), but must be quoted
|
||||
otherwise. You can use a non-literal string expression as a key by wrapping it in
|
||||
parentheses, like `(var.business_unit_tag_name) = "SRE"`.
|
||||
|
||||
## Indices and Attributes
|
||||
|
||||
[inpage-index]: #indices-and-attributes
|
||||
|
||||
Elements of list/tuple and map/object values can be accessed using
|
||||
the square-bracket index notation, like `local.list[3]`. The expression within
|
||||
the brackets must be a whole number for list and tuple values or a string
|
||||
for map and object values.
|
||||
|
||||
Map/object attributes with names that are valid identifiers can also be accessed
|
||||
using the dot-separated attribute notation, like `local.object.attrname`.
|
||||
In cases where a map might contain arbitrary user-specified keys, we recommend
|
||||
using only the square-bracket index notation (`local.map["keyname"]`).
|
||||
|
||||
## More About Complex Types
|
||||
|
||||
In most situations, lists and tuples behave identically, as do maps and objects.
|
||||
Whenever the distinction isn't relevant, the Terraform documentation uses each
|
||||
pair of terms interchangeably (with a historical preference for "list" and
|
||||
"map").
|
||||
|
||||
However, module authors and provider developers should understand the
|
||||
differences between these similar types (and the related `set` type), since they
|
||||
offer different ways to restrict the allowed values for input variables and
|
||||
resource arguments.
|
||||
|
||||
For complete details about these types (and an explanation of why the difference
|
||||
usually doesn't matter), see [Type Constraints](/docs/configuration/types.html).
|
||||
|
||||
## Type Conversion
|
||||
|
||||
Expressions are most often used to set values for the arguments of resources and
|
||||
child modules. In these cases, the argument has an expected type and the given
|
||||
expression must produce a value of that type.
|
||||
|
||||
Where possible, Terraform automatically converts values from one type to
|
||||
another in order to produce the expected type. If this isn't possible, Terraform
|
||||
will produce a type mismatch error and you must update the configuration with a
|
||||
more suitable expression.
|
||||
|
||||
Terraform automatically converts number and bool values to strings when needed.
|
||||
It also converts strings to numbers or bools, as long as the string contains a
|
||||
valid representation of a number or bool value.
|
||||
|
||||
* `true` converts to `"true"`, and vice-versa
|
||||
* `false` converts to `"false"`, and vice-versa
|
||||
* `15` converts to `"15"`, and vice-versa
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Files and Directories - Configuration Language"
|
||||
---
|
||||
|
||||
# Files and Directories
|
||||
|
||||
## File Extension
|
||||
|
||||
Code in the Terraform language is stored in plain text files with the `.tf` file
|
||||
extension. There is also
|
||||
[a JSON-based variant of the language](/docs/configuration/syntax-json.html) that is named with
|
||||
the `.tf.json` file extension.
|
||||
|
||||
Files containing Terraform code are often called _configuration files._
|
||||
|
||||
## Text Encoding
|
||||
|
||||
Configuration files must always use UTF-8 encoding, and by convention
|
||||
usually use Unix-style line endings (LF) rather than Windows-style
|
||||
line endings (CRLF), though both are accepted.
|
||||
|
||||
## Directories and Modules
|
||||
|
||||
A _module_ is a collection of `.tf` and/or `.tf.json` files kept together in a
|
||||
directory.
|
||||
|
||||
A Terraform module only consists of the top-level configuration files in a
|
||||
directory; nested directories are treated as completely separate modules, and
|
||||
are not automatically included in the configuration.
|
||||
|
||||
Terraform evaluates all of the configuration files in a module, effectively
|
||||
treating the entire module as a single document. Separating various blocks into
|
||||
different files is purely for the convenience of readers and maintainers, and
|
||||
has no effect on the module's behavior.
|
||||
|
||||
A Terraform module can use [module calls](/docs/configuration/blocks/modules/index.html) to
|
||||
explicitly include other modules into the configuration. These child modules can
|
||||
come from local directories (nested in the parent module's directory, or
|
||||
anywhere else on disk), or from external sources like the
|
||||
[Terraform Registry](https://registry.terraform.io).
|
||||
|
||||
## The Root Module
|
||||
|
||||
Terraform always runs in the context of a single _root module._ A complete
|
||||
_Terraform configuration_ consists of a root module and the tree of child
|
||||
modules (which includes the modules called by the root module, any modules
|
||||
called by those modules, etc.).
|
||||
|
||||
- In Terraform CLI, the root module is the working directory where Terraform is
|
||||
invoked. (You can use command line options to specify a root module outside
|
||||
the working directory, but in practice this is rare. )
|
||||
- In Terraform Cloud and Terraform Enterprise, the root module for a workspace
|
||||
defaults to the top level of the configuration directory (supplied via version
|
||||
control repository or direct upload), but the workspace settings can specify a
|
||||
subdirectory to use instead.
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "Functions - Configuration Language"
|
||||
sidebar_current: "docs-config-functions"
|
||||
description: |-
|
||||
The Terraform language has a number of built-in functions that can be called
|
||||
from within expressions to transform and combine values.
|
||||
---
|
||||
|
||||
# Built-in Functions
|
||||
|
||||
> **Hands-on:** Try the [Perform Dynamic Operations with Functions](https://learn.hashicorp.com/tutorials/terraform/functions?in=terraform/configuration-language&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
|
||||
|
||||
The Terraform language includes a number of built-in functions that you can
|
||||
call from within expressions to transform and combine values. The general
|
||||
syntax for function calls is a function name followed by comma-separated
|
||||
arguments in parentheses:
|
||||
|
||||
```hcl
|
||||
max(5, 12, 9)
|
||||
```
|
||||
|
||||
For more details on syntax, see
|
||||
[_Function Calls_](/docs/configuration/expressions/function-calls.html)
|
||||
in the Expressions section.
|
||||
|
||||
The Terraform language does not support user-defined functions, and so only
|
||||
the functions built in to the language are available for use. The navigation
|
||||
for this section includes a list of all of the available built-in functions.
|
||||
|
||||
You can experiment with the behavior of Terraform's built-in functions from
|
||||
the Terraform expression console, by running
|
||||
[the `terraform console` command](/docs/commands/console.html):
|
||||
|
||||
```
|
||||
> max(5, 12, 9)
|
||||
12
|
||||
```
|
||||
|
||||
The examples in the documentation for each function use console output to
|
||||
illustrate the result of calling the function with different parameters.
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "abs - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-abs"
|
||||
description: |-
|
||||
The abs function returns the absolute value of the given number.
|
||||
---
|
||||
|
||||
# `abs` Function
|
||||
|
||||
`abs` returns the absolute value of the given number. In other words, if the
|
||||
number is zero or positive then it is returned as-is, but if it is negative
|
||||
then it is multiplied by -1 to make it positive before returning it.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> abs(23)
|
||||
23
|
||||
> abs(0)
|
||||
0
|
||||
> abs(-12.4)
|
||||
12.4
|
||||
```
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "abspath - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-abspath"
|
||||
description: |-
|
||||
The abspath function converts the argument to an absolute filesystem path.
|
||||
---
|
||||
|
||||
# `abspath` Function
|
||||
|
||||
`abspath` takes a string containing a filesystem path and converts it
|
||||
to an absolute path. That is, if the path is not absolute, it will be joined
|
||||
with the current working directory.
|
||||
|
||||
Referring directly to filesystem paths in resource arguments may cause
|
||||
spurious diffs if the same configuration is applied from multiple systems or on
|
||||
different host operating systems. We recommend using filesystem paths only
|
||||
for transient values, such as the argument to [`file`](./file.html) (where
|
||||
only the contents are then stored) or in `connection` and `provisioner` blocks.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> abspath(path.root)
|
||||
/home/user/some/terraform/root
|
||||
```
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: alltrue - Functions - Configuration Language
|
||||
sidebar_current: docs-funcs-collection-alltrue
|
||||
description: |-
|
||||
The alltrue function determines whether all elements of a collection
|
||||
are true or "true". If the collection is empty, it returns true.
|
||||
---
|
||||
|
||||
# `alltrue` Function
|
||||
|
||||
-> **Note:** This function is available in Terraform 0.14 and later.
|
||||
|
||||
`alltrue` returns `true` if all elements in a given collection are `true`
|
||||
or `"true"`. It also returns `true` if the collection is empty.
|
||||
|
||||
```hcl
|
||||
alltrue(list)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```command
|
||||
> alltrue(["true", true])
|
||||
true
|
||||
> alltrue([true, false])
|
||||
false
|
||||
```
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: anytrue - Functions - Configuration Language
|
||||
sidebar_current: docs-funcs-collection-anytrue
|
||||
description: |-
|
||||
The anytrue function determines whether any element of a collection
|
||||
is true or "true". If the collection is empty, it returns false.
|
||||
---
|
||||
|
||||
# `anytrue` Function
|
||||
|
||||
-> **Note:** This function is available in Terraform 0.14 and later.
|
||||
|
||||
`anytrue` returns `true` if any element in a given collection is `true`
|
||||
or `"true"`. It also returns `false` if the collection is empty.
|
||||
|
||||
```hcl
|
||||
anytrue(list)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```command
|
||||
> anytrue(["true"])
|
||||
true
|
||||
> anytrue([true])
|
||||
true
|
||||
> anytrue([true, false])
|
||||
true
|
||||
> anytrue([])
|
||||
false
|
||||
```
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "base64decode - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-encoding-base64decode"
|
||||
description: |-
|
||||
The base64decode function decodes a string containing a base64 sequence.
|
||||
---
|
||||
|
||||
# `base64decode` Function
|
||||
|
||||
`base64decode` takes a string containing a Base64 character sequence and
|
||||
returns the original string.
|
||||
|
||||
Terraform uses the "standard" Base64 alphabet as defined in
|
||||
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
||||
|
||||
Strings in the Terraform language are sequences of unicode characters rather
|
||||
than bytes, so this function will also interpret the resulting bytes as
|
||||
UTF-8. If the bytes after Base64 decoding are _not_ valid UTF-8, this function
|
||||
produces an error.
|
||||
|
||||
While we do not recommend manipulating large, raw binary data in the Terraform
|
||||
language, Base64 encoding is the standard way to represent arbitrary byte
|
||||
sequences, and so resource types that accept or return binary data will use
|
||||
Base64 themselves, which avoids the need to encode or decode it directly in
|
||||
most cases. Various other functions with names containing "base64" can generate
|
||||
or manipulate Base64 data directly.
|
||||
|
||||
`base64decode` is, in effect, a shorthand for calling
|
||||
[`textdecodebase64`](./textdecodebase64.html) with the encoding name set to
|
||||
`UTF-8`.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> base64decode("SGVsbG8gV29ybGQ=")
|
||||
Hello World
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`base64encode`](./base64encode.html) performs the opposite operation,
|
||||
encoding the UTF-8 bytes for a string as Base64.
|
||||
* [`textdecodebase64`](./textdecodebase64.html) is a more general function that
|
||||
supports character encodings other than UTF-8.
|
||||
* [`base64gzip`](./base64gzip.html) applies gzip compression to a string
|
||||
and returns the result with Base64 encoding.
|
||||
* [`filebase64`](./filebase64.html) reads a file from the local filesystem
|
||||
and returns its raw bytes with Base64 encoding.
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "base64encode - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-encoding-base64encode"
|
||||
description: |-
|
||||
The base64encode function applies Base64 encoding to a string.
|
||||
---
|
||||
|
||||
# `base64encode` Function
|
||||
|
||||
`base64encode` applies Base64 encoding to a string.
|
||||
|
||||
Terraform uses the "standard" Base64 alphabet as defined in
|
||||
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
||||
|
||||
Strings in the Terraform language are sequences of unicode characters rather
|
||||
than bytes, so this function will first encode the characters from the string
|
||||
as UTF-8, and then apply Base64 encoding to the result.
|
||||
|
||||
The Terraform language applies Unicode normalization to all strings, and so
|
||||
passing a string through `base64decode` and then `base64encode` may not yield
|
||||
the original result exactly.
|
||||
|
||||
While we do not recommend manipulating large, raw binary data in the Terraform
|
||||
language, Base64 encoding is the standard way to represent arbitrary byte
|
||||
sequences, and so resource types that accept or return binary data will use
|
||||
Base64 themselves, and so this function exists primarily to allow string
|
||||
data to be easily provided to resource types that expect Base64 bytes.
|
||||
|
||||
`base64encode` is, in effect, a shorthand for calling
|
||||
[`textencodebase64`](./textencodebase64.html) with the encoding name set to
|
||||
`UTF-8`.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> base64encode("Hello World")
|
||||
SGVsbG8gV29ybGQ=
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`base64decode`](./base64decode.html) performs the opposite operation,
|
||||
decoding Base64 data and interpreting it as a UTF-8 string.
|
||||
* [`textencodebase64`](./textencodebase64.html) is a more general function that
|
||||
supports character encodings other than UTF-8.
|
||||
* [`base64gzip`](./base64gzip.html) applies gzip compression to a string
|
||||
and returns the result with Base64 encoding all in one operation.
|
||||
* [`filebase64`](./filebase64.html) reads a file from the local filesystem
|
||||
and returns its raw bytes with Base64 encoding, without creating an
|
||||
intermediate Unicode string.
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "base64gzip - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-encoding-base64gzip"
|
||||
description: |-
|
||||
The base64encode function compresses the given string with gzip and then
|
||||
encodes the result in Base64.
|
||||
---
|
||||
|
||||
# `base64gzip` Function
|
||||
|
||||
`base64gzip` compresses a string with gzip and then encodes the result in
|
||||
Base64 encoding.
|
||||
|
||||
Terraform uses the "standard" Base64 alphabet as defined in
|
||||
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
||||
|
||||
Strings in the Terraform language are sequences of unicode characters rather
|
||||
than bytes, so this function will first encode the characters from the string
|
||||
as UTF-8, then apply gzip compression, and then finally apply Base64 encoding.
|
||||
|
||||
While we do not recommend manipulating large, raw binary data in the Terraform
|
||||
language, this function can be used to compress reasonably sized text strings
|
||||
generated within the Terraform language. For example, the result of this
|
||||
function can be used to create a compressed object in Amazon S3 as part of
|
||||
an S3 website.
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`base64encode`](./base64encode.html) applies Base64 encoding _without_
|
||||
gzip compression.
|
||||
* [`filebase64`](./filebase64.html) reads a file from the local filesystem
|
||||
and returns its raw bytes with Base64 encoding.
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "base64sha256 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-base64sha256"
|
||||
description: |-
|
||||
The base64sha256 function computes the SHA256 hash of a given string and
|
||||
encodes it with Base64.
|
||||
---
|
||||
|
||||
# `base64sha256` Function
|
||||
|
||||
`base64sha256` computes the SHA256 hash of a given string and encodes it with
|
||||
Base64. This is not equivalent to `base64encode(sha256("test"))` since `sha256()`
|
||||
returns hexadecimal representation.
|
||||
|
||||
The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
|
||||
as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is
|
||||
then encoded with Base64 before returning. Terraform uses the "standard" Base64
|
||||
alphabet as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> base64sha256("hello world")
|
||||
uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`filebase64sha256`](./filebase64sha256.html) calculates the same hash from
|
||||
the contents of a file rather than from a string value.
|
||||
* [`sha256`](./sha256.html) calculates the same hash but returns the result
|
||||
in a more-verbose hexadecimal encoding.
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "base64sha512 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-base64sha512"
|
||||
description: |-
|
||||
The base64sha512 function computes the SHA512 hash of a given string and
|
||||
encodes it with Base64.
|
||||
---
|
||||
|
||||
# `base64sha512` Function
|
||||
|
||||
`base64sha512` computes the SHA512 hash of a given string and encodes it with
|
||||
Base64. This is not equivalent to `base64encode(sha512("test"))` since `sha512()`
|
||||
returns hexadecimal representation.
|
||||
|
||||
The given string is first encoded as UTF-8 and then the SHA512 algorithm is applied
|
||||
as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is
|
||||
then encoded with Base64 before returning. Terraform uses the "standard" Base64
|
||||
alphabet as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> base64sha512("hello world")
|
||||
MJ7MSJwS1utMxA9QyQLytNDtd+5RGnx6m808qG1M2G+YndNbxf9JlnDaNCVbRbDP2DDoH2Bdz33FVC6TrpzXbw==
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`filebase64sha512`](./filebase64sha512.html) calculates the same hash from
|
||||
the contents of a file rather than from a string value.
|
||||
* [`sha512`](./sha512.html) calculates the same hash but returns the result
|
||||
in a more-verbose hexadecimal encoding.
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "basename - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-basename"
|
||||
description: |-
|
||||
The basename function removes all except the last portion from a filesystem
|
||||
path.
|
||||
---
|
||||
|
||||
# `basename` Function
|
||||
|
||||
`basename` takes a string containing a filesystem path and removes all except
|
||||
the last portion from it.
|
||||
|
||||
This function works only with the path string and does not access the
|
||||
filesystem itself. It is therefore unable to take into account filesystem
|
||||
features such as symlinks.
|
||||
|
||||
If the path is empty then the result is `"."`, representing the current
|
||||
working directory.
|
||||
|
||||
The behavior of this function depends on the host platform. On Windows systems,
|
||||
it uses backslash `\` as the path segment separator. On Unix systems, the slash
|
||||
`/` is used.
|
||||
|
||||
Referring directly to filesystem paths in resource arguments may cause
|
||||
spurious diffs if the same configuration is applied from multiple systems or on
|
||||
different host operating systems. We recommend using filesystem paths only
|
||||
for transient values, such as the argument to [`file`](./file.html) (where
|
||||
only the contents are then stored) or in `connection` and `provisioner` blocks.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> basename("foo/bar/baz.txt")
|
||||
baz.txt
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`dirname`](./dirname.html) returns all of the segments of a filesystem path
|
||||
_except_ the last, discarding the portion that would be returned by
|
||||
`basename`.
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "bcrypt - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-bcrypt"
|
||||
description: |-
|
||||
The bcrypt function computes a hash of the given string using the Blowfish
|
||||
cipher.
|
||||
---
|
||||
|
||||
# `bcrypt` Function
|
||||
|
||||
`bcrypt` computes a hash of the given string using the Blowfish cipher,
|
||||
returning a string in
|
||||
[the _Modular Crypt Format_](https://passlib.readthedocs.io/en/stable/modular_crypt_format.html)
|
||||
usually expected in the shadow password file on many Unix systems.
|
||||
|
||||
```hcl
|
||||
bcrypt(string, cost)
|
||||
```
|
||||
|
||||
The `cost` argument is optional and will default to 10 if unspecified.
|
||||
|
||||
Since a bcrypt hash value includes a randomly selected salt, each call to this
|
||||
function will return a different value, even if the given string and cost are
|
||||
the same. Using this function directly with resource arguments will therefore
|
||||
cause spurious diffs. We recommend using this function only in `provisioner`
|
||||
blocks, or in data resources whose results are only used in `provisioner`
|
||||
blocks.
|
||||
|
||||
The version prefix on the generated string (e.g. `$2a$`) may change in future
|
||||
versions of Terraform.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> bcrypt("hello world")
|
||||
$2a$10$D5grTTzcsqyvAeIAnY/mYOIqliCoG7eAMX0/oFcuD.iErkksEbcAa
|
||||
```
|
||||
@@ -1,76 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "can - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-conversion-can"
|
||||
description: |-
|
||||
The can function tries to evaluate an expression given as an argument and
|
||||
indicates whether the evaluation succeeded.
|
||||
---
|
||||
|
||||
# `can` Function
|
||||
|
||||
`can` evaluates the given expression and returns a boolean value indicating
|
||||
whether the expression produced a result without any errors.
|
||||
|
||||
This is a special function that is able to catch errors produced when evaluating
|
||||
its argument. For most situations where you could use `can` it's better to use
|
||||
[`try`](./try.html) instead, because it allows for more concise definition of
|
||||
fallback values for failing expressions.
|
||||
|
||||
The primary purpose of `can` is to turn an error condition into a boolean
|
||||
validation result when writing
|
||||
[custom variable validation rules](../variables.html#custom-validation-rules).
|
||||
For example:
|
||||
|
||||
```
|
||||
variable "timestamp" {
|
||||
type = string
|
||||
|
||||
validation {
|
||||
# formatdate fails if the second argument is not a valid timestamp
|
||||
condition = can(formatdate("", var.timestamp))
|
||||
error_message = "The timestamp argument requires a valid RFC 3339 timestamp."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `can` function can only catch and handle _dynamic_ errors resulting from
|
||||
access to data that isn't known until runtime. It will not catch errors
|
||||
relating to expressions that can be proven to be invalid for any input, such
|
||||
as a malformed resource reference.
|
||||
|
||||
~> **Warning:** The `can` function is intended only for simple tests in
|
||||
variable validation rules. Although it can technically accept any sort of
|
||||
expression and be used elsewhere in the configuration, we recommend against
|
||||
using it in other contexts. For error handling elsewhere in the configuration,
|
||||
prefer to use [`try`](./try.html).
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> local.foo
|
||||
{
|
||||
"bar" = "baz"
|
||||
}
|
||||
> can(local.foo.bar)
|
||||
true
|
||||
> can(local.foo.boop)
|
||||
false
|
||||
```
|
||||
|
||||
The `can` function will _not_ catch errors relating to constructs that are
|
||||
provably invalid even before dynamic expression evaluation, such as a malformed
|
||||
reference or a reference to a top-level object that has not been declared:
|
||||
|
||||
```
|
||||
> can(local.nonexist)
|
||||
|
||||
Error: Reference to undeclared local value
|
||||
|
||||
A local value with the name "nonexist" has not been declared.
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`try`](./try.html), which tries evaluating a sequence of expressions and
|
||||
returns the result of the first one that succeeds.
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "ceil - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-ceil"
|
||||
description: |-
|
||||
The ceil function returns the closest whole number greater than or equal to
|
||||
the given value.
|
||||
---
|
||||
|
||||
# `ceil` Function
|
||||
|
||||
`ceil` returns the closest whole number that is greater than or equal to the
|
||||
given value, which may be a fraction.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> ceil(5)
|
||||
5
|
||||
> ceil(5.1)
|
||||
6
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`floor`](./floor.html), which rounds to the nearest whole number _less than_
|
||||
or equal.
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "chomp - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-chomp"
|
||||
description: |-
|
||||
The chomp function removes newline characters at the end of a string.
|
||||
---
|
||||
|
||||
# `chomp` Function
|
||||
|
||||
`chomp` removes newline characters at the end of a string.
|
||||
|
||||
This can be useful if, for example, the string was read from a file that has
|
||||
a newline character at the end.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> chomp("hello\n")
|
||||
hello
|
||||
> chomp("hello\r\n")
|
||||
hello
|
||||
> chomp("hello\n\n")
|
||||
hello
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`trimspace`](./trimspace.html), which removes all types of whitespace from
|
||||
both the start and the end of a string.
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "chunklist - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-chunklist"
|
||||
description: |-
|
||||
The chunklist function splits a single list into fixed-size chunks, returning
|
||||
a list of lists.
|
||||
---
|
||||
|
||||
# `chunklist` Function
|
||||
|
||||
`chunklist` splits a single list into fixed-size chunks, returning a list
|
||||
of lists.
|
||||
|
||||
```hcl
|
||||
chunklist(list, chunk_size)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> chunklist(["a", "b", "c", "d", "e"], 2)
|
||||
[
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
],
|
||||
[
|
||||
"c",
|
||||
"d",
|
||||
],
|
||||
[
|
||||
"e",
|
||||
],
|
||||
]
|
||||
> chunklist(["a", "b", "c", "d", "e"], 1)
|
||||
[
|
||||
[
|
||||
"a",
|
||||
],
|
||||
[
|
||||
"b",
|
||||
],
|
||||
[
|
||||
"c",
|
||||
],
|
||||
[
|
||||
"d",
|
||||
],
|
||||
[
|
||||
"e",
|
||||
],
|
||||
]
|
||||
```
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "cidrhost - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-ipnet-cidrhost"
|
||||
description: |-
|
||||
The cidrhost function calculates a full host IP address within a given
|
||||
IP network address prefix.
|
||||
---
|
||||
|
||||
# `cidrhost` Function
|
||||
|
||||
`cidrhost` calculates a full host IP address for a given host number within
|
||||
a given IP network address prefix.
|
||||
|
||||
```hcl
|
||||
cidrhost(prefix, hostnum)
|
||||
```
|
||||
|
||||
`prefix` must be given in CIDR notation, as defined in
|
||||
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
|
||||
|
||||
`hostnum` is a whole number that can be represented as a binary integer with
|
||||
no more than the number of digits remaining in the address after the given
|
||||
prefix. For more details on how this function interprets CIDR prefixes and
|
||||
populates host numbers, see the worked example for
|
||||
[`cidrsubnet`](./cidrsubnet.html).
|
||||
|
||||
Conventionally host number zero is used to represent the address of the
|
||||
network itself and the host number that would fill all the host bits with
|
||||
binary 1 represents the network's broadcast address. These numbers should
|
||||
generally not be used to identify individual hosts except in unusual
|
||||
situations, such as point-to-point links.
|
||||
|
||||
This function accepts both IPv6 and IPv4 prefixes, and the result always uses
|
||||
the same addressing scheme as the given prefix.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> cidrhost("10.12.127.0/20", 16)
|
||||
10.12.112.16
|
||||
> cidrhost("10.12.127.0/20", 268)
|
||||
10.12.113.12
|
||||
> cidrhost("fd00:fd12:3456:7890:00a2::/72", 34)
|
||||
fd00:fd12:3456:7890::22
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`cidrsubnet`](./cidrsubnet.html) calculates a subnet address under a given
|
||||
network address prefix.
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "cidrnetmask - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-ipnet-cidrnetmask"
|
||||
description: |-
|
||||
The cidrnetmask function converts an IPv4 address prefix given in CIDR
|
||||
notation into a subnet mask address.
|
||||
---
|
||||
|
||||
# `cidrnetmask` Function
|
||||
|
||||
`cidrnetmask` converts an IPv4 address prefix given in CIDR notation into
|
||||
a subnet mask address.
|
||||
|
||||
```hcl
|
||||
cidrnetmask(prefix)
|
||||
```
|
||||
|
||||
`prefix` must be given in IPv4 CIDR notation, as defined in
|
||||
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
|
||||
|
||||
The result is a subnet address formatted in the conventional dotted-decimal
|
||||
IPv4 address syntax, as expected by some software.
|
||||
|
||||
CIDR notation is the only valid notation for IPv6 addresses, so `cidrnetmask`
|
||||
produces an error if given an IPv6 address.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> cidrnetmask("172.16.0.0/12")
|
||||
255.240.0.0
|
||||
```
|
||||
@@ -1,168 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "cidrsubnet - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-ipnet-cidrsubnet"
|
||||
description: |-
|
||||
The cidrsubnet function calculates a subnet address within a given IP network
|
||||
address prefix.
|
||||
---
|
||||
|
||||
# `cidrsubnet` Function
|
||||
|
||||
`cidrsubnet` calculates a subnet address within given IP network address prefix.
|
||||
|
||||
```hcl
|
||||
cidrsubnet(prefix, newbits, netnum)
|
||||
```
|
||||
|
||||
`prefix` must be given in CIDR notation, as defined in
|
||||
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
|
||||
|
||||
`newbits` is the number of additional bits with which to extend the prefix.
|
||||
For example, if given a prefix ending in `/16` and a `newbits` value of
|
||||
`4`, the resulting subnet address will have length `/20`.
|
||||
|
||||
`netnum` is a whole number that can be represented as a binary integer with
|
||||
no more than `newbits` binary digits, which will be used to populate the
|
||||
additional bits added to the prefix.
|
||||
|
||||
This function accepts both IPv6 and IPv4 prefixes, and the result always uses
|
||||
the same addressing scheme as the given prefix.
|
||||
|
||||
Unlike the related function [`cidrsubnets`](./cidrsubnets.html), `cidrsubnet`
|
||||
allows you to give a specific network number to use. `cidrsubnets` can allocate
|
||||
multiple network addresses at once, but numbers them automatically starting
|
||||
with zero.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> cidrsubnet("172.16.0.0/12", 4, 2)
|
||||
172.18.0.0/16
|
||||
> cidrsubnet("10.1.2.0/24", 4, 15)
|
||||
10.1.2.240/28
|
||||
> cidrsubnet("fd00:fd12:3456:7890::/56", 16, 162)
|
||||
fd00:fd12:3456:7800:a200::/72
|
||||
```
|
||||
|
||||
## Netmasks and Subnets
|
||||
|
||||
Using `cidrsubnet` requires familiarity with some network addressing concepts.
|
||||
|
||||
The most important idea is that an IP address (whether IPv4 or IPv6) is
|
||||
fundamentally constructed from binary digits, even though we conventionally
|
||||
represent it as either four decimal octets (for IPv4) or a sequence of 16-bit
|
||||
hexadecimal numbers (for IPv6).
|
||||
|
||||
Taking our example above of `cidrsubnet("10.1.2.0/24", 4, 15)`, the function
|
||||
will first convert the given IP address string into an equivalent binary
|
||||
representation:
|
||||
|
||||
```
|
||||
10 . 1 . 2 . 0
|
||||
00001010 00000001 00000010 | 00000000
|
||||
network | host
|
||||
```
|
||||
|
||||
The `/24` at the end of the prefix string specifies that the first 24
|
||||
bits -- or, the first three octets -- of the address identify the network
|
||||
while the remaining bits (32 - 24 = 8 bits in this case) identify hosts
|
||||
within the network.
|
||||
|
||||
The CLI tool [`ipcalc`](https://gitlab.com/ipcalc/ipcalc) is useful for
|
||||
visualizing CIDR prefixes as binary numbers. We can confirm the conversion
|
||||
above by providing the same prefix string to `ipcalc`:
|
||||
|
||||
```
|
||||
$ ipcalc 10.1.2.0/24
|
||||
Address: 10.1.2.0 00001010.00000001.00000010. 00000000
|
||||
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000
|
||||
Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111
|
||||
=>
|
||||
Network: 10.1.2.0/24 00001010.00000001.00000010. 00000000
|
||||
HostMin: 10.1.2.1 00001010.00000001.00000010. 00000001
|
||||
HostMax: 10.1.2.254 00001010.00000001.00000010. 11111110
|
||||
Broadcast: 10.1.2.255 00001010.00000001.00000010. 11111111
|
||||
Hosts/Net: 254 Class A, Private Internet
|
||||
```
|
||||
|
||||
This gives us some additional information but also confirms (using a slightly
|
||||
different notation) the conversion from decimal to binary and shows the range
|
||||
of possible host addresses in this network.
|
||||
|
||||
While [`cidrhost`](./cidrhost.html) allows calculating single host IP addresses,
|
||||
`cidrsubnet` on the other hand creates a new network prefix _within_ the given
|
||||
network prefix. In other words, it creates a subnet.
|
||||
|
||||
When we call `cidrsubnet` we also pass two additional arguments: `newbits` and
|
||||
`netnum`. `newbits` decides how much longer the resulting prefix will be in
|
||||
bits; in our example here we specified `4`, which means that the resulting
|
||||
subnet will have a prefix length of 24 + 4 = 28 bits. We can imagine these
|
||||
bits breaking down as follows:
|
||||
|
||||
```
|
||||
10 . 1 . 2 . ? 0
|
||||
00001010 00000001 00000010 | XXXX | 0000
|
||||
parent network | netnum | host
|
||||
```
|
||||
|
||||
Four of the eight bits that were originally the "host number" are now being
|
||||
repurposed as the subnet number. The network prefix no longer falls on an
|
||||
exact octet boundary, so in effect we are now splitting the last decimal number
|
||||
in the IP address into two parts, using half of it to represent the subnet
|
||||
number and the other half to represent the host number.
|
||||
|
||||
The `netnum` argument then decides what number value to encode into those
|
||||
four new subnet bits. In our current example we passed `15`, which is
|
||||
represented in binary as `1111`, allowing us to fill in the `XXXX` segment
|
||||
in the above:
|
||||
|
||||
```
|
||||
10 . 1 . 2 . 15 0
|
||||
00001010 00000001 00000010 | 1111 | 0000
|
||||
parent network | netnum | host
|
||||
```
|
||||
|
||||
To convert this back into normal decimal notation we need to recombine the
|
||||
two portions of the final octet. Converting `11110000` from binary to decimal
|
||||
gives 240, which can then be combined with our new prefix length of 28 to
|
||||
produce the result `10.1.2.240/28`. Again we can pass this prefix string to
|
||||
`ipcalc` to visualize it:
|
||||
|
||||
```
|
||||
$ ipcalc 10.1.2.240/28
|
||||
Address: 10.1.2.240 00001010.00000001.00000010.1111 0000
|
||||
Netmask: 255.255.255.240 = 28 11111111.11111111.11111111.1111 0000
|
||||
Wildcard: 0.0.0.15 00000000.00000000.00000000.0000 1111
|
||||
=>
|
||||
Network: 10.1.2.240/28 00001010.00000001.00000010.1111 0000
|
||||
HostMin: 10.1.2.241 00001010.00000001.00000010.1111 0001
|
||||
HostMax: 10.1.2.254 00001010.00000001.00000010.1111 1110
|
||||
Broadcast: 10.1.2.255 00001010.00000001.00000010.1111 1111
|
||||
Hosts/Net: 14 Class A, Private Internet
|
||||
```
|
||||
|
||||
The new subnet has four bits available for host numbering, which means
|
||||
that there are 14 host addresses available for assignment once we subtract
|
||||
the network's own address and the broadcast address. You can thus use
|
||||
[`cidrhost`](./cidrhost.html) function to calculate those host addresses by
|
||||
providing it a value between 1 and 14:
|
||||
|
||||
```
|
||||
> cidrhost("10.1.2.240/28", 1)
|
||||
10.1.2.241
|
||||
> cidrhost("10.1.2.240/28", 14)
|
||||
10.1.2.254
|
||||
```
|
||||
|
||||
For more information on CIDR notation and subnetting, see
|
||||
[Classless Inter-domain Routing](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing).
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`cidrhost`](./cidrhost.html) calculates the IP address for a single host
|
||||
within a given network address prefix.
|
||||
* [`cidrnetmask`](./cidrnetmask.html) converts an IPv4 network prefix in CIDR
|
||||
notation into netmask notation.
|
||||
* [`cidrsubnets`](./cidrsubnets.html) can allocate multiple consecutive
|
||||
addresses under a prefix at once, numbering them automatically.
|
||||
@@ -1,101 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "cidrsubnets - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-ipnet-cidrsubnets"
|
||||
description: |-
|
||||
The cidrsubnets function calculates a sequence of consecutive IP address
|
||||
ranges within a particular CIDR prefix.
|
||||
---
|
||||
|
||||
# `cidrsubnets` Function
|
||||
|
||||
`cidrsubnets` calculates a sequence of consecutive IP address ranges within
|
||||
a particular CIDR prefix.
|
||||
|
||||
```hcl
|
||||
cidrsubnets(prefix, newbits...)
|
||||
```
|
||||
|
||||
`prefix` must be given in CIDR notation, as defined in
|
||||
[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1).
|
||||
|
||||
The remaining arguments, indicated as `newbits` above, each specify the number
|
||||
of additional network prefix bits for one returned address range. The return
|
||||
value is therefore a list with one element per `newbits` argument, each
|
||||
a string containing an address range in CIDR notation.
|
||||
|
||||
For more information on IP addressing concepts, see the documentation for the
|
||||
related function [`cidrsubnet`](./cidrsubnet.html). `cidrsubnet` calculates
|
||||
a single subnet address within a prefix while allowing you to specify its
|
||||
subnet number, while `cidrsubnets` can calculate many at once, potentially of
|
||||
different sizes, and assigns subnet numbers automatically.
|
||||
|
||||
When using this function to partition an address space as part of a network
|
||||
address plan, you must not change any of the existing arguments once network
|
||||
addresses have been assigned to real infrastructure, or else later address
|
||||
assignments will be invalidated. However, you _can_ append new arguments to
|
||||
existing calls safely, as long as there is sufficient address space available.
|
||||
|
||||
This function accepts both IPv6 and IPv4 prefixes, and the result always uses
|
||||
the same addressing scheme as the given prefix.
|
||||
|
||||
-> **Note:** [The Terraform module `hashicorp/subnets/cidr`](https://registry.terraform.io/modules/hashicorp/subnets/cidr)
|
||||
wraps `cidrsubnets` to provide additional functionality for assigning symbolic
|
||||
names to your networks and skipping prefixes for obsolete allocations. Its
|
||||
documentation includes usage examples for several popular cloud virtual network
|
||||
platforms.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> cidrsubnets("10.1.0.0/16", 4, 4, 8, 4)
|
||||
[
|
||||
"10.1.0.0/20",
|
||||
"10.1.16.0/20",
|
||||
"10.1.32.0/24",
|
||||
"10.1.48.0/20",
|
||||
]
|
||||
|
||||
> cidrsubnets("fd00:fd12:3456:7890::/56", 16, 16, 16, 32)
|
||||
[
|
||||
"fd00:fd12:3456:7800::/72",
|
||||
"fd00:fd12:3456:7800:100::/72",
|
||||
"fd00:fd12:3456:7800:200::/72",
|
||||
"fd00:fd12:3456:7800:300::/88",
|
||||
]
|
||||
```
|
||||
|
||||
You can use nested `cidrsubnets` calls with
|
||||
[`for` expressions](/docs/configuration/expressions/for.html)
|
||||
to concisely allocate groups of network address blocks:
|
||||
|
||||
```
|
||||
> [for cidr_block in cidrsubnets("10.0.0.0/8", 8, 8, 8, 8) : cidrsubnets(cidr_block, 4, 4)]
|
||||
[
|
||||
[
|
||||
"10.0.0.0/20",
|
||||
"10.0.16.0/20",
|
||||
],
|
||||
[
|
||||
"10.1.0.0/20",
|
||||
"10.1.16.0/20",
|
||||
],
|
||||
[
|
||||
"10.2.0.0/20",
|
||||
"10.2.16.0/20",
|
||||
],
|
||||
[
|
||||
"10.3.0.0/20",
|
||||
"10.3.16.0/20",
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`cidrhost`](./cidrhost.html) calculates the IP address for a single host
|
||||
within a given network address prefix.
|
||||
* [`cidrnetmask`](./cidrnetmask.html) converts an IPv4 network prefix in CIDR
|
||||
notation into netmask notation.
|
||||
* [`cidrsubnet`](./cidrsubnet.html) calculates a single subnet address, allowing
|
||||
you to specify its network number.
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "coalesce - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-coalesce-x"
|
||||
description: |-
|
||||
The coalesce function takes any number of arguments and returns the
|
||||
first one that isn't null nor empty.
|
||||
---
|
||||
|
||||
# `coalesce` Function
|
||||
|
||||
`coalesce` takes any number of arguments and returns the first one
|
||||
that isn't null or an empty string.
|
||||
|
||||
All of the arguments must be of the same type. Terraform will try to
|
||||
convert mismatched arguments to the most general of the types that all
|
||||
arguments can convert to, or return an error if the types are incompatible.
|
||||
The result type is the same as the type of all of the arguments.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> coalesce("a", "b")
|
||||
a
|
||||
> coalesce("", "b")
|
||||
b
|
||||
> coalesce(1,2)
|
||||
1
|
||||
```
|
||||
|
||||
To perform the `coalesce` operation with a list of strings, use the `...`
|
||||
symbol to expand the list as arguments:
|
||||
|
||||
```
|
||||
> coalesce(["", "b"]...)
|
||||
b
|
||||
```
|
||||
|
||||
Terraform attempts to select a result type that all of the arguments can
|
||||
convert to, so mixing argument types may produce surprising results due to
|
||||
Terraform's automatic type conversion rules:
|
||||
|
||||
```
|
||||
> coalesce(1, "hello")
|
||||
"1"
|
||||
> coalesce(true, "hello")
|
||||
"true"
|
||||
> coalesce({}, "hello")
|
||||
|
||||
Error: Error in function call
|
||||
|
||||
Call to function "coalesce" failed: all arguments must have the same type.
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`coalescelist`](./coalescelist.html) performs a similar operation with
|
||||
list arguments rather than individual arguments.
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "coalescelist - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-coalescelist"
|
||||
description: |-
|
||||
The coalescelist function takes any number of list arguments and returns the
|
||||
first one that isn't empty.
|
||||
---
|
||||
|
||||
# `coalescelist` Function
|
||||
|
||||
`coalescelist` takes any number of list arguments and returns the first one
|
||||
that isn't empty.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> coalescelist(["a", "b"], ["c", "d"])
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
]
|
||||
> coalescelist([], ["c", "d"])
|
||||
[
|
||||
"c",
|
||||
"d",
|
||||
]
|
||||
```
|
||||
|
||||
To perform the `coalescelist` operation with a list of lists, use the `...`
|
||||
symbol to expand the outer list as arguments:
|
||||
|
||||
```
|
||||
> coalescelist([[], ["c", "d"]]...)
|
||||
[
|
||||
"c",
|
||||
"d",
|
||||
]
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`coalesce`](./coalesce.html) performs a similar operation with string
|
||||
arguments rather than list arguments.
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "compact - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-compact"
|
||||
description: |-
|
||||
The compact function removes empty string elements from a list.
|
||||
---
|
||||
|
||||
# `compact` Function
|
||||
|
||||
`compact` takes a list of strings and returns a new list with any empty string
|
||||
elements removed.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> compact(["a", "", "b", "c"])
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
```
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "concat - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-concat"
|
||||
description: |-
|
||||
The concat function combines two or more lists into a single list.
|
||||
---
|
||||
|
||||
# `concat` Function
|
||||
|
||||
`concat` takes two or more lists and combines them into a single list.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> concat(["a", ""], ["b", "c"])
|
||||
[
|
||||
"a",
|
||||
"",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
```
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "contains - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-contains"
|
||||
description: |-
|
||||
The contains function determines whether a list or set contains a given value.
|
||||
---
|
||||
|
||||
# `contains` Function
|
||||
|
||||
`contains` determines whether a given list or set contains a given single value
|
||||
as one of its elements.
|
||||
|
||||
```hcl
|
||||
contains(list, value)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> contains(["a", "b", "c"], "a")
|
||||
true
|
||||
> contains(["a", "b", "c"], "d")
|
||||
false
|
||||
```
|
||||
@@ -1,98 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "csvdecode - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-encoding-csvdecode"
|
||||
description: |-
|
||||
The csvdecode function decodes CSV data into a list of maps.
|
||||
---
|
||||
|
||||
# `csvdecode` Function
|
||||
|
||||
`csvdecode` decodes a string containing CSV-formatted data and produces a
|
||||
list of maps representing that data.
|
||||
|
||||
CSV is _Comma-separated Values_, an encoding format for tabular data. There
|
||||
are many variants of CSV, but this function implements the format defined
|
||||
in [RFC 4180](https://tools.ietf.org/html/rfc4180).
|
||||
|
||||
The first line of the CSV data is interpreted as a "header" row: the values
|
||||
given are used as the keys in the resulting maps. Each subsequent line becomes
|
||||
a single map in the resulting list, matching the keys from the header row
|
||||
with the given values by index. All lines in the file must contain the same
|
||||
number of fields, or this function will produce an error.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> csvdecode("a,b,c\n1,2,3\n4,5,6")
|
||||
[
|
||||
{
|
||||
"a" = "1"
|
||||
"b" = "2"
|
||||
"c" = "3"
|
||||
},
|
||||
{
|
||||
"a" = "4"
|
||||
"b" = "5"
|
||||
"c" = "6"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Use with the `for_each` meta-argument
|
||||
|
||||
You can use the result of `csvdecode` with
|
||||
[the `for_each` meta-argument](/docs/configuration/meta-arguments/for_each.html)
|
||||
to describe a collection of similar objects whose differences are
|
||||
described by the rows in the given CSV file.
|
||||
|
||||
There must be one column in the CSV file that can serve as a unique id for each
|
||||
row, which we can then use as the tracking key for the individual instances in
|
||||
the `for_each` expression. For example:
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
# We've included this inline to create a complete example, but in practice
|
||||
# this is more likely to be loaded from a file using the "file" function.
|
||||
csv_data = <<-CSV
|
||||
local_id,instance_type,ami
|
||||
foo1,t2.micro,ami-54d2a63b
|
||||
foo2,t2.micro,ami-54d2a63b
|
||||
foo3,t2.micro,ami-54d2a63b
|
||||
bar1,m3.large,ami-54d2a63b
|
||||
CSV
|
||||
|
||||
instances = csvdecode(local.csv_data)
|
||||
}
|
||||
|
||||
resource "aws_instance" "example" {
|
||||
for_each = { for inst in local.instances : inst.local_id => inst }
|
||||
|
||||
instance_type = each.value.instance_type
|
||||
ami = each.value.ami
|
||||
}
|
||||
```
|
||||
|
||||
The `for` expression in our `for_each` argument transforms the list produced
|
||||
by `csvdecode` into a map using the `local_id` as a key, which tells
|
||||
Terraform to use the `local_id` value to track each instance it creates.
|
||||
Terraform will create and manage the following instance addresses:
|
||||
|
||||
- `aws_instance.example["foo1"]`
|
||||
- `aws_instance.example["foo2"]`
|
||||
- `aws_instance.example["foo3"]`
|
||||
- `aws_instance.example["bar1"]`
|
||||
|
||||
If you modify a row in the CSV on a subsequent plan, Terraform will interpret
|
||||
that as an update to the existing object as long as the `local_id` value is
|
||||
unchanged. If you add or remove rows from the CSV then Terraform will plan to
|
||||
create or destroy associated instances as appropriate.
|
||||
|
||||
If there is no reasonable value you can use as a unique identifier in your CSV
|
||||
then you could instead use
|
||||
[the `count` meta-argument](/docs/configuration/meta-arguments/count.html)
|
||||
to define an object for each CSV row, with each one identified by its index into
|
||||
the list returned by `csvdecode`. However, in that case any future updates to
|
||||
the CSV may be disruptive if they change the positions of particular objects in
|
||||
the list. We recommend using `for_each` with a unique id column to make
|
||||
behavior more predictable on future changes.
|
||||
@@ -1,201 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "defaults - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-conversion-defaults"
|
||||
description: |-
|
||||
The defaults function can fill in default values in place of null values.
|
||||
---
|
||||
|
||||
# `defaults` Function
|
||||
|
||||
-> **Note:** This function is available only in Terraform 0.15 and later.
|
||||
|
||||
~> **Experimental:** This function is part of
|
||||
[the optional attributes experiment](../types.html#experimental-optional-object-type-attributes)
|
||||
and is only available in modules where the `module_variable_optional_attrs`
|
||||
experiment is explicitly enabled.
|
||||
|
||||
The `defaults` function is a specialized function intended for use with
|
||||
input variables whose type constraints are object types or collections of
|
||||
object types that include optional attributes.
|
||||
|
||||
When you define an attribute as optional and the caller doesn't provide an
|
||||
explicit value for it, Terraform will set the attribute to `null` to represent
|
||||
that it was omitted. If you want to use a placeholder value other than `null`
|
||||
when an attribute isn't set, you can use the `defaults` function to concisely
|
||||
assign default values only where an attribute value was set to `null`.
|
||||
|
||||
```
|
||||
defaults(input_value, defaults)
|
||||
```
|
||||
|
||||
The `defaults` function expects that the `input_value` argument will be the
|
||||
value of an input variable with an exact [type constraint](../types.html)
|
||||
(not containing `any`). The function will then visit every attribute in
|
||||
the data structure, including attributes of nested objects, and apply the
|
||||
default values given in the defaults object.
|
||||
|
||||
The interpretation of attributes in the `defaults` argument depends on what
|
||||
type an attribute has in the `input_value`:
|
||||
|
||||
* **Primitive types** (`string`, `number`, `bool`): if a default value is given
|
||||
then it will be used only if the `input_value`'s attribute of the same
|
||||
name has the value `null`. The default value's type must match the input
|
||||
value's type.
|
||||
* **Structural types** (`object` and `tuple` types): Terraform will recursively
|
||||
visit all of the attributes or elements of the nested value and repeat the
|
||||
same defaults-merging logic one level deeper. The default value's type must
|
||||
be of the same kind as the input value's type, and a default value for an
|
||||
object type must only contain attribute names that appear in the input
|
||||
value's type.
|
||||
* **Collection types** (`list`, `map`, and `set` types): Terraform will visit
|
||||
each of the collection elements in turn and apply defaults to them. In this
|
||||
case the default value is only a single value to be applied to _all_ elements
|
||||
of the collection, so it must have a type compatible with the collection's
|
||||
element type rather than with the collection type itself.
|
||||
|
||||
The above rules may be easier to follow with an example. Consider the following
|
||||
Terraform configuration:
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
# Optional attributes and the defaults function are
|
||||
# both experimental, so we must opt in to the experiment.
|
||||
experiments = [module_variable_optional_attrs]
|
||||
}
|
||||
|
||||
variable "storage" {
|
||||
type = object({
|
||||
name = string
|
||||
enabled = optional(bool)
|
||||
website = object({
|
||||
index_document = optional(string)
|
||||
error_document = optional(string)
|
||||
})
|
||||
documents = map(
|
||||
object({
|
||||
source_file = string
|
||||
content_type = optional(string)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
locals {
|
||||
storage = defaults(var.storage, {
|
||||
# If "enabled" isn't set then it will default
|
||||
# to true.
|
||||
enabled = true
|
||||
|
||||
# The "website" attribute is required, but
|
||||
# it's here to provide defaults for the
|
||||
# optional attributes inside.
|
||||
website = {
|
||||
index_document = "index.html"
|
||||
error_document = "error.html"
|
||||
}
|
||||
|
||||
# The "documents" attribute has a map type,
|
||||
# so the default value represents defaults
|
||||
# to be applied to all of the elements in
|
||||
# the map, not for the map itself. Therefore
|
||||
# it's a single object matching the map
|
||||
# element type, not a map itself.
|
||||
documents = {
|
||||
# If _any_ of the map elements omit
|
||||
# content_type then this default will be
|
||||
# used instead.
|
||||
content_type = "application/octet-stream"
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
output "storage" {
|
||||
value = local.storage
|
||||
}
|
||||
```
|
||||
|
||||
To test this out, we can create a file `terraform.tfvars` to provide an example
|
||||
value for `var.storage`:
|
||||
|
||||
```hcl
|
||||
storage = {
|
||||
name = "example"
|
||||
|
||||
website = {
|
||||
error_document = "error.txt"
|
||||
}
|
||||
documents = {
|
||||
"index.html" = {
|
||||
source_file = "index.html.tmpl"
|
||||
content_type = "text/html"
|
||||
}
|
||||
"error.txt" = {
|
||||
source_file = "error.txt.tmpl"
|
||||
content_type = "text/plain"
|
||||
}
|
||||
"terraform.exe" = {
|
||||
source_file = "terraform.exe"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The above value conforms to the variable's type constraint because it only
|
||||
omits attributes that are declared as optional. Terraform will automatically
|
||||
populate those attributes with the value `null` before evaluating anything
|
||||
else, and then the `defaults` function in `local.storage` will substitute
|
||||
default values for each of them.
|
||||
|
||||
The result of this `defaults` call would therefore be the following object:
|
||||
|
||||
```
|
||||
storage = {
|
||||
"documents" = tomap({
|
||||
"error.txt" = {
|
||||
"content_type" = "text/plain"
|
||||
"source_file" = "error.txt.tmpl"
|
||||
}
|
||||
"index.html" = {
|
||||
"content_type" = "text/html"
|
||||
"source_file" = "index.html.tmpl"
|
||||
}
|
||||
"terraform.exe" = {
|
||||
"content_type" = "application/octet-stream"
|
||||
"source_file" = "terraform.exe"
|
||||
}
|
||||
})
|
||||
"enabled" = true
|
||||
"name" = "example"
|
||||
"website" = {
|
||||
"error_document" = "error.txt"
|
||||
"index_document" = "index.html"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notice that `enabled` and `website.index_document` were both populated directly
|
||||
from the defaults. Notice also that the `"terraform.exe"` element of
|
||||
`documents` had its `content_type` attribute populated from the `documents`
|
||||
default, but the default value didn't need to predict that there would be an
|
||||
element key `"terraform.exe"` because the default values apply equally to
|
||||
all elements of the map where the optional attributes are `null`.
|
||||
|
||||
## Using `defaults` elsewhere
|
||||
|
||||
The design of the `defaults` function depends on input values having
|
||||
well-specified type constraints, so it can reliably recognize the difference
|
||||
between similar types: maps vs. objects, lists vs. tuples. The type constraint
|
||||
causes Terraform to convert the caller's value to conform to the constraint
|
||||
and thus `defaults` can rely on the input to conform.
|
||||
|
||||
Elsewhere in the Terraform language it's typical to be less precise about
|
||||
types, for example using the object construction syntax `{ ... }` to construct
|
||||
values that will be used as if they are maps. Because `defaults` uses the
|
||||
type information of `input_value`, an `input_value` that _doesn't_ originate
|
||||
in an input variable will tend not to have an appropriate value type and will
|
||||
thus not be interpreted as expected by `defaults`.
|
||||
|
||||
We recommend using `defaults` only with fully-constrained input variable values
|
||||
in the first argument, so you can use the variable's type constraint to
|
||||
explicitly distinguish between collection and structural types.
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "dirname - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-dirname"
|
||||
description: |-
|
||||
The dirname function removes the last portion from a filesystem path.
|
||||
---
|
||||
|
||||
# `dirname` Function
|
||||
|
||||
`dirname` takes a string containing a filesystem path and removes the last
|
||||
portion from it.
|
||||
|
||||
This function works only with the path string and does not access the
|
||||
filesystem itself. It is therefore unable to take into account filesystem
|
||||
features such as symlinks.
|
||||
|
||||
If the path is empty then the result is `"."`, representing the current
|
||||
working directory.
|
||||
|
||||
The behavior of this function depends on the host platform. On Windows systems,
|
||||
it uses backslash `\` as the path segment separator. On Unix systems, the slash
|
||||
`/` is used. The result of this function is normalized, so on a Windows system
|
||||
any slashes in the given path will be replaced by backslashes before returning.
|
||||
|
||||
Referring directly to filesystem paths in resource arguments may cause
|
||||
spurious diffs if the same configuration is applied from multiple systems or on
|
||||
different host operating systems. We recommend using filesystem paths only
|
||||
for transient values, such as the argument to [`file`](./file.html) (where
|
||||
only the contents are then stored) or in `connection` and `provisioner` blocks.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> dirname("foo/bar/baz.txt")
|
||||
foo/bar
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`basename`](./basename.html) returns _only_ the last portion of a filesystem
|
||||
path, discarding the portion that would be returned by `dirname`.
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "distinct - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-distinct"
|
||||
description: |-
|
||||
The distinct function removes duplicate elements from a list.
|
||||
---
|
||||
|
||||
# `distinct` Function
|
||||
|
||||
`distinct` takes a list and returns a new list with any duplicate elements
|
||||
removed.
|
||||
|
||||
The first occurrence of each value is retained and the relative ordering of
|
||||
these elements is preserved.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> distinct(["a", "b", "a", "c", "d", "b"])
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"d",
|
||||
]
|
||||
```
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "element - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-element"
|
||||
description: |-
|
||||
The element function retrieves a single element from a list.
|
||||
---
|
||||
|
||||
# `element` Function
|
||||
|
||||
`element` retrieves a single element from a list.
|
||||
|
||||
```hcl
|
||||
element(list, index)
|
||||
```
|
||||
|
||||
The index is zero-based. This function produces an error if used with an
|
||||
empty list. The index must be a non-negative integer.
|
||||
|
||||
Use the built-in index syntax `list[index]` in most cases. Use this function
|
||||
only for the special additional "wrap-around" behavior described below.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> element(["a", "b", "c"], 1)
|
||||
b
|
||||
```
|
||||
|
||||
If the given index is greater than the length of the list then the index is
|
||||
"wrapped around" by taking the index modulo the length of the list:
|
||||
|
||||
```
|
||||
> element(["a", "b", "c"], 3)
|
||||
a
|
||||
```
|
||||
|
||||
To get the last element from the list use [`length`](./length.html) to find
|
||||
the size of the list (minus 1 as the list is zero-based) and then pick the
|
||||
last element:
|
||||
|
||||
```
|
||||
> element(["a", "b", "c"], length(["a", "b", "c"])-1)
|
||||
c
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`index`](./index.html) finds the index for a particular element value.
|
||||
* [`lookup`](./lookup.html) retrieves a value from a _map_ given its _key_.
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "file - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-file-x"
|
||||
description: |-
|
||||
The file function reads the contents of the file at the given path and
|
||||
returns them as a string.
|
||||
---
|
||||
|
||||
# `file` Function
|
||||
|
||||
`file` reads the contents of a file at the given path and returns them as
|
||||
a string.
|
||||
|
||||
```hcl
|
||||
file(path)
|
||||
```
|
||||
|
||||
Strings in the Terraform language are sequences of Unicode characters, so
|
||||
this function will interpret the file contents as UTF-8 encoded text and
|
||||
return the resulting Unicode characters. If the file contains invalid UTF-8
|
||||
sequences then this function will produce an error.
|
||||
|
||||
This function can be used only with files that already exist on disk
|
||||
at the beginning of a Terraform run. Functions do not participate in the
|
||||
dependency graph, so this function cannot be used with files that are generated
|
||||
dynamically during a Terraform operation. We do not recommend using dynamic
|
||||
local files in Terraform configurations, but in rare situations where this is
|
||||
necessary you can use
|
||||
[the `local_file` data source](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file)
|
||||
to read files while respecting resource dependencies.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> file("${path.module}/hello.txt")
|
||||
Hello World
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`filebase64`](./filebase64.html) also reads the contents of a given file,
|
||||
but returns the raw bytes in that file Base64-encoded, rather than
|
||||
interpreting the contents as UTF-8 text.
|
||||
* [`fileexists`](./fileexists.html) determines whether a file exists
|
||||
at a given path.
|
||||
* [`templatefile`](./templatefile.html) renders using a file from disk as a
|
||||
template.
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "filebase64 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-filebase64"
|
||||
description: |-
|
||||
The filebase64 function reads the contents of the file at the given path and
|
||||
returns them as a base64-encoded string.
|
||||
---
|
||||
|
||||
# `filebase64` Function
|
||||
|
||||
`filebase64` reads the contents of a file at the given path and returns them as
|
||||
a base64-encoded string.
|
||||
|
||||
```hcl
|
||||
filebase64(path)
|
||||
```
|
||||
|
||||
The result is a Base64 representation of the raw bytes in the given file.
|
||||
Strings in the Terraform language are sequences of Unicode characters, so
|
||||
Base64 is the standard way to represent raw binary data that cannot be
|
||||
interpreted as Unicode characters. Resource types that operate on binary
|
||||
data will accept this data encoded in Base64, thus avoiding the need to
|
||||
decode the result of this function.
|
||||
|
||||
Terraform uses the "standard" Base64 alphabet as defined in
|
||||
[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
||||
|
||||
This function can be used only with functions that already exist as static
|
||||
files on disk at the beginning of a Terraform run. Language functions do not
|
||||
participate in the dependency graph, so this function cannot be used with
|
||||
files that are generated dynamically during a Terraform operation.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> filebase64("${path.module}/hello.txt")
|
||||
SGVsbG8gV29ybGQ=
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`file`](./file.html) also reads the contents of a given file,
|
||||
but interprets the data as UTF-8 text and returns the result directly
|
||||
as a string, without any further encoding.
|
||||
* [`base64decode`](./base64decode.html) can decode a Base64 string representing
|
||||
bytes in UTF-8, but in practice `base64decode(filebase64(...))` is equivalent
|
||||
to the shorter expression `file(...)`.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "filebase64sha256 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-filebase64sha256"
|
||||
description: |-
|
||||
The filebase64sha256 function computes the SHA256 hash of the contents of
|
||||
a given file and encodes it with Base64.
|
||||
---
|
||||
|
||||
# `filebase64sha256` Function
|
||||
|
||||
`filebase64sha256` is a variant of [`base64sha256`](./base64sha256.html)
|
||||
that hashes the contents of a given file rather than a literal string.
|
||||
|
||||
This is similar to `base64sha256(file(filename))`, but
|
||||
because [`file`](./file.html) accepts only UTF-8 text it cannot be used to
|
||||
create hashes for binary files.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "filebase64sha512 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-filebase64sha512"
|
||||
description: |-
|
||||
The filebase64sha512 function computes the SHA512 hash of the contents of
|
||||
a given file and encodes it with Base64.
|
||||
---
|
||||
|
||||
# `filebase64sha512` Function
|
||||
|
||||
`filebase64sha512` is a variant of [`base64sha512`](./base64sha512.html)
|
||||
that hashes the contents of a given file rather than a literal string.
|
||||
|
||||
This is similar to `base64sha512(file(filename))`, but
|
||||
because [`file`](./file.html) accepts only UTF-8 text it cannot be used to
|
||||
create hashes for binary files.
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "fileexists - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-file-exists"
|
||||
description: |-
|
||||
The fileexists function determines whether a file exists at a given path.
|
||||
---
|
||||
|
||||
# `fileexists` Function
|
||||
|
||||
`fileexists` determines whether a file exists at a given path.
|
||||
|
||||
```hcl
|
||||
fileexists(path)
|
||||
```
|
||||
|
||||
Functions are evaluated during configuration parsing rather than at apply time,
|
||||
so this function can only be used with files that are already present on disk
|
||||
before Terraform takes any actions.
|
||||
|
||||
This function works only with regular files. If used with a directory, FIFO,
|
||||
or other special mode, it will return an error.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> fileexists("${path.module}/hello.txt")
|
||||
true
|
||||
```
|
||||
|
||||
```hcl
|
||||
fileexists("custom-section.sh") ? file("custom-section.sh") : local.default_content
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`file`](./file.html) reads the contents of a file at a given path
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "filemd5 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-filemd5"
|
||||
description: |-
|
||||
The filemd5 function computes the MD5 hash of the contents of
|
||||
a given file and encodes it as hex.
|
||||
---
|
||||
|
||||
# `filemd5` Function
|
||||
|
||||
`filemd5` is a variant of [`md5`](./md5.html)
|
||||
that hashes the contents of a given file rather than a literal string.
|
||||
|
||||
This is similar to `md5(file(filename))`, but
|
||||
because [`file`](./file.html) accepts only UTF-8 text it cannot be used to
|
||||
create hashes for binary files.
|
||||
@@ -1,76 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "fileset - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-file-set"
|
||||
description: |-
|
||||
The fileset function enumerates a set of regular file names given a pattern.
|
||||
---
|
||||
|
||||
# `fileset` Function
|
||||
|
||||
`fileset` enumerates a set of regular file names given a path and pattern.
|
||||
The path is automatically removed from the resulting set of file names and any
|
||||
result still containing path separators always returns forward slash (`/`) as
|
||||
the path separator for cross-system compatibility.
|
||||
|
||||
```hcl
|
||||
fileset(path, pattern)
|
||||
```
|
||||
|
||||
Supported pattern matches:
|
||||
|
||||
- `*` - matches any sequence of non-separator characters
|
||||
- `**` - matches any sequence of characters, including separator characters
|
||||
- `?` - matches any single non-separator character
|
||||
- `{alternative1,...}` - matches a sequence of characters if one of the comma-separated alternatives matches
|
||||
- `[CLASS]` - matches any single non-separator character inside a class of characters (see below)
|
||||
- `[^CLASS]` - matches any single non-separator character outside a class of characters (see below)
|
||||
|
||||
Character classes support the following:
|
||||
|
||||
- `[abc]` - matches any single character within the set
|
||||
- `[a-z]` - matches any single character within the range
|
||||
|
||||
Functions are evaluated during configuration parsing rather than at apply time,
|
||||
so this function can only be used with files that are already present on disk
|
||||
before Terraform takes any actions.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> fileset(path.module, "files/*.txt")
|
||||
[
|
||||
"files/hello.txt",
|
||||
"files/world.txt",
|
||||
]
|
||||
|
||||
> fileset(path.module, "files/{hello,world}.txt")
|
||||
[
|
||||
"files/hello.txt",
|
||||
"files/world.txt",
|
||||
]
|
||||
|
||||
> fileset("${path.module}/files", "*")
|
||||
[
|
||||
"hello.txt",
|
||||
"world.txt",
|
||||
]
|
||||
|
||||
> fileset("${path.module}/files", "**")
|
||||
[
|
||||
"hello.txt",
|
||||
"world.txt",
|
||||
"subdirectory/anotherfile.txt",
|
||||
]
|
||||
```
|
||||
|
||||
A common use of `fileset` is to create one resource instance per matched file, using
|
||||
[the `for_each` meta-argument](/docs/configuration/meta-arguments/for_each.html):
|
||||
|
||||
```hcl
|
||||
resource "example_thing" "example" {
|
||||
for_each = fileset(path.module, "files/*")
|
||||
|
||||
# other configuration using each.value
|
||||
}
|
||||
```
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "filesha1 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-filesha1"
|
||||
description: |-
|
||||
The filesha1 function computes the SHA1 hash of the contents of
|
||||
a given file and encodes it as hex.
|
||||
---
|
||||
|
||||
# `filesha1` Function
|
||||
|
||||
`filesha1` is a variant of [`sha1`](./sha1.html)
|
||||
that hashes the contents of a given file rather than a literal string.
|
||||
|
||||
This is similar to `sha1(file(filename))`, but
|
||||
because [`file`](./file.html) accepts only UTF-8 text it cannot be used to
|
||||
create hashes for binary files.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "filesha256 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-filesha256"
|
||||
description: |-
|
||||
The filesha256 function computes the SHA256 hash of the contents of
|
||||
a given file and encodes it as hex.
|
||||
---
|
||||
|
||||
# `filesha256` Function
|
||||
|
||||
`filesha256` is a variant of [`sha256`](./sha256.html)
|
||||
that hashes the contents of a given file rather than a literal string.
|
||||
|
||||
This is similar to `sha256(file(filename))`, but
|
||||
because [`file`](./file.html) accepts only UTF-8 text it cannot be used to
|
||||
create hashes for binary files.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "filesha512 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-filesha512"
|
||||
description: |-
|
||||
The filesha512 function computes the SHA512 hash of the contents of
|
||||
a given file and encodes it as hex.
|
||||
---
|
||||
|
||||
# `filesha512` Function
|
||||
|
||||
`filesha512` is a variant of [`sha512`](./sha512.html)
|
||||
that hashes the contents of a given file rather than a literal string.
|
||||
|
||||
This is similar to `sha512(file(filename))`, but
|
||||
because [`file`](./file.html) accepts only UTF-8 text it cannot be used to
|
||||
create hashes for binary files.
|
||||
@@ -1,109 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "flatten - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-flatten"
|
||||
description: |-
|
||||
The flatten function eliminates nested lists from a list.
|
||||
---
|
||||
|
||||
# `flatten` Function
|
||||
|
||||
`flatten` takes a list and replaces any elements that are lists with a
|
||||
flattened sequence of the list contents.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> flatten([["a", "b"], [], ["c"]])
|
||||
["a", "b", "c"]
|
||||
```
|
||||
|
||||
If any of the nested lists also contain directly-nested lists, these too are
|
||||
flattened recursively:
|
||||
|
||||
```
|
||||
> flatten([[["a", "b"], []], ["c"]])
|
||||
["a", "b", "c"]
|
||||
```
|
||||
|
||||
Indirectly-nested lists, such as those in maps, are _not_ flattened.
|
||||
|
||||
## Flattening nested structures for `for_each`
|
||||
|
||||
The
|
||||
[resource `for_each`](/docs/configuration/meta-arguments/for_each.html)
|
||||
and
|
||||
[`dynamic` block](/docs/configuration/expressions/dynamic-blocks.html)
|
||||
language features both require a collection value that has one element for
|
||||
each repetition.
|
||||
|
||||
Sometimes your input data structure isn't naturally in a suitable shape for
|
||||
use in a `for_each` argument, and `flatten` can be a useful helper function
|
||||
when reducing a nested data structure into a flat one.
|
||||
|
||||
For example, consider a module that declares a variable like the following:
|
||||
|
||||
```hcl
|
||||
variable "networks" {
|
||||
type = map(object({
|
||||
cidr_block = string
|
||||
subnets = map(object({ cidr_block = string }))
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
The above is a reasonable way to model objects that naturally form a tree,
|
||||
such as top-level networks and their subnets. The repetition for the top-level
|
||||
networks can use this variable directly, because it's already in a form
|
||||
where the resulting instances match one-to-one with map elements:
|
||||
|
||||
```hcl
|
||||
resource "aws_vpc" "example" {
|
||||
for_each = var.networks
|
||||
|
||||
cidr_block = each.value.cidr_block
|
||||
}
|
||||
```
|
||||
|
||||
However, in order to declare all of the _subnets_ with a single `resource`
|
||||
block, we must first flatten the structure to produce a collection where each
|
||||
top-level element represents a single subnet:
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
# flatten ensures that this local value is a flat list of objects, rather
|
||||
# than a list of lists of objects.
|
||||
network_subnets = flatten([
|
||||
for network_key, network in var.networks : [
|
||||
for subnet_key, subnet in network.subnets : {
|
||||
network_key = network_key
|
||||
subnet_key = subnet_key
|
||||
network_id = aws_vpc.example[network_key].id
|
||||
cidr_block = subnet.cidr_block
|
||||
}
|
||||
]
|
||||
])
|
||||
}
|
||||
|
||||
resource "aws_subnet" "example" {
|
||||
# local.network_subnets is a list, so we must now project it into a map
|
||||
# where each key is unique. We'll combine the network and subnet keys to
|
||||
# produce a single unique key per instance.
|
||||
for_each = {
|
||||
for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
|
||||
}
|
||||
|
||||
vpc_id = each.value.network_id
|
||||
availability_zone = each.value.subnet_key
|
||||
cidr_block = each.value.cidr_block
|
||||
}
|
||||
```
|
||||
|
||||
The above results in one subnet instance per subnet object, while retaining
|
||||
the associations between the subnets and their containing networks.
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`setproduct`](./setproduct.html) finds all of the combinations of multiple
|
||||
lists or sets of values, which can also be useful when preparing collections
|
||||
for use with `for_each` constructs.
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "floor - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-floor"
|
||||
description: |-
|
||||
The floor function returns the closest whole number less than or equal to
|
||||
the given value.
|
||||
---
|
||||
|
||||
# `floor` Function
|
||||
|
||||
`floor` returns the closest whole number that is less than or equal to the
|
||||
given value, which may be a fraction.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> floor(5)
|
||||
5
|
||||
> floor(4.9)
|
||||
4
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`ceil`](./ceil.html), which rounds to the nearest whole number _greater than_
|
||||
or equal.
|
||||
@@ -1,125 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "format - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-format-x"
|
||||
description: |-
|
||||
The format function produces a string by formatting a number of other values
|
||||
according to a specification string.
|
||||
---
|
||||
|
||||
# `format` Function
|
||||
|
||||
`format` produces a string by formatting a number of other values according
|
||||
to a specification string. It is similar to the `printf` function in C, and
|
||||
other similar functions in other programming languages.
|
||||
|
||||
```hcl
|
||||
format(spec, values...)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> format("Hello, %s!", "Ander")
|
||||
Hello, Ander!
|
||||
> format("There are %d lights", 4)
|
||||
There are 4 lights
|
||||
```
|
||||
|
||||
Simple format verbs like `%s` and `%d` behave similarly to template
|
||||
interpolation syntax, which is often more readable:
|
||||
|
||||
```
|
||||
> format("Hello, %s!", var.name)
|
||||
Hello, Valentina!
|
||||
> "Hello, ${var.name}!"
|
||||
Hello, Valentina!
|
||||
```
|
||||
|
||||
The `format` function is therefore more useful when you use more complex format
|
||||
specifications, as described in the following section.
|
||||
|
||||
## Specification Syntax
|
||||
|
||||
The specification is a string that includes formatting verbs that are introduced
|
||||
with the `%` character. The function call must then have one additional argument
|
||||
for each verb sequence in the specification. The verbs are matched with
|
||||
consecutive arguments and formatted as directed, as long as each given argument
|
||||
is convertible to the type required by the format verb.
|
||||
|
||||
The specification may contain the following verbs:
|
||||
|
||||
| Verb | Result |
|
||||
| ----- | ----------------------------------------------------------------------------------------- |
|
||||
| `%%` | Literal percent sign, consuming no value. |
|
||||
| `%v` | Default formatting based on the value type, as described below. |
|
||||
| `%#v` | JSON serialization of the value, as with `jsonencode`. |
|
||||
| `%t` | Convert to boolean and produce `true` or `false`. |
|
||||
| `%b` | Convert to integer number and produce binary representation. |
|
||||
| `%d` | Convert to integer number and produce decimal representation. |
|
||||
| `%o` | Convert to integer number and produce octal representation. |
|
||||
| `%x` | Convert to integer number and produce hexadecimal representation with lowercase letters. |
|
||||
| `%X` | Like `%x`, but use uppercase letters. |
|
||||
| `%e` | Convert to number and produce scientific notation, like `-1.234456e+78`. |
|
||||
| `%E` | Like `%e`, but use an uppercase `E` to introduce the exponent. |
|
||||
| `%f` | Convert to number and produce decimal fraction notation with no exponent, like `123.456`. |
|
||||
| `%g` | Like `%e` for large exponents or like `%f` otherwise. |
|
||||
| `%G` | Like `%E` for large exponents or like `%f` otherwise. |
|
||||
| `%s` | Convert to string and insert the string's characters. |
|
||||
| `%q` | Convert to string and produce a JSON quoted string representation. |
|
||||
|
||||
When `%v` is used, one of the following format verbs is chosen based on the value type:
|
||||
|
||||
| Type | Verb |
|
||||
| --------- | ----- |
|
||||
| `string` | `%s` |
|
||||
| `number` | `%g` |
|
||||
| `bool` | `%t` |
|
||||
| any other | `%#v` |
|
||||
|
||||
Null values produce the string `null` if formatted with `%v` or `%#v`, and
|
||||
cause an error for other verbs.
|
||||
|
||||
A width modifier can be included with an optional decimal number immediately
|
||||
preceding the verb letter, to specify how many characters will be used to
|
||||
represent the value. Precision can be specified after the (optional) width
|
||||
with a period (`.`) followed by a decimal number. If width or precision are
|
||||
omitted then default values are selected based on the given value. For example:
|
||||
|
||||
| Sequence | Result |
|
||||
| -------- | ---------------------------- |
|
||||
| `%f` | Default width and precision. |
|
||||
| `%9f` | Width 9, default precision. |
|
||||
| `%.2f` | Default width, precision 2. |
|
||||
| `%9.2f` | Width 9, precision 2. |
|
||||
|
||||
The following additional symbols can be used immediately after the `%` symbol
|
||||
to set additional flags:
|
||||
|
||||
| Symbol | Result |
|
||||
| ------ | -------------------------------------------------------------- |
|
||||
| space | Leave a space where the sign would be if a number is positive. |
|
||||
| `+` | Show the sign of a number even if it is positive. |
|
||||
| `-` | Pad the width with spaces on the left rather than the right. |
|
||||
| `0` | Pad the width with leading zeros rather than spaces. |
|
||||
|
||||
By default, `%` sequences consume successive arguments starting with the first.
|
||||
Introducing a `[n]` sequence immediately before the verb letter, where `n` is a
|
||||
decimal integer, explicitly chooses a particular value argument by its
|
||||
one-based index. Subsequent calls without an explicit index will then proceed
|
||||
with `n`+1, `n`+2, etc.
|
||||
|
||||
The function produces an error if the format string requests an impossible
|
||||
conversion or access more arguments than are given. An error is produced also
|
||||
for an unsupported format verb.
|
||||
|
||||
-> **Note:** Width and precision modifiers with non-numeric types such as
|
||||
strings (`%s`) are interpreted differently. Setting either width or precision to
|
||||
zero is the same as not including them at all.
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`formatdate`](./formatdate.html) is a specialized formatting function for
|
||||
human-readable timestamps.
|
||||
* [`formatlist`](./formatlist.html) uses the same specification syntax to
|
||||
produce a list of strings.
|
||||
@@ -1,108 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "formatdate - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-datetime-formatdate"
|
||||
description: |-
|
||||
The formatdate function converts a timestamp into a different time format.
|
||||
---
|
||||
|
||||
# `formatdate` Function
|
||||
|
||||
`formatdate` converts a timestamp into a different time format.
|
||||
|
||||
```hcl
|
||||
formatdate(spec, timestamp)
|
||||
```
|
||||
|
||||
In the Terraform language, timestamps are conventionally represented as
|
||||
strings using [RFC 3339](https://tools.ietf.org/html/rfc3339)
|
||||
"Date and Time format" syntax. `formatdate` requires the `timestamp` argument
|
||||
to be a string conforming to this syntax.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> formatdate("DD MMM YYYY hh:mm ZZZ", "2018-01-02T23:12:01Z")
|
||||
02 Jan 2018 23:12 UTC
|
||||
> formatdate("EEEE, DD-MMM-YY hh:mm:ss ZZZ", "2018-01-02T23:12:01Z")
|
||||
Tuesday, 02-Jan-18 23:12:01 UTC
|
||||
> formatdate("EEE, DD MMM YYYY hh:mm:ss ZZZ", "2018-01-02T23:12:01-08:00")
|
||||
Tue, 02 Jan 2018 23:12:01 -0800
|
||||
> formatdate("MMM DD, YYYY", "2018-01-02T23:12:01Z")
|
||||
Jan 02, 2018
|
||||
> formatdate("HH:mmaa", "2018-01-02T23:12:01Z")
|
||||
11:12pm
|
||||
```
|
||||
|
||||
## Specification Syntax
|
||||
|
||||
The format specification is a string that includes formatting sequences from
|
||||
the following table. This function is intended for producing common
|
||||
_machine-oriented_ timestamp formats such as those defined in RFC822, RFC850,
|
||||
and RFC1123. It is not suitable for truly human-oriented date formatting
|
||||
because it is not locale-aware. In particular, it can produce month and day
|
||||
names only in English.
|
||||
|
||||
The specification may contain the following sequences:
|
||||
|
||||
| Sequence | Result |
|
||||
| --------- | ------------------------------------------------------------------------ |
|
||||
| `YYYY` | Four (or more) digit year, like "2006". |
|
||||
| `YY` | The year modulo 100, zero padded to at least two digits, like "06". |
|
||||
| `MMMM` | English month name unabbreviated, like "January". |
|
||||
| `MMM` | English month name abbreviated to three letters, like "Jan". |
|
||||
| `MM` | Month number zero-padded to two digits, like "01" for January. |
|
||||
| `M` | Month number with no padding, like "1" for January. |
|
||||
| `DD` | Day of month number zero-padded to two digits, like "02". |
|
||||
| `D` | Day of month number with no padding, like "2". |
|
||||
| `EEEE` | English day of week name unabbreviated, like "Monday". |
|
||||
| `EEE` | English day of week name abbreviated to three letters, like "Mon". |
|
||||
| `hh` | 24-hour number zero-padded to two digits, like "02". |
|
||||
| `h` | 24-hour number unpadded, like "2". |
|
||||
| `HH` | 12-hour number zero-padded to two digits, like "02". |
|
||||
| `H` | 12-hour number unpadded, like "2". |
|
||||
| `AA` | Hour AM/PM marker in uppercase, like "AM". |
|
||||
| `aa` | Hour AM/PM marker in lowercase, like "am". |
|
||||
| `mm` | Minute within hour zero-padded to two digits, like "05". |
|
||||
| `m` | Minute within hour unpadded, like "5". |
|
||||
| `ss` | Second within minute zero-padded to two digits, like "09". |
|
||||
| `s` | Second within minute, like "9". |
|
||||
| `ZZZZZ` | Timezone offset with colon separating hours and minutes, like "-08:00". |
|
||||
| `ZZZZ` | Timezone offset with just sign and digit, like "-0800". |
|
||||
| `ZZZ` | Like `ZZZZ` but with a special case "UTC" for UTC. |
|
||||
| `Z` | Like `ZZZZZ` but with a special case "Z" for UTC. |
|
||||
|
||||
Any non-letter characters, such as punctuation, are reproduced verbatim in the
|
||||
output. To include literal letters in the format string, enclose them in single
|
||||
quotes `'`. To include a literal quote, escape it by doubling the quotes.
|
||||
|
||||
```
|
||||
> formatdate("h'h'mm", "2018-01-02T23:12:01-08:00")
|
||||
23h12
|
||||
> formatdate("H 'o''clock'", "2018-01-02T23:12:01-08:00")
|
||||
11 o'clock
|
||||
```
|
||||
|
||||
This format specification syntax is intended to make it easy for a reader
|
||||
to guess which format will result even if they are not experts on the syntax.
|
||||
Therefore there are no predefined shorthands for common formats, but format
|
||||
strings for various RFC-specified formats are given below to be copied into your
|
||||
configuration as needed:
|
||||
|
||||
- [RFC 822](https://tools.ietf.org/html/rfc822#section-5) and
|
||||
[RFC RFC 2822](https://tools.ietf.org/html/rfc2822#section-3.3):
|
||||
`"DD MMM YYYY hh:mm ZZZ"`
|
||||
- [RFC 850](https://tools.ietf.org/html/rfc850#section-2.1.4):
|
||||
`"EEEE, DD-MMM-YY hh:mm:ss ZZZ"`
|
||||
- [RFC 1123](https://tools.ietf.org/html/rfc1123#section-5.2.14):
|
||||
`"EEE, DD MMM YYYY hh:mm:ss ZZZ"`
|
||||
- [RFC 3339](https://tools.ietf.org/html/rfc3339):
|
||||
`"YYYY-MM-DD'T'hh:mm:ssZ"` (but this is also the input format, so such a
|
||||
conversion is redundant.)
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`format`](./format.html) is a more general formatting function for arbitrary
|
||||
data.
|
||||
* [`timestamp`](./timestamp.html) returns the current date and time in a format
|
||||
suitable for input to `formatdate`.
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "formatlist - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-formatlist"
|
||||
description: |-
|
||||
The formatlist function produces a list of strings by formatting a number of
|
||||
other values according to a specification string.
|
||||
---
|
||||
|
||||
# `formatlist` Function
|
||||
|
||||
`formatlist` produces a list of strings by formatting a number of other
|
||||
values according to a specification string.
|
||||
|
||||
```hcl
|
||||
formatlist(spec, values...)
|
||||
```
|
||||
|
||||
The specification string uses
|
||||
[the same syntax as `format`](./format.html#specification-syntax).
|
||||
|
||||
The given values can be a mixture of list and non-list arguments. Any given
|
||||
lists must be the same length, which decides the length of the resulting list.
|
||||
|
||||
The list arguments are iterated together in order by index, while the non-list
|
||||
arguments are used repeatedly for each iteration. The format string is evaluated
|
||||
once per element of the list arguments.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> formatlist("Hello, %s!", ["Valentina", "Ander", "Olivia", "Sam"])
|
||||
[
|
||||
"Hello, Valentina!",
|
||||
"Hello, Ander!",
|
||||
"Hello, Olivia!",
|
||||
"Hello, Sam!",
|
||||
]
|
||||
> formatlist("%s, %s!", "Salutations", ["Valentina", "Ander", "Olivia", "Sam"])
|
||||
[
|
||||
"Salutations, Valentina!",
|
||||
"Salutations, Ander!",
|
||||
"Salutations, Olivia!",
|
||||
"Salutations, Sam!",
|
||||
]
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`format`](./format.html) defines the specification syntax used by this
|
||||
function and produces a single string as its result.
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "indent - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-indent"
|
||||
description: |-
|
||||
The indent function adds a number of spaces to the beginnings of all but the
|
||||
first line of a given multi-line string.
|
||||
---
|
||||
|
||||
# `indent` Function
|
||||
|
||||
`indent` adds a given number of spaces to the beginnings of all but the first
|
||||
line in a given multi-line string.
|
||||
|
||||
```hcl
|
||||
indent(num_spaces, string)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
This function is useful for inserting a multi-line string into an
|
||||
already-indented context in another string:
|
||||
|
||||
```
|
||||
> " items: ${indent(2, "[\n foo,\n bar,\n]\n")}"
|
||||
items: [
|
||||
foo,
|
||||
bar,
|
||||
]
|
||||
```
|
||||
|
||||
The first line of the string is not indented so that, as above, it can be
|
||||
placed after an introduction sequence that has already begun the line.
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "index - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-index"
|
||||
description: |-
|
||||
The index function finds the element index for a given value in a list.
|
||||
---
|
||||
|
||||
# `index` Function
|
||||
|
||||
`index` finds the element index for a given value in a list.
|
||||
|
||||
```hcl
|
||||
index(list, value)
|
||||
```
|
||||
|
||||
The returned index is zero-based. This function produces an error if the given
|
||||
value is not present in the list.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> index(["a", "b", "c"], "b")
|
||||
1
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`element`](./element.html) retrieves a particular element from a list given
|
||||
its index.
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "join - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-join"
|
||||
description: |-
|
||||
The join function produces a string by concatenating the elements of a list
|
||||
with a given delimiter.
|
||||
---
|
||||
|
||||
# `join` Function
|
||||
|
||||
`join` produces a string by concatenating together all elements of a given
|
||||
list of strings with the given delimiter.
|
||||
|
||||
```hcl
|
||||
join(separator, list)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> join(", ", ["foo", "bar", "baz"])
|
||||
foo, bar, baz
|
||||
> join(", ", ["foo"])
|
||||
foo
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`split`](./split.html) performs the opposite operation: producing a list
|
||||
by separating a single string using a given delimiter.
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "jsondecode - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-encoding-jsondecode"
|
||||
description: |-
|
||||
The jsondecode function decodes a JSON string into a representation of its
|
||||
value.
|
||||
---
|
||||
|
||||
# `jsondecode` Function
|
||||
|
||||
`jsondecode` interprets a given string as JSON, returning a representation
|
||||
of the result of decoding that string.
|
||||
|
||||
The JSON encoding is defined in [RFC 7159](https://tools.ietf.org/html/rfc7159).
|
||||
|
||||
This function maps JSON values to
|
||||
[Terraform language values](/docs/configuration/expressions/types.html)
|
||||
in the following way:
|
||||
|
||||
| JSON type | Terraform type |
|
||||
| --------- | ------------------------------------------------------------ |
|
||||
| String | `string` |
|
||||
| Number | `number` |
|
||||
| Boolean | `bool` |
|
||||
| Object | `object(...)` with attribute types determined per this table |
|
||||
| Array | `tuple(...)` with element types determined per this table |
|
||||
| Null | The Terraform language `null` value |
|
||||
|
||||
The Terraform language automatic type conversion rules mean that you don't
|
||||
usually need to worry about exactly what type is produced for a given value,
|
||||
and can just use the result in an intuitive way.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> jsondecode("{\"hello\": \"world\"}")
|
||||
{
|
||||
"hello" = "world"
|
||||
}
|
||||
> jsondecode("true")
|
||||
true
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`jsonencode`](./jsonencode.html) performs the opposite operation, _encoding_
|
||||
a value as JSON.
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "jsonencode - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-encoding-jsonencode"
|
||||
description: |-
|
||||
The jsonencode function encodes a given value as a JSON string.
|
||||
---
|
||||
|
||||
# `jsonencode` Function
|
||||
|
||||
`jsonencode` encodes a given value to a string using JSON syntax.
|
||||
|
||||
The JSON encoding is defined in [RFC 7159](https://tools.ietf.org/html/rfc7159).
|
||||
|
||||
This function maps
|
||||
[Terraform language values](/docs/configuration/expressions/types.html)
|
||||
to JSON values in the following way:
|
||||
|
||||
| Terraform type | JSON type |
|
||||
| -------------- | --------- |
|
||||
| `string` | String |
|
||||
| `number` | Number |
|
||||
| `bool` | Bool |
|
||||
| `list(...)` | Array |
|
||||
| `set(...)` | Array |
|
||||
| `tuple(...)` | Array |
|
||||
| `map(...)` | Object |
|
||||
| `object(...)` | Object |
|
||||
| Null value | `null` |
|
||||
|
||||
Since the JSON format cannot fully represent all of the Terraform language
|
||||
types, passing the `jsonencode` result to `jsondecode` will not produce an
|
||||
identical value, but the automatic type conversion rules mean that this is
|
||||
rarely a problem in practice.
|
||||
|
||||
When encoding strings, this function escapes some characters using
|
||||
Unicode escape sequences: replacing `<`, `>`, `&`, `U+2028`, and `U+2029` with
|
||||
`\u003c`, `\u003e`, `\u0026`, `\u2028`, and `\u2029`. This is to preserve
|
||||
compatibility with Terraform 0.11 behavior.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> jsonencode({"hello"="world"})
|
||||
{"hello":"world"}
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`jsondecode`](./jsondecode.html) performs the opposite operation, _decoding_
|
||||
a JSON string to obtain its represented value.
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "keys - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-keys"
|
||||
description: |-
|
||||
The keys function returns a list of the keys in a given map.
|
||||
---
|
||||
|
||||
# `keys` Function
|
||||
|
||||
`keys` takes a map and returns a list containing the keys from that map.
|
||||
|
||||
The keys are returned in lexicographical order, ensuring that the result will
|
||||
be identical as long as the keys in the map don't change.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> keys({a=1, c=2, d=3})
|
||||
[
|
||||
"a",
|
||||
"c",
|
||||
"d",
|
||||
]
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`values`](./values.html) returns a list of the _values_ from a map.
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "length - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-length"
|
||||
description: |-
|
||||
The length function determines the length of a collection or string.
|
||||
---
|
||||
|
||||
# `length` Function
|
||||
|
||||
`length` determines the length of a given list, map, or string.
|
||||
|
||||
If given a list or map, the result is the number of elements in that collection.
|
||||
If given a string, the result is the number of characters in the string.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> length([])
|
||||
0
|
||||
> length(["a", "b"])
|
||||
2
|
||||
> length({"a" = "b"})
|
||||
1
|
||||
> length("hello")
|
||||
5
|
||||
```
|
||||
|
||||
When given a string, the result is the number of characters, rather than the
|
||||
number of bytes or Unicode sequences that form them:
|
||||
|
||||
```
|
||||
> length("👾🕹️")
|
||||
2
|
||||
```
|
||||
|
||||
A "character" is a _grapheme cluster_, as defined by
|
||||
[Unicode Standard Annex #29](http://unicode.org/reports/tr29/). Note that
|
||||
remote APIs may have a different definition of "character" for the purpose of
|
||||
length limits on string arguments; a Terraform provider is responsible for
|
||||
translating Terraform's string representation into that used by its respective
|
||||
remote system and applying any additional validation rules to it.
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "list - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-list"
|
||||
description: |-
|
||||
The list function constructs a list from some given elements.
|
||||
---
|
||||
|
||||
# `list` Function
|
||||
|
||||
The `list` function is no longer available. Prior to Terraform v0.12 it was
|
||||
the only available syntax for writing a literal list inside an expression,
|
||||
but Terraform v0.12 introduced a new first-class syntax.
|
||||
|
||||
To update an expression like `list(a, b, c)`, write the following instead:
|
||||
|
||||
```
|
||||
tolist([a, b, c])
|
||||
```
|
||||
|
||||
The `[ ... ]` brackets construct a tuple value, and then the `tolist` function
|
||||
then converts it to a list. For more information on the value types in the
|
||||
Terraform language, see [Type Constraints](../types.html).
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`concat`](./concat.html) produces a new list by concatenating together the
|
||||
elements from other lists.
|
||||
* [`tolist`](./tolist.html) converts a set or tuple value to a list.
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "log - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-log"
|
||||
description: |-
|
||||
The log function returns the logarithm of a given number in a given base.
|
||||
---
|
||||
|
||||
# `log` Function
|
||||
|
||||
`log` returns the logarithm of a given number in a given base.
|
||||
|
||||
```hcl
|
||||
log(number, base)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> log(50, 10)
|
||||
1.6989700043360185
|
||||
> log(16, 2)
|
||||
4
|
||||
```
|
||||
|
||||
`log` and `ceil` can be used together to find the minimum number of binary
|
||||
digits required to represent a given number of distinct values:
|
||||
|
||||
```
|
||||
> ceil(log(15, 2))
|
||||
4
|
||||
> ceil(log(16, 2))
|
||||
4
|
||||
> ceil(log(17, 2))
|
||||
5
|
||||
```
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "lookup - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-lookup"
|
||||
description: |-
|
||||
The lookup function retrieves an element value from a map given its key.
|
||||
---
|
||||
|
||||
# `lookup` Function
|
||||
|
||||
`lookup` retrieves the value of a single element from a map, given its key.
|
||||
If the given key does not exist, the given default value is returned instead.
|
||||
|
||||
```
|
||||
lookup(map, key, default)
|
||||
```
|
||||
|
||||
-> For historical reasons, the `default` parameter is actually optional. However,
|
||||
omitting `default` is deprecated since v0.7 because that would then be
|
||||
equivalent to the native index syntax, `map[key]`.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> lookup({a="ay", b="bee"}, "a", "what?")
|
||||
ay
|
||||
> lookup({a="ay", b="bee"}, "c", "what?")
|
||||
what?
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`element`](./element.html) retrieves a value from a _list_ given its _index_.
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "lower - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-lower"
|
||||
description: |-
|
||||
The lower function converts all cased letters in the given string to lowercase.
|
||||
---
|
||||
|
||||
# `lower` Function
|
||||
|
||||
`lower` converts all cased letters in the given string to lowercase.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> lower("HELLO")
|
||||
hello
|
||||
> lower("АЛЛО!")
|
||||
алло!
|
||||
```
|
||||
|
||||
This function uses Unicode's definition of letters and of upper- and lowercase.
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`upper`](./upper.html) converts letters in a string to _uppercase_.
|
||||
* [`title`](./title.html) converts the first letter of each word in a string to uppercase.
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "map - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-map"
|
||||
description: |-
|
||||
The map function constructs a map from some given elements.
|
||||
---
|
||||
|
||||
# `map` Function
|
||||
|
||||
The `map` function is no longer available. Prior to Terraform v0.12 it was
|
||||
the only available syntax for writing a literal map inside an expression,
|
||||
but Terraform v0.12 introduced a new first-class syntax.
|
||||
|
||||
To update an expression like `map("a", "b", "c", "d")`, write the following instead:
|
||||
|
||||
```
|
||||
tomap({
|
||||
a = "b"
|
||||
c = "d"
|
||||
})
|
||||
```
|
||||
|
||||
The `{ ... }` braces construct an object value, and then the `tomap` function
|
||||
then converts it to a map. For more information on the value types in the
|
||||
Terraform language, see [Type Constraints](../types.html).
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`tomap`](./tomap.html) converts an object value to a map.
|
||||
* [`zipmap`](./zipmap.html) constructs a map dynamically, by taking keys from
|
||||
one list and values from another list.
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "matchkeys - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-matchkeys"
|
||||
description: |-
|
||||
The matchkeys function takes a subset of elements from one list by matching
|
||||
corresponding indexes in another list.
|
||||
---
|
||||
|
||||
# `matchkeys` Function
|
||||
|
||||
`matchkeys` constructs a new list by taking a subset of elements from one
|
||||
list whose indexes match the corresponding indexes of values in another
|
||||
list.
|
||||
|
||||
```hcl
|
||||
matchkeys(valueslist, keyslist, searchset)
|
||||
```
|
||||
|
||||
`matchkeys` identifies the indexes in `keyslist` that are equal to elements of
|
||||
`searchset`, and then constructs a new list by taking those same indexes from
|
||||
`valueslist`. Both `valueslist` and `keyslist` must be the same length.
|
||||
|
||||
The ordering of the values in `valueslist` is preserved in the result.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> matchkeys(["i-123", "i-abc", "i-def"], ["us-west", "us-east", "us-east"], ["us-east"])
|
||||
[
|
||||
"i-abc",
|
||||
"i-def",
|
||||
]
|
||||
```
|
||||
|
||||
If the result ordering is not significant, you can achieve a similar result
|
||||
using a `for` expression with a map:
|
||||
|
||||
```
|
||||
> [for i, z in {"i-123"="us-west","i-abc"="us-east","i-def"="us-east"}: i if z == "us-east"]
|
||||
[
|
||||
"i-def",
|
||||
"i-abc",
|
||||
]
|
||||
```
|
||||
|
||||
If the keys and values of interest are attributes of objects in a list of
|
||||
objects then you can also achieve a similar result using a `for` expression
|
||||
with that list:
|
||||
|
||||
```
|
||||
> [for x in [{id="i-123",zone="us-west"},{id="i-abc",zone="us-east"}]: x.id if x.zone == "us-east"]
|
||||
[
|
||||
"i-abc",
|
||||
]
|
||||
```
|
||||
|
||||
For example, the previous form can be used with the list of resource instances
|
||||
produced by a `resource` block with the `count` meta-attribute set, to filter
|
||||
the instances by matching one of the resource attributes:
|
||||
|
||||
```
|
||||
> [for x in aws_instance.example: x.id if x.availability_zone == "us-east-1a"]
|
||||
[
|
||||
"i-abc123",
|
||||
"i-def456",
|
||||
]
|
||||
```
|
||||
|
||||
Since the signature of `matchkeys` is complicated and not immediately clear to
|
||||
the reader when used in configuration, prefer to use `for` expressions where
|
||||
possible to maximize readability.
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "max - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-max"
|
||||
description: |-
|
||||
The max function takes one or more numbers and returns the greatest number.
|
||||
---
|
||||
|
||||
# `max` Function
|
||||
|
||||
`max` takes one or more numbers and returns the greatest number from the set.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> max(12, 54, 3)
|
||||
54
|
||||
```
|
||||
|
||||
If the numbers are in a list or set value, use `...` to expand the collection
|
||||
to individual arguments:
|
||||
|
||||
```
|
||||
> max([12, 54, 3]...)
|
||||
54
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`min`](./min.html), which returns the _smallest_ number from a set.
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "md5 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-md5"
|
||||
description: |-
|
||||
The md5 function computes the MD5 hash of a given string and encodes it
|
||||
with hexadecimal digits.
|
||||
---
|
||||
|
||||
# `md5` Function
|
||||
|
||||
`md5` computes the MD5 hash of a given string and encodes it with
|
||||
hexadecimal digits.
|
||||
|
||||
The given string is first encoded as UTF-8 and then the MD5 algorithm is applied
|
||||
as defined in [RFC 1321](https://tools.ietf.org/html/rfc1321). The raw hash is
|
||||
then encoded to lowercase hexadecimal digits before returning.
|
||||
|
||||
Before using this function for anything security-sensitive, refer to
|
||||
[RFC 6151](https://tools.ietf.org/html/rfc6151) for updated security
|
||||
considerations applying to the MD5 algorithm.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> md5("hello world")
|
||||
5eb63bbbe01eeed093cb22bb8f5acdc3
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`filemd5`](./filemd5.html) calculates the same hash from
|
||||
the contents of a file rather than from a string value.
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "merge - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-merge"
|
||||
description: |-
|
||||
The merge function takes an arbitrary number maps or objects, and returns a
|
||||
single map or object that contains a merged set of elements from all
|
||||
arguments.
|
||||
---
|
||||
|
||||
# `merge` Function
|
||||
|
||||
`merge` takes an arbitrary number of maps or objects, and returns a single map
|
||||
or object that contains a merged set of elements from all arguments.
|
||||
|
||||
If more than one given map or object defines the same key or attribute, then
|
||||
the one that is later in the argument sequence takes precedence. If the
|
||||
argument types do not match, the resulting type will be an object matching the
|
||||
type structure of the attributes after the merging rules have been applied.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> merge({a="b", c="d"}, {e="f", c="z"})
|
||||
{
|
||||
"a" = "b"
|
||||
"c" = "z"
|
||||
"e" = "f"
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
> merge({a="b"}, {a=[1,2], c="z"}, {d=3})
|
||||
{
|
||||
"a" = [
|
||||
1,
|
||||
2,
|
||||
]
|
||||
"c" = "z"
|
||||
"d" = 3
|
||||
}
|
||||
```
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "min - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-min"
|
||||
description: |-
|
||||
The min function takes one or more numbers and returns the smallest number.
|
||||
---
|
||||
|
||||
# `min` Function
|
||||
|
||||
`min` takes one or more numbers and returns the smallest number from the set.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> min(12, 54, 3)
|
||||
3
|
||||
```
|
||||
|
||||
If the numbers are in a list or set value, use `...` to expand the collection
|
||||
to individual arguments:
|
||||
|
||||
```
|
||||
> min([12, 54, 3]...)
|
||||
3
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`max`](./max.html), which returns the _greatest_ number from a set.
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "parseint - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-parseint"
|
||||
description: |-
|
||||
The parseint function parses the given string as a representation of an integer.
|
||||
---
|
||||
|
||||
# `parseint` Function
|
||||
|
||||
`parseint` parses the given string as a representation of an integer in
|
||||
the specified base and returns the resulting number. The base must be between 2
|
||||
and 62 inclusive.
|
||||
|
||||
All bases use the arabic numerals 0 through 9 first. Bases between 11 and 36
|
||||
inclusive use case-insensitive latin letters to represent higher unit values.
|
||||
Bases 37 and higher use lowercase latin letters and then uppercase latin
|
||||
letters.
|
||||
|
||||
If the given string contains any non-digit characters or digit characters that
|
||||
are too large for the given base then `parseint` will produce an error.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> parseint("100", 10)
|
||||
100
|
||||
|
||||
> parseint("FF", 16)
|
||||
255
|
||||
|
||||
> parseint("-10", 16)
|
||||
-16
|
||||
|
||||
> parseint("1011111011101111", 2)
|
||||
48879
|
||||
|
||||
> parseint("aA", 62)
|
||||
656
|
||||
|
||||
> parseint("12", 2)
|
||||
|
||||
Error: Invalid function argument
|
||||
|
||||
Invalid value for "number" parameter: cannot parse "12" as a base 2 integer.
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`format`](./format.html) can format numbers and other values into strings,
|
||||
with optional zero padding, alignment, etc.
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "pathexpand - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-file-pathexpand"
|
||||
description: |-
|
||||
The pathexpand function expands a leading ~ character to the current user's
|
||||
home directory.
|
||||
---
|
||||
|
||||
# `pathexpand` Function
|
||||
|
||||
`pathexpand` takes a filesystem path that might begin with a `~` segment,
|
||||
and if so it replaces that segment with the current user's home directory
|
||||
path.
|
||||
|
||||
This function works only with the path string and does not access the
|
||||
filesystem itself. It is therefore unable to take into account filesystem
|
||||
features such as symlinks.
|
||||
|
||||
If the leading segment in the path is not `~` then the given path is returned
|
||||
unmodified.
|
||||
|
||||
Using this function in resource arguments will cause spurious diffs if the
|
||||
same configuration is run by multiple users with different home directory
|
||||
paths, or used on different host operating systems. We recommend using this
|
||||
function only for transient values, such as in `connection` and `provisioner`
|
||||
blocks to locate SSH keys, etc.
|
||||
|
||||
The rules for determining the "home directory" for the current user vary
|
||||
depending on host operating system.
|
||||
|
||||
**For Unix systems**, the following sources are consulted, in order of preference:
|
||||
|
||||
* The `HOME` environment variable.
|
||||
* The result of running `getent passwd` followed by the Terraform process uid.
|
||||
* The result of running `cd && pwd` in `sh`.
|
||||
|
||||
**For Windows systems**, there is not really the concept of a home directory
|
||||
in the same sense as on Unix, but the following sources are consulted in
|
||||
order of preference:
|
||||
|
||||
* The `HOME` environment variable.
|
||||
* The `HOMEDRIVE` and `HOMEPATH` environment variables, if both are set.
|
||||
* The `USERPROFILE` environment variable.
|
||||
|
||||
The exact rules employed for each operating system may change in future
|
||||
releases of Terraform.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> pathexpand("~/.ssh/id_rsa")
|
||||
/home/steve/.ssh/id_rsa
|
||||
> pathexpand("/etc/resolv.conf")
|
||||
/etc/resolv.conf
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "pow - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-numeric-pow"
|
||||
description: |-
|
||||
The pow function raises a number to a power.
|
||||
---
|
||||
|
||||
# `pow` Function
|
||||
|
||||
`pow` calculates an exponent, by raising its first argument to the power of the second argument.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> pow(3, 2)
|
||||
9
|
||||
> pow(4, 0)
|
||||
1
|
||||
```
|
||||
@@ -1,142 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "range - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-range"
|
||||
description: |-
|
||||
The range function generates sequences of numbers.
|
||||
---
|
||||
|
||||
# `range` Function
|
||||
|
||||
`range` generates a list of numbers using a start value, a limit value,
|
||||
and a step value.
|
||||
|
||||
```hcl
|
||||
range(max)
|
||||
range(start, limit)
|
||||
range(start, limit, step)
|
||||
```
|
||||
|
||||
The `start` and `step` arguments can be omitted, in which case `start` defaults
|
||||
to zero and `step` defaults to either one or negative one depending on whether
|
||||
`limit` is greater than or less than `start`.
|
||||
|
||||
The resulting list is created by starting with the given `start` value and
|
||||
repeatedly adding `step` to it until the result is equal to or beyond `limit`.
|
||||
|
||||
The interpretation of `limit` depends on the direction of `step`: for a positive
|
||||
step, the sequence is complete when the next number is greater than or equal
|
||||
to `limit`. For a negative step, it's complete when less than or equal.
|
||||
|
||||
The sequence-building algorithm follows the following pseudocode:
|
||||
|
||||
```
|
||||
let num = start
|
||||
while num < limit: (or, for negative step, num >= limit)
|
||||
append num to the sequence
|
||||
num = num + step
|
||||
return the sequence
|
||||
```
|
||||
|
||||
Because the sequence is created as a physical list in memory, Terraform imposes
|
||||
an artificial limit of 1024 numbers in the resulting sequence in order to avoid
|
||||
unbounded memory usage if, for example, a very large value were accidentally
|
||||
passed as the limit or a very small value as the step. If the algorithm above
|
||||
would append the 1025th number to the sequence, the function immediately exits
|
||||
with an error.
|
||||
|
||||
We recommend iterating over existing collections where possible, rather than
|
||||
creating ranges. However, creating small numerical sequences can sometimes
|
||||
be useful when combined with other collections in collection-manipulation
|
||||
functions or `for` expressions.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> range(3)
|
||||
[
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
]
|
||||
|
||||
> range(1, 4)
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]
|
||||
|
||||
> range(1, 8, 2)
|
||||
[
|
||||
1,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
]
|
||||
|
||||
> range(1, 4, 0.5)
|
||||
[
|
||||
1,
|
||||
1.5,
|
||||
2,
|
||||
2.5,
|
||||
3,
|
||||
3.5,
|
||||
]
|
||||
|
||||
> range(4, 1)
|
||||
[
|
||||
4,
|
||||
3,
|
||||
2,
|
||||
]
|
||||
|
||||
> range(10, 5, -2)
|
||||
[
|
||||
10,
|
||||
8,
|
||||
6,
|
||||
]
|
||||
```
|
||||
|
||||
The `range` function is primarily useful when working with other collections
|
||||
to produce a certain number of instances of something. For example:
|
||||
|
||||
```hcl
|
||||
variable "name_counts" {
|
||||
type = map(number)
|
||||
default = {
|
||||
"foo" = 2
|
||||
"bar" = 4
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
expanded_names = {
|
||||
for name, count in var.name_counts : name => [
|
||||
for i in range(count) : format("%s%02d", name, i)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
output "expanded_names" {
|
||||
value = local.expanded_names
|
||||
}
|
||||
|
||||
# Produces the following expanded_names value when run with the default
|
||||
# "name_counts":
|
||||
#
|
||||
# {
|
||||
# "bar" = [
|
||||
# "bar00",
|
||||
# "bar01",
|
||||
# "bar02",
|
||||
# "bar03",
|
||||
# ]
|
||||
# "foo" = [
|
||||
# "foo00",
|
||||
# "foo01",
|
||||
# ]
|
||||
# }
|
||||
```
|
||||
@@ -1,163 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "regex - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-regex"
|
||||
description: |-
|
||||
The regex function applies a regular expression to a string and returns the
|
||||
matching substrings.
|
||||
---
|
||||
|
||||
# `regex` Function
|
||||
|
||||
`regex` applies a
|
||||
[regular expression](https://en.wikipedia.org/wiki/Regular_expression)
|
||||
to a string and returns the matching substrings.
|
||||
|
||||
```hcl
|
||||
regex(pattern, string)
|
||||
```
|
||||
|
||||
The return type of `regex` depends on the capture groups, if any, in the
|
||||
pattern:
|
||||
|
||||
- If the pattern has no capture groups at all, the result is a single string
|
||||
covering the substring matched by the pattern as a whole.
|
||||
- If the pattern has one or more _unnamed_ capture groups, the result is a
|
||||
list of the captured substrings in the same order as the definition of
|
||||
the capture groups.
|
||||
- If the pattern has one or more _named_ capture groups, the result is a
|
||||
map of the captured substrings, using the capture group names as map keys.
|
||||
|
||||
It's not valid to mix both named and unnamed capture groups in the same pattern.
|
||||
|
||||
If the given pattern does not match at all, the `regex` raises an error. To
|
||||
_test_ whether a given pattern matches a string, use
|
||||
[`regexall`](./regexall.html) and test that the result has length greater than
|
||||
zero.
|
||||
|
||||
The pattern is a string containing a mixture of literal characters and special
|
||||
matching operators as described in the following table. Note that when giving a
|
||||
regular expression pattern as a literal quoted string in the Terraform
|
||||
language, the quoted string itself already uses backslash `\` as an escape
|
||||
character for the string, so any backslashes intended to be recognized as part
|
||||
of the pattern must be escaped as `\\`.
|
||||
|
||||
| Sequence | Matches |
|
||||
| -------------- | -------------------------------------------------------------------------------- |
|
||||
| `.` | Any character except newline |
|
||||
| `[xyz]` | Any character listed between the brackets (`x`, `y`, and `z` in this example) |
|
||||
| `[a-z]` | Any character between `a` and `z`, inclusive |
|
||||
| `[^xyz]` | The opposite of `[xyz]` |
|
||||
| `\d` | ASCII digits (0 through 9, inclusive) |
|
||||
| `\D` | Anything except ASCII digits |
|
||||
| `\s` | ASCII spaces (space, tab, newline, carriage return, form feed) |
|
||||
| `\S` | Anything except ASCII spaces |
|
||||
| `\w` | The same as `[0-9A-Za-z_]` |
|
||||
| `\W` | Anything except the characters matched by `\w` |
|
||||
| `[[:alnum:]]` | The same as `[0-9A-Za-z]` |
|
||||
| `[[:alpha:]]` | The same as `[A-Za-z]` |
|
||||
| `[[:ascii:]]` | Any ASCII character |
|
||||
| `[[:blank:]]` | ASCII tab or space |
|
||||
| `[[:cntrl:]]` | ASCII/Unicode control characters |
|
||||
| `[[:digit:]]` | The same as `[0-9]` |
|
||||
| `[[:graph:]]` | All "graphical" (printable) ASCII characters |
|
||||
| `[[:lower:]]` | The same as `[a-z]` |
|
||||
| `[[:print:]]` | The same as `[[:graph:]]` |
|
||||
| `[[:punct:]]` | The same as `` [!-/:-@[-`{-~] `` |
|
||||
| `[[:space:]]` | The same as `[\t\n\v\f\r ]` |
|
||||
| `[[:upper:]]` | The same as `[A-Z]` |
|
||||
| `[[:word:]]` | The same as `\w` |
|
||||
| `[[:xdigit:]]` | The same as `[0-9A-Fa-f]` |
|
||||
| `\pN` | Unicode character class by using single-letter class names ("N" in this example) |
|
||||
| `\p{Greek}` | Unicode character class by unicode name ("Greek" in this example) |
|
||||
| `\PN` | The opposite of `\pN` |
|
||||
| `\P{Greek}` | The opposite of `\p{Greek}` |
|
||||
| `xy` | `x` followed immediately by `y` |
|
||||
| `x|y` | either `x` or `y`, preferring `x` |
|
||||
| `x*` | zero or more `x`, preferring more |
|
||||
| `x*?` | zero or more `x`, preferring fewer |
|
||||
| `x+` | one or more `x`, preferring more |
|
||||
| `x+?` | one or more `x`, preferring fewer |
|
||||
| `x?` | zero or one `x`, preferring one |
|
||||
| `x??` | zero or one `x`, preferring zero |
|
||||
| `x{n,m}` | between `n` and `m` repetitions of `x`, preferring more |
|
||||
| `x{n,m}?` | between `n` and `m` repetitions of `x`, preferring fewer |
|
||||
| `x{n,}` | at least `n` repetitions of `x`, preferring more |
|
||||
| `x{n,}?` | at least `n` repetitions of `x`, preferring fewer |
|
||||
| `x{n}` | exactly `n` repetitions of `x` |
|
||||
| `(x)` | unnamed capture group for sub-pattern `x` |
|
||||
| `(?P<name>x)` | named capture group, named `name`, for sub-pattern `x` |
|
||||
| `(?:x)` | non-capturing sub-pattern `x` |
|
||||
| `\*` | Literal `*` for any punctuation character `*` |
|
||||
| `\Q...\E` | Literal `...` for any text `...` as long as it does not include literally `\E` |
|
||||
|
||||
In addition to the above matching operators that consume the characters they
|
||||
match, there are some additional operators that _only_ match, but consume
|
||||
no characters. These are "zero-width" matching operators:
|
||||
|
||||
| Sequence | Matches |
|
||||
| -------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `^` | At the beginning of the given string |
|
||||
| `$` | At the end of the given string |
|
||||
| `\A` | At the beginning of the given string |
|
||||
| `\z` | At the end of the given string |
|
||||
| `\b` | At an ASCII word boundary (transition between `\w` and either `\W`, `\A` or `\z`, or vice-versa) |
|
||||
| `\B` | Not at an ASCII word boundary |
|
||||
|
||||
Terraform uses the
|
||||
[RE2](https://github.com/google/re2/wiki/Syntax) regular expression language.
|
||||
This engine does not support all of the features found in some other regular
|
||||
expression engines; in particular, it does not support backreferences.
|
||||
|
||||
## Matching Flags
|
||||
|
||||
Some of the matching behaviors described above can be modified by setting
|
||||
matching flags, activated using either the `(?flags)` operator (to activate
|
||||
within the current sub-pattern) or the `(?flags:x)` operator (to match `x` with
|
||||
the modified flags). Each flag is a single letter, and multiple flags can be
|
||||
set at once by listing multiple letters in the `flags` position.
|
||||
The available flags are listed in the table below:
|
||||
|
||||
| Flag | Meaning |
|
||||
| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `i` | Case insensitive: a literal letter in the pattern matches both lowercase and uppercase versions of that letter |
|
||||
| `m` | The `^` and `$` operators also match the beginning and end of lines within the string, marked by newline characters; behavior of `\A` and `\z` is unchanged |
|
||||
| `s` | The `.` operator also matches newline |
|
||||
| `U` | The meaning of presence or absense `?` after a repetition operator is inverted. For example, `x*` is interpreted like `x*?` and vice-versa. |
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> regex("[a-z]+", "53453453.345345aaabbbccc23454")
|
||||
aaabbbccc
|
||||
|
||||
> regex("(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)", "2019-02-01")
|
||||
[
|
||||
"2019",
|
||||
"02",
|
||||
"01",
|
||||
]
|
||||
|
||||
> regex("^(?:(?P<scheme>[^:/?#]+):)?(?://(?P<authority>[^/?#]*))?", "https://terraform.io/docs/")
|
||||
{
|
||||
"authority" = "terraform.io"
|
||||
"scheme" = "https"
|
||||
}
|
||||
|
||||
> regex("[a-z]+", "53453453.34534523454")
|
||||
|
||||
Error: Error in function call
|
||||
|
||||
Call to function "regex" failed: pattern did not match any part of the given
|
||||
string.
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
- [`regexall`](./regexall.html) searches for potentially multiple matches of a given pattern in a string.
|
||||
- [`replace`](./replace.html) replaces a substring of a string with another string, optionally matching using the same regular expression syntax as `regex`.
|
||||
|
||||
If Terraform already has a more specialized function to parse the syntax you
|
||||
are trying to match, prefer to use that function instead. Regular expressions
|
||||
can be hard to read and can obscure your intent, making a configuration harder
|
||||
to read and understand.
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "regexall - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-regexall"
|
||||
description: |-
|
||||
The regex function applies a regular expression to a string and returns a list of all matches.
|
||||
---
|
||||
|
||||
# `regexall` Function
|
||||
|
||||
`regexall` applies a
|
||||
[regular expression](https://en.wikipedia.org/wiki/Regular_expression)
|
||||
to a string and returns a list of all matches.
|
||||
|
||||
```hcl
|
||||
regexall(pattern, string)
|
||||
```
|
||||
|
||||
`regexall` is a variant of [`regex`](./regex.html) and uses the same pattern
|
||||
syntax. For any given input to `regex`, `regexall` returns a list of whatever
|
||||
type `regex` would've returned, with one element per match. That is:
|
||||
|
||||
- If the pattern has no capture groups at all, the result is a list of
|
||||
strings.
|
||||
- If the pattern has one or more _unnamed_ capture groups, the result is a
|
||||
list of lists.
|
||||
- If the pattern has one or more _named_ capture groups, the result is a
|
||||
list of maps.
|
||||
|
||||
`regexall` can also be used to test whether a particular string matches a
|
||||
given pattern, by testing whether the length of the resulting list of matches
|
||||
is greater than zero.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> regexall("[a-z]+", "1234abcd5678efgh9")
|
||||
[
|
||||
"abcd",
|
||||
"efgh",
|
||||
]
|
||||
|
||||
> length(regexall("[a-z]+", "1234abcd5678efgh9"))
|
||||
2
|
||||
|
||||
> length(regexall("[a-z]+", "123456789")) > 0
|
||||
false
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
- [`regex`](./regex.html) searches for a single match of a given pattern, and
|
||||
returns an error if no match is found.
|
||||
|
||||
If Terraform already has a more specialized function to parse the syntax you
|
||||
are trying to match, prefer to use that function instead. Regular expressions
|
||||
can be hard to read and can obscure your intent, making a configuration harder
|
||||
to read and understand.
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "replace - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-string-replace"
|
||||
description: |-
|
||||
The replace function searches a given string for another given substring,
|
||||
and replaces all occurrences with a given replacement string.
|
||||
---
|
||||
|
||||
# `replace` Function
|
||||
|
||||
`replace` searches a given string for another given substring, and replaces
|
||||
each occurrence with a given replacement string.
|
||||
|
||||
```hcl
|
||||
replace(string, substring, replacement)
|
||||
```
|
||||
|
||||
If `substring` is wrapped in forward slashes, it is treated as a regular
|
||||
expression, using the same pattern syntax as
|
||||
[`regex`](./regex.html). If using a regular expression for the substring
|
||||
argument, the `replacement` string can incorporate captured strings from
|
||||
the input by using an `$n` sequence, where `n` is the index or name of a
|
||||
capture group.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> replace("1 + 2 + 3", "+", "-")
|
||||
1 - 2 - 3
|
||||
|
||||
> replace("hello world", "/w.*d/", "everybody")
|
||||
hello everybody
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
- [`regex`](./regex.html) searches a given string for a substring matching a
|
||||
given regular expression pattern.
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "reverse - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-reverse"
|
||||
description: |-
|
||||
The reverse function reverses a sequence.
|
||||
---
|
||||
|
||||
# `reverse` Function
|
||||
|
||||
`reverse` takes a sequence and produces a new sequence of the same length
|
||||
with all of the same elements as the given sequence but in reverse order.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> reverse([1, 2, 3])
|
||||
[
|
||||
3,
|
||||
2,
|
||||
1,
|
||||
]
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`strrev`](./strrev.html) reverses a string.
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "rsadecrypt - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-rsadecrypt"
|
||||
description: |-
|
||||
The rsadecrypt function decrypts an RSA-encrypted message.
|
||||
---
|
||||
|
||||
# `rsadecrypt` Function
|
||||
|
||||
`rsadecrypt` decrypts an RSA-encrypted ciphertext, returning the corresponding
|
||||
cleartext.
|
||||
|
||||
```hcl
|
||||
rsadecrypt(ciphertext, privatekey)
|
||||
```
|
||||
|
||||
`ciphertext` must be a base64-encoded representation of the ciphertext, using
|
||||
the PKCS #1 v1.5 padding scheme. Terraform uses the "standard" Base64 alphabet
|
||||
as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4).
|
||||
|
||||
`privatekey` must be a PEM-encoded RSA private key that is not itself
|
||||
encrypted.
|
||||
|
||||
Terraform has no corresponding function for _encrypting_ a message. Use this
|
||||
function to decrypt ciphertexts returned by remote services using a keypair
|
||||
negotiated out-of-band.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> rsadecrypt(filebase64("${path.module}/ciphertext"), file("privatekey.pem"))
|
||||
Hello, world!
|
||||
```
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "setintersection - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-setintersection"
|
||||
description: |-
|
||||
The setintersection function takes multiple sets and produces a single set
|
||||
containing only the elements that all of the given sets have in common.
|
||||
---
|
||||
|
||||
# `setintersection` Function
|
||||
|
||||
The `setintersection` function takes multiple sets and produces a single set
|
||||
containing only the elements that all of the given sets have in common.
|
||||
In other words, it computes the
|
||||
[intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)) of the sets.
|
||||
|
||||
```hcl
|
||||
setintersection(sets...)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> setintersection(["a", "b"], ["b", "c"], ["b", "d"])
|
||||
[
|
||||
"b",
|
||||
]
|
||||
```
|
||||
|
||||
The given arguments are converted to sets, so the result is also a set and
|
||||
the ordering of the given elements is not preserved.
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`contains`](./contains.html) tests whether a given list or set contains
|
||||
a given element value.
|
||||
* [`setproduct`](./setproduct.html) computes the _Cartesian product_ of multiple
|
||||
sets.
|
||||
* [`setsubtract`](./setsubtract.html) computes the _relative complement_ of two sets
|
||||
* [`setunion`](./setunion.html) computes the _union_ of
|
||||
multiple sets.
|
||||
@@ -1,225 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "setproduct - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-setproduct"
|
||||
description: |-
|
||||
The setproduct function finds all of the possible combinations of elements
|
||||
from all of the given sets by computing the cartesian product.
|
||||
---
|
||||
|
||||
# `setproduct` Function
|
||||
|
||||
The `setproduct` function finds all of the possible combinations of elements
|
||||
from all of the given sets by computing the
|
||||
[Cartesian product](https://en.wikipedia.org/wiki/Cartesian_product).
|
||||
|
||||
```hcl
|
||||
setproduct(sets...)
|
||||
```
|
||||
|
||||
This function is particularly useful for finding the exhaustive set of all
|
||||
combinations of members of multiple sets, such as per-application-per-environment
|
||||
resources.
|
||||
|
||||
```
|
||||
> setproduct(["development", "staging", "production"], ["app1", "app2"])
|
||||
[
|
||||
[
|
||||
"development",
|
||||
"app1",
|
||||
],
|
||||
[
|
||||
"development",
|
||||
"app2",
|
||||
],
|
||||
[
|
||||
"staging",
|
||||
"app1",
|
||||
],
|
||||
[
|
||||
"staging",
|
||||
"app2",
|
||||
],
|
||||
[
|
||||
"production",
|
||||
"app1",
|
||||
],
|
||||
[
|
||||
"production",
|
||||
"app2",
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
You must pass at least two arguments to this function.
|
||||
|
||||
Although defined primarily for sets, this function can also work with lists.
|
||||
If all of the given arguments are lists then the result is a list, preserving
|
||||
the ordering of the given lists. Otherwise the result is a set. In either case,
|
||||
the result's element type is a list of values corresponding to each given
|
||||
argument in turn.
|
||||
|
||||
## Examples
|
||||
|
||||
There is an example of the common usage of this function above. There are some
|
||||
other situations that are less common when hand-writing but may arise in
|
||||
reusable module situations.
|
||||
|
||||
If any of the arguments is empty then the result is always empty itself,
|
||||
similar to how multiplying any number by zero gives zero:
|
||||
|
||||
```
|
||||
> setproduct(["development", "staging", "production"], [])
|
||||
[]
|
||||
```
|
||||
|
||||
Similarly, if all of the arguments have only one element then the result has
|
||||
only one element, which is the first element of each argument:
|
||||
|
||||
```
|
||||
> setproduct(["a"], ["b"])
|
||||
[
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
Each argument must have a consistent type for all of its elements. If not,
|
||||
Terraform will attempt to convert to the most general type, or produce an
|
||||
error if such a conversion is impossible. For example, mixing both strings and
|
||||
numbers results in the numbers being converted to strings so that the result
|
||||
elements all have a consistent type:
|
||||
|
||||
```
|
||||
> setproduct(["staging", "production"], ["a", 2])
|
||||
[
|
||||
[
|
||||
"staging",
|
||||
"a",
|
||||
],
|
||||
[
|
||||
"staging",
|
||||
"2",
|
||||
],
|
||||
[
|
||||
"production",
|
||||
"a",
|
||||
],
|
||||
[
|
||||
"production",
|
||||
"2",
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
## Finding combinations for `for_each`
|
||||
|
||||
The
|
||||
[resource `for_each`](/docs/configuration/meta-arguments/for_each.html)
|
||||
and
|
||||
[`dynamic` block](/docs/configuration/expressions/dynamic-blocks.html)
|
||||
language features both require a collection value that has one element for
|
||||
each repetition.
|
||||
|
||||
Sometimes your input data comes in separate values that cannot be directly
|
||||
used in a `for_each` argument, and `setproduct` can be a useful helper function
|
||||
for the situation where you want to find all unique combinations of elements in
|
||||
a number of different collections.
|
||||
|
||||
For example, consider a module that declares variables like the following:
|
||||
|
||||
```hcl
|
||||
variable "networks" {
|
||||
type = map(object({
|
||||
base_cidr_block = string
|
||||
}))
|
||||
}
|
||||
|
||||
variable "subnets" {
|
||||
type = map(object({
|
||||
number = number
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
If the goal is to create each of the defined subnets per each of the defined
|
||||
networks, creating the top-level networks can directly use `var.networks`
|
||||
because it's already in a form where the resulting instances match one-to-one
|
||||
with map elements:
|
||||
|
||||
```hcl
|
||||
resource "aws_vpc" "example" {
|
||||
for_each = var.networks
|
||||
|
||||
cidr_block = each.value.base_cidr_block
|
||||
}
|
||||
```
|
||||
|
||||
However, in order to declare all of the _subnets_ with a single `resource`
|
||||
block, we must first produce a collection whose elements represent all of
|
||||
the combinations of networks and subnets, so that each element itself
|
||||
represents a subnet:
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
# setproduct works with sets and lists, but our variables are both maps
|
||||
# so we'll need to convert them first.
|
||||
networks = [
|
||||
for key, network in var.networks : {
|
||||
key = key
|
||||
cidr_block = network.cidr_block
|
||||
}
|
||||
]
|
||||
subnets = [
|
||||
for key, subnet in var.subnets : {
|
||||
key = key
|
||||
number = subnet.number
|
||||
}
|
||||
]
|
||||
|
||||
network_subnets = [
|
||||
# in pair, element zero is a network and element one is a subnet,
|
||||
# in all unique combinations.
|
||||
for pair in setproduct(local.networks, local.subnets) : {
|
||||
network_key = pair[0].key
|
||||
subnet_key = pair[1].key
|
||||
network_id = aws_vpc.example[pair[0].key].id
|
||||
|
||||
# The cidr_block is derived from the corresponding network. See the
|
||||
# cidrsubnet function for more information on how this calculation works.
|
||||
cidr_block = cidrsubnet(pair[0].cidr_block, 4, pair[1].number)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource "aws_subnet" "example" {
|
||||
# local.network_subnets is a list, so we must now project it into a map
|
||||
# where each key is unique. We'll combine the network and subnet keys to
|
||||
# produce a single unique key per instance.
|
||||
for_each = {
|
||||
for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
|
||||
}
|
||||
|
||||
vpc_id = each.value.network_id
|
||||
availability_zone = each.value.subnet_key
|
||||
cidr_block = each.value.cidr_block
|
||||
}
|
||||
```
|
||||
|
||||
The above results in one subnet instance per combination of network and subnet
|
||||
elements in the input variables.
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`contains`](./contains.html) tests whether a given list or set contains
|
||||
a given element value.
|
||||
* [`flatten`](./flatten.html) is useful for flattening hierarchical data
|
||||
into a single list, for situations where the relationships between two
|
||||
object types are defined explicitly.
|
||||
* [`setintersection`](./setintersection.html) computes the _intersection_ of
|
||||
multiple sets.
|
||||
* [`setsubtract`](./setsubtract.html) computes the _relative complement_ of two sets
|
||||
* [`setunion`](./setunion.html) computes the _union_ of multiple
|
||||
sets.
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "setsubtract - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-setsubtract"
|
||||
description: |-
|
||||
The setsubtract function returns a new set containing the elements
|
||||
from the first set that are not present in the second set
|
||||
---
|
||||
|
||||
# `setsubtract` Function
|
||||
|
||||
The `setsubtract` function returns a new set containing the elements from the first set that are not present in the second set. In other words, it computes the
|
||||
[relative complement](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement) of the first set in the second set.
|
||||
|
||||
```hcl
|
||||
setsubtract(a, b)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> setsubtract(["a", "b", "c"], ["a", "c"])
|
||||
[
|
||||
"b",
|
||||
]
|
||||
```
|
||||
|
||||
### Set Difference (Symmetric Difference)
|
||||
|
||||
```
|
||||
> setunion(setsubtract(["a", "b", "c"], ["a", "c", "d"]), setsubtract(["a", "c", "d"], ["a", "b", "c"]))
|
||||
[
|
||||
"b",
|
||||
"d",
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`setintersection`](./setintersection.html) computes the _intersection_ of multiple sets
|
||||
* [`setproduct`](./setproduct.html) computes the _Cartesian product_ of multiple
|
||||
sets.
|
||||
* [`setunion`](./setunion.html) computes the _union_ of
|
||||
multiple sets.
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "setunion - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-collection-setunion"
|
||||
description: |-
|
||||
The setunion function takes multiple sets and produces a single set
|
||||
containing the elements from all of the given sets.
|
||||
---
|
||||
|
||||
# `setunion` Function
|
||||
|
||||
The `setunion` function takes multiple sets and produces a single set
|
||||
containing the elements from all of the given sets. In other words, it
|
||||
computes the [union](https://en.wikipedia.org/wiki/Union_(set_theory)) of
|
||||
the sets.
|
||||
|
||||
```hcl
|
||||
setunion(sets...)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> setunion(["a", "b"], ["b", "c"], ["d"])
|
||||
[
|
||||
"d",
|
||||
"b",
|
||||
"c",
|
||||
"a",
|
||||
]
|
||||
```
|
||||
|
||||
The given arguments are converted to sets, so the result is also a set and
|
||||
the ordering of the given elements is not preserved.
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`contains`](./contains.html) tests whether a given list or set contains
|
||||
a given element value.
|
||||
* [`setintersection`](./setintersection.html) computes the _intersection_ of
|
||||
multiple sets.
|
||||
* [`setproduct`](./setproduct.html) computes the _Cartesian product_ of multiple
|
||||
sets.
|
||||
* [`setsubtract`](./setsubtract.html) computes the _relative complement_ of two sets
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "sha1 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-sha1"
|
||||
description: |-
|
||||
The sha1 function computes the SHA1 hash of a given string and encodes it
|
||||
with hexadecimal digits.
|
||||
---
|
||||
|
||||
# `sha1` Function
|
||||
|
||||
`sha1` computes the SHA1 hash of a given string and encodes it with
|
||||
hexadecimal digits.
|
||||
|
||||
The given string is first encoded as UTF-8 and then the SHA1 algorithm is applied
|
||||
as defined in [RFC 3174](https://tools.ietf.org/html/rfc3174). The raw hash is
|
||||
then encoded to lowercase hexadecimal digits before returning.
|
||||
|
||||
Collision attacks have been successfully performed against this hashing
|
||||
function. Before using this function for anything security-sensitive, review
|
||||
relevant literature to understand the security implications.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> sha1("hello world")
|
||||
2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`filesha1`](./filesha1.html) calculates the same hash from
|
||||
the contents of a file rather than from a string value.
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
layout: "language"
|
||||
page_title: "sha256 - Functions - Configuration Language"
|
||||
sidebar_current: "docs-funcs-crypto-sha256"
|
||||
description: |-
|
||||
The sha256 function computes the SHA256 hash of a given string and encodes it
|
||||
with hexadecimal digits.
|
||||
---
|
||||
|
||||
# `sha256` Function
|
||||
|
||||
`sha256` computes the SHA256 hash of a given string and encodes it with
|
||||
hexadecimal digits.
|
||||
|
||||
The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
|
||||
as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is
|
||||
then encoded to lowercase hexadecimal digits before returning.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> sha256("hello world")
|
||||
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
||||
```
|
||||
|
||||
## Related Functions
|
||||
|
||||
|
||||
## Related Functions
|
||||
|
||||
* [`filesha256`](./filesha256.html) calculates the same hash from
|
||||
the contents of a file rather than from a string value.
|
||||
* [`base64sha256`](./base64sha256.html) calculates the same hash but returns
|
||||
the result in a more-compact Base64 encoding.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user