360 lines
16 KiB
Markdown
360 lines
16 KiB
Markdown
---
|
|
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/language/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/language/values/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/language/values/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](/docs/language/modules/syntax.html).
|
|
|
|
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](/docs/language/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/language/data-sources/index.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/language/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/language/meta-arguments/count.html).
|
|
- `each.key` / `each.value`, in resources that use
|
|
[the `for_each` meta-argument](/docs/language/meta-arguments/for_each.html).
|
|
- `self`, in [provisioner](/docs/language/resources/provisioners/syntax.html) and
|
|
[connection](/docs/language/resources/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/language/values/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/language/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/language/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/language/values/variables.html)
|
|
and
|
|
[output values](/docs/language/values/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/language/settings/index.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.
|