Skip to content

2.07 - Terraform Resource Attributes & Reference Expressions

Overview

Resource attributes allow you to link resources together by using the output of one resource as the input of another, enabling Terraform to model real infrastructure dependencies.

Abstract

In real-world infrastructure, resources rarely exist in isolation. Terraform's reference expressions let you pass attributes from one resource directly into another, creating implicit dependencies and dynamic configurations that reflect actual infrastructure relationships.


Key Concepts

Concept Description
Resource attribute A value exported by a resource after it is created (e.g. id, arn, ip)
Attribute reference An expression that reads an attribute from another resource
Interpolation sequence ${...} syntax used to embed an expression inside a string
Implicit dependency Terraform infers creation order automatically from reference expressions
Explicit dependency Dependency declared manually using depends_on when no reference expression is used
depends_on Meta-argument that accepts a list of resources the current resource must wait for
id attribute Most resources expose an id attribute representing their unique identifier

Reference Expression Syntax

To use an attribute from another resource:

<resource_type>.<resource_name>.<attribute>

Inside a string argument, wrap it in an interpolation sequence:

"My favorite pet is ${random_pet.my-pet.id}"
Part Example
Resource type random_pet
Resource name my-pet
Attribute id

Example Configuration

Without reference (no dependency)

resource "local_file" "pet" {
  filename = var.filename
  content  = "My favorite pet is Mr.Cat"
}

resource "random_pet" "my-pet" {
  prefix    = var.prefix
  separator = var.separator
  length    = var.length
}

The file content is hardcoded — no relationship between the two resources.

With reference expression (linked resources)

resource "local_file" "pet" {
  filename = var.filename
  content  = "My favorite pet is ${random_pet.my-pet.id}"
}

resource "random_pet" "my-pet" {
  prefix    = var.prefix
  separator = var.separator
  length    = var.length
}

Now the file content is dynamically populated with the pet name generated by random_pet.my-pet.


How It Works at Apply Time

When terraform apply runs:

  1. random_pet.my-pet is created first (Terraform infers the dependency).
  2. The id attribute — the generated pet name (e.g. Mr.Bull) — becomes available.
  3. local_file.pet is created with content = "My favorite pet is Mr.Bull".
random_pet.my-pet: Creating...
local_file.pet: Creating...
random_pet.my-pet: Creation complete after 0s [id=Mr.bull]
local_file.pet: Creation complete after 0s
[id=059090e865809f9b6debfda7aebf48fdce2220a6]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Resource Dependencies

Terraform supports two types of resource dependency.

Implicit Dependency

Created automatically when one resource references an attribute of another via a reference expression. Terraform builds the dependency graph from these references and determines the correct creation and destruction order without any extra configuration.

resource "local_file" "pet" {
  filename = var.filename
  content  = "My favorite pet is ${random_pet.my-pet.id}"  # reference creates implicit dependency
}

resource "random_pet" "my-pet" {
  prefix    = var.prefix
  separator = var.separator
  length    = var.length
}

Creation order: random_pet.my-petlocal_file.pet
Destruction order: local_file.petrandom_pet.my-pet

Explicit Dependency (depends_on)

Used when a resource relies on another indirectly — for example, a script that reads a file created by another resource — but no reference expression is present. Use depends_on to manually declare the relationship:

resource "local_file" "pet" {
  filename  = var.filename
  content   = "My favorite pet is Mr.Cat"

  depends_on = [
    random_pet.my-pet
  ]
}

resource "random_pet" "my-pet" {
  prefix    = var.prefix
  separator = var.separator
  length    = var.length
}

depends_on accepts a list of resource references and ensures the listed resources are fully created before this resource is provisioned.

Note

Prefer implicit dependencies wherever possible — they're self-documenting and easier to maintain. Use depends_on only when the dependency cannot be expressed through a reference expression.


Resource Replacement on Attribute Change

If the referenced attribute changes (e.g. random_pet generates a new name), Terraform will destroy and recreate any dependent resources whose content no longer matches:

# local_file.pet must be replaced
-/+ resource "local_file" "pet" {
    ~ content = "My favorite pet is Mrs.Cat!" ->
      "My favorite pet is Mr.bull"  # forces replacement
      directory_permission = "0777"
      file_permission      = "0777"
      filename             = "/roots/pets.txt"
    ~ id                   = "98af5244e23508cffd4a0c3c46546821c4ccbbd0" -> (known after apply)
    }

