Hi, in this mini series I’m adding an overview of the exam content for the terraform associate 004 exam found here: https://developer.hashicorp.com/terraform/tutorials/certification-004/associate-review-004. Hope this helps you on your quest to pass the exam π look for more sections (1-8) under Terraform in the navigation bar.
Section 4 β Terraform Configuration
4a β Resources vs Data blocks
These are the two most fundamental building blocks. Know the difference cold.
Resource block β creates, updates, or destroys real infrastructure
resource "aws_instance" "my_server" {
ami = "ami-12345"
instance_type = "t3.micro"
}
Format is always resource "provider_type" "local_name". The local name is just what you call it in your own config.
Data block β reads existing infrastructure that Terraform didn’t create. Read-only, never makes changes.
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
}
Exam point β if the question says “look up an existing thing” that’s a data source. If it says “create a thing” that’s a resource.
4b β Cross-resource references
Resources can reference each other’s attributes. This is how you connect things together.
resource "aws_instance" "server" {
subnet_id = aws_subnet.main.id
}
Format is resource_type.local_name.attribute. Terraform uses these references to automatically figure out the order things need to be created in β if resource B references resource A, Terraform creates A first.
4c β Variables and outputs
Input variables β make your config reusable by accepting values from outside
variable "region" {
type = string
description = "AWS region to deploy to"
default = "eu-west-1"
}
You reference it with var.region. You can pass values in via a terraform.tfvars file, environment variables (TF_VAR_region), or the command line (-var="region=us-east-1").
Output values β expose values after apply, useful for passing data between modules or just seeing results
output "server_ip" {
value = aws_instance.server.public_ip
}
Key exam point β the order of precedence for variable values (highest to lowest): command line -var flag β *.auto.tfvars file β terraform.tfvars β environment variables β default value.
4d β Complex types
Variables aren’t just strings. Know these three:
- list β ordered collection:
["a", "b", "c"] - map β key-value pairs:
{ env = "prod", region = "eu-west-1" } - object β structured type with named attributes of different types
variable "tags" {
type = map(string)
default = {
environment = "production"
owner = "me"
}
}
4e β Expressions and functions
Terraform has built-in functions for transforming values. The ones that come up most in the exam:
length(list)β count items in a listtoset(list)β convert list to set (removes duplicates)lookup(map, key, default)β get a value from a mapjoin(separator, list)β join a list into a stringfile(path)β read a file’s contents
Also know conditional expressions β they work like a ternary:
instance_type = var.environment == "prod" ? "t3.large" : "t3.micro"
And for expressions β loop over a list or map:
output "instance_ids" {
value = [for i in aws_instance.servers : i.id]
}
4f β Resource dependencies
Terraform builds a dependency graph automatically using references. But sometimes you need to force an order when there’s no direct reference β use depends_on:
resource "aws_instance" "server" {
depends_on = [aws_iam_role_policy.my_policy]
}
Exam point β use depends_on sparingly and only when there’s a hidden dependency Terraform can’t detect automatically.
4g β Validation and custom conditions
You can add validation rules to variables to catch bad inputs early:
variable "environment" {
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
Also know check blocks β they validate infrastructure state after apply without blocking the deployment. Think of them as health checks for your config.
4h β Sensitive data and secrets
Key rules for the exam:
- Mark sensitive variables with
sensitive = trueβ Terraform redacts them from output - Sensitive values still end up in state β which is why state files must be protected
- Use Vault provider to inject secrets directly from HashiCorp Vault rather than hardcoding them
- Never put secrets in
.tfvarsfiles that get committed to Git
variable "db_password" {
type = string
sensitive = true
}
The mental model for Section 4
Think of a Terraform config like a recipe:
- Variables are the ingredients you can swap out
- Resources are the steps that create real things
- Data sources are steps that look things up
- Outputs are what you get at the end
- Functions and expressions are how you transform and connect everything
