| --- |
| page_title: References to Values - Configuration Language |
| description: >- |
| Reference values in configurations, including resources, input variables, |
| local and block-local values, module outputs, data sources, and workspace |
| data. |
| --- |
| |
| # 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. |
| |
| 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](/language/expressions/types#indices-and-attributes) for elements of object values, they are not |
| implemented as real objects. This means you must use them exactly as written: |
| you cannot use square-bracket notation to replace the dot-separated paths, and |
| you cannot iterate over the "parent object" of a named entity; for example, you |
| cannot use `aws_instance` in a `for` expression to iterate over every AWS |
| instance resource. |
| |
| ### Resources |
| |
| `<RESOURCE TYPE>.<NAME>` represents a [managed resource](/language/resources) 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](/language/expressions/types#indices-and-attributes). |
| * If the resource has the `count` argument set, the reference's value is a |
| _list_ of objects representing its instances. |
| * If the resource has the `for_each` argument set, the reference's value is a |
| _map_ of objects representing its instances. |
| |
| Any named value that does not match another pattern listed below |
| will be interpreted by Terraform as a reference to a managed resource. |
| |
| 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](/language/values/variables) of the given name. |
| |
| If the variable has a type constraint (`type` argument) as part of its |
| declaration, Terraform will automatically convert the caller's given value |
| 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](/language/values/locals) of the given name. |
| |
| Local values can refer to other local values, even within the same `locals` |
| block, as long as you don't introduce circular dependencies. |
| |
| ### Child Module Outputs |
| |
| `module.<MODULE NAME>` is an value representing the results of |
| [a `module` block](/language/modules/syntax). |
| |
| If the corresponding `module` block does not have either `count` nor `for_each` |
| set then the value will be an object with one attribute for each output value |
| defined in the child module. To access one of the module's |
| [output values](/language/values/outputs), use `module.<MODULE NAME>.<OUTPUT NAME>`. |
| |
| If the corresponding `module` uses `for_each` then the value will be a map |
| of objects whose keys correspond with the keys in the `for_each` expression, |
| 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](/language/data-sources) of the given data |
| source type and name. If the resource has the `count` argument set, the value |
| is a list of objects representing its instances. If the resource has the `for_each` |
| argument set, the value is a map of objects representing its instances. |
| |
| 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 |
| |
| The following values are available: |
| |
| - `path.module` is the filesystem path of the module where the expression is placed. |
| We do not recommend using `path.module` in write operations because it can produce |
| different behavior depending on whether you use remote or local module sources. |
| Multiple invocations of local modules use the same source directory, overwriting |
| the data in `path.module` during each call. This can lead to race conditions and |
| unexpected results. |
| - `path.root` is the filesystem path of the root module of the configuration. |
| - `path.cwd` is the filesystem path of the original working directory from where you |
| ran Terraform before applying any `-chdir` argument. This path is an absolute path |
| that includes details about the filesystem structure. It is also useful in some |
| advanced cases where Terraform is run from a directory other than the root module |
| directory. We recommend using `path.root` or `path.module` over `path.cwd` where |
| possible. |
| - `terraform.workspace` is the name of the currently selected |
| [workspace](/language/state/workspaces). |
| |
| Use the values in this section carefully, because they include information |
| about the context in which a configuration is being applied and so may |
| 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](/language/meta-arguments/count). |
| * `each.key` / `each.value`, in resources that use |
| [the `for_each` meta-argument](/language/meta-arguments/for_each). |
| * `self`, in [provisioner](/language/resources/provisioners/syntax) and |
| [connection](/language/resources/provisioners/connection) blocks. |
| |
| -> **Note:** Local names are often referred to as _variables_ or |
| _temporary variables_ in their documentation. These are not [input |
| variables](/language/values/variables); they are just arbitrary names |
| that temporarily represent a value. |
| |
| The names in this section relate to top-level configuration blocks only. |
| If you use [`dynamic` blocks](/language/expressions/dynamic-blocks) to dynamically generate |
| resource-type-specific _nested_ blocks within `resource` and `data` blocks then |
| you'll refer to the key and value of each element differently. See the |
| `dynamic` blocks documentation for details. |
| |
| ## 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](/language/expressions/splat). For example, to obtain a list of |
| all of the `device_name` values, use |
| `aws_instance.example.ebs_block_device[*].device_name`. |
| * The nested blocks in this particular resource type do not have any exported |
| 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](/language/expressions/for): |
| `{for k, device in aws_instance.example.device : k => device.size}`. |
| |
| When a resource has the |
| [`count`](/language/meta-arguments/count) |
| argument set, the resource itself becomes a _list_ of instance objects rather than |
| a single object. In that case, access the attributes of the instances using |
| either [splat expressions](/language/expressions/splat) or index syntax: |
| |
| * `aws_instance.example[*].id` returns a list of all of the ids of each of the |
| instances. |
| * `aws_instance.example[0].id` returns just the id of the first instance. |
| |
| When a resource has the |
| [`for_each`](/language/meta-arguments/for_each) |
| argument set, the resource itself becomes a _map_ of instance objects rather than |
| a single object, and attributes of instances must be specified by key, or can |
| be accessed using a [`for` expression](/language/expressions/for). |
| |
| * `aws_instance.example["a"].id` returns the id of the "a"-keyed resource. |
| * `[for value in aws_instance.example: value.id]` returns a list of all of the ids |
| 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` |
| |
| ### 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 value)` instead of the actual value when rendering |
| a plan involving that attribute. |
| |
| A provider attribute marked as sensitive behaves similarly to an |
| [an input variable declared as sensitive](/language/values/variables#suppressing-values-in-cli-output), |
| where Terraform will hide the value in the plan and apply messages and will |
| also hide any other values you derive from it as sensitive. |
| However, there are some limitations to that behavior as described in |
| [Cases where Terraform may disclose a sensitive variable](/language/values/variables#cases-where-terraform-may-disclose-a-sensitive-variable). |
| |
| If you use a sensitive value from a resource attribute as part of an |
| [output value](/language/values/outputs) then Terraform will require |
| you to also mark the output value itself as sensitive, to confirm that you |
| intended to export it. |
| |
| Terraform will still record sensitive values in the [state](/language/state), |
| and so anyone who can access the state data will have access to the sensitive |
| values in cleartext. For more information, see |
| [_Sensitive Data in State_](/language/state/sensitive-data). |
| |
| -> **Note:** Treating values derived from a sensitive resource attribute as |
| sensitive themselves was introduced in Terraform v0.15. Earlier versions of |
| Terraform will obscure the direct value of a sensitive resource attribute, |
| but will _not_ automatically obscure other values derived from sensitive |
| resource attributes. |
| |
| ### 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. |
| |
| Terraform uses special unknown value placeholders for information that it |
| cannot predict during the plan phase. The Terraform language automatically |
| handles unknown values in expressions. For example, adding a known value to an |
| unknown value automatically produces an unknown value as a result. |
| |
| 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 `(known after apply)`. |