Terraform Associate
Deep Dive
Resources are Terraform's central element: they define the infrastructure you want to manage. Data sources let you read existing infrastructure. Understanding dependencies and the lifecycle block is key for the exam.
Contents
The resource block has two mandatory labels: the type (determined by the provider) and the local name (identifier within Terraform).
# resource "<TYPE>" "<LOCAL_NAME>" { ... }
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server"
}
}
# Resource address: aws_instance.web
# Attribute: aws_instance.web.id
# Attribute: aws_instance.web.public_ip
# Root module: aws_instance.web
# Child module: module.app.aws_instance.web
# Nested module: module.app.module.compute.aws_instance.web| Concept | Description | Example |
|---|---|---|
| Type | Defines which API is called (determined by the provider) | aws_instance, azurerm_virtual_machine |
| Local name | Unique identifier within the module (not in the cloud) | web, database, main — letters, numbers, and _ only |
| Address | Type + name = full resource address | aws_instance.web |
| Arguments | Parameters that configure the resource (defined by the provider) | ami, instance_type, tags |
| Attributes | Values computed after creation (exported values) | .id, .arn, .public_ip |
Data sources let you query information about existing infrastructure (created by another module, another tool, or manually) without Terraform managing it.
# data "<TYPE>" "<LOCAL_NAME>" { ... }
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"]
}
}
# Use the data source result
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id # data.<type>.<name>.<attr>
instance_type = "t3.micro"
}
# Other examples of data sources
data "aws_vpc" "existing" {
id = "vpc-12345678" # look up by exact ID
}
data "aws_availability_zones" "available" {
state = "available" # all available AZs
}💡 Data sources are read during terraform plan
Data sources are queried during terraform plan (or at the start of apply). If the queried infrastructure doesn't exist, the plan will fail with an error. Unlike resources, Terraform creates or destroys nothing when using data sources.
| Characteristic | resource {} | data {} |
|---|---|---|
| Creates infra? | ✅ Yes — Terraform creates/manages the resource | ❌ No — only reads existing infra |
| Appears in state? | ✅ Yes — tracks its state in tfstate | ❌ No — does not save state (re-reads every plan) |
| Can Terraform destroy it? | ✅ Yes — with destroy | ❌ No — never destroys it |
| Reference prefix | type.name.attr (no prefix) | data.type.name.attr |
| When to use it | When Terraform must own the resource | When the infra already exists and you only need its attributes |
| Syntax | resource "aws_vpc" "main" {} | data "aws_vpc" "existing" {} |
Terraform automatically builds a dependency graph based on the references between resources. You can also declare explicit dependencies with depends_on.
# IMPLICIT DEPENDENCY (recommended)
# Terraform detects that aws_subnet.main depends on aws_vpc.main
# because it references its .id attribute
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id # <-- creates an implicit dependency
cidr_block = "10.0.1.0/24"
}
# EXPLICIT DEPENDENCY (use only when there is no direct reference)
# For example: the app depends on the DB existing, but doesn't reference any attr
resource "aws_db_instance" "main" {
# ... DB configuration
}
resource "aws_instance" "app" {
ami = "ami-abc123"
instance_type = "t3.micro"
depends_on = [aws_db_instance.main] # wait for the DB to be ready
}💡 When to use depends_on
Use depends_on only when there is a real dependency that Terraform cannot detect automatically (for example, when a resource needs another one to be ready but doesn't use any of its attributes). Unnecessary use of depends_on can slow down the plan by adding dependencies that Terraform could otherwise parallelize.
The lifecycle block inside a resource controls how Terraform manages the resource's lifecycle: creation, update, and destruction.
resource "aws_db_instance" "prod" {
identifier = "prod-db"
# ... other arguments
lifecycle {
# Prevents Terraform from destroying this resource (errors if it tries)
prevent_destroy = true
# Creates the new resource BEFORE destroying the old one (zero downtime)
create_before_destroy = true
# Ignores changes to these arguments (no diff shown in plan)
ignore_changes = [
engine_version, # the DB can self-update without Terraform reverting it
tags["LastModified"],
]
# Terraform destroys and recreates the resource if this other resource changes
replace_triggered_by = [
aws_launch_template.app.id,
]
}
}| Argument | Type | Effect |
|---|---|---|
| prevent_destroy | bool | If true, any plan that destroys the resource will produce an error. Protects critical resources. |
| create_before_destroy | bool | If true, creates the replacement before destroying the current one. Requires the provider to support it. |
| ignore_changes | list(attr) | Ignores changes on the listed attributes. Use "all" to ignore everything (extreme case). |
| replace_triggered_by | list(ref) | Forces replacement of this resource when the referenced resources/attributes change. |
⚠️ prevent_destroy does not protect against terraform destroy
prevent_destroy = true prevents Terraform from destroying the resource as part of a configuration change (e.g.: renaming a DB that requires replacement). However, if someone removes the resource block from the code and runs apply, the resource will still be destroyed because the prevent_destroy rule no longer exists.
Did you get this topic?
Test what you just learned
A team has a production database defined with resource 'aws_db_instance' 'prod'. They want Terraform to NOT revert changes if someone changes the engine_version parameter (the DB manages its own engine updates). Which lifecycle configuration is correct?
Put what you learned to the test with original Terraform Associate exam questions.
Start Terraform Associate mock examUnlimited mock exams with the Pro plan
Log in to track your progress.