local_file.pet: Destroying...
local_file.pet: Destruction complete after 0s
local_file.pet: Creating...
local_file.pet: Creation complete after 0s
[id=e56101d304de7cf1b1001102923c6bdeaa60c523]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Note

When a referenced attribute changes, Terraform marks the dependent resource for replacement (-/+), destroys the old version, and creates a new one. This is expected behaviour — not an error.


Finding Available Attributes

Every resource in the Terraform Registry documents its exported attributes under the Attribute Reference section.

For random_pet:

Attribute Type Description
id string The randomly generated pet name

Always check the registry docs for the resource you're using to see which attributes are available for reference.


Best Practices

Best Practices

  • Use reference expressions instead of hardcoded values to keep configurations dynamic and environment-agnostic.
  • Prefer implicit dependencies (via references) over explicit depends_on — they're self-documenting and easier to maintain.
  • Use depends_on only when a resource has an indirect dependency that cannot be expressed through a reference expression.
  • Use interpolation ${...} only inside strings; for non-string arguments, reference expressions can be used directly (e.g. filename = local_file.pet.id).
  • Check the Attribute Reference section of provider docs to know exactly which attributes are available post-apply.

Security Best Practices

Security

  • Avoid referencing sensitive attributes (e.g. passwords, tokens) in content fields of files or outputs — they may be stored in state in plaintext.
  • Mark sensitive outputs and variables with sensitive = true to suppress them in CLI output.
  • Never write secrets to local_file resources — use a secrets manager instead.

Do and Don't

✅ Do ❌ Don't
Use ${resource_type.name.attribute} to link resources Hardcode values that another resource already generates
Check the Attribute Reference section in Terraform Registry docs Guess which attributes are available — verify in the docs
Let Terraform infer order via implicit dependencies Use depends_on when a reference expression already models the relationship
Use depends_on for indirect dependencies with no reference expression Omit depends_on when two resources are related but share no direct attribute reference
Expect -/+ replacement when a referenced value changes Assume dependent resources update in-place

Common Mistakes

Common Mistakes

  • Forgetting the ${} interpolation wrapper when embedding a reference inside a string argument.
  • Referencing an attribute that doesn't exist on the resource type — always verify in the registry docs.
  • Assuming resources are created in the order they appear in the file — Terraform determines order from the dependency graph, not file position.
  • Not accounting for resource replacement when an upstream attribute changes — plan output will show -/+.

Quick Recap

  • Resource attributes are values exported by a resource after creation (e.g. id).
  • Reference syntax: resource_type.resource_name.attribute
  • Use ${...} to embed references inside string values (interpolation).
  • References create implicit dependencies — Terraform builds the correct creation order automatically.
  • Destruction always happens in reverse dependency order.
  • Use depends_on for explicit dependencies when no reference expression exists.
  • If a referenced attribute changes, Terraform destroys and recreates dependent resources.
  • Always check the Attribute Reference section in Terraform Registry documentation.

Interview / Revision Notes

  • Q: What is the syntax for a Terraform reference expression?
    A: resource_type.resource_name.attribute — e.g. random_pet.my-pet.id

  • Q: What is an interpolation sequence?
    A: ${...} — evaluates an expression and inserts the result as a string inside a string argument.

  • Q: How does Terraform know which resource to create first when one references another?
    A: It builds an implicit dependency graph from reference expressions and resolves the correct order automatically.

  • Q: What is the difference between implicit and explicit dependency?
    A: Implicit dependency is inferred automatically from reference expressions. Explicit dependency is declared manually using depends_on when no reference expression is present.

  • Q: When should you use depends_on?
    A: Only when a resource has an indirect dependency on another — e.g. a script that uses an output file — but no attribute reference exists to model that relationship.

  • Q: In what order does Terraform destroy resources with dependencies?
    A: Reverse dependency order — dependents are destroyed before the resources they depend on.

  • Q: Where do you find which attributes a resource exports?
    A: The Attribute Reference section of the resource's page in registry.terraform.io.

  • Q: What happens to a dependent resource when the attribute it references changes?
    A: It is marked for replacement (-/+) — destroyed and recreated with the updated value.