HashiCorp Certified: Terraform Associate (003) — Exam Guide (2025 Edition)
Introduction
Terraform is a powerful Infrastructure as Code (IaC) tool that allows you to define and manage infrastructure using a declarative configuration language. Whether you are preparing for the Terraform Associate Certification or want to master Terraform, this guide provides a comprehensive cheat sheet covering key concepts, commands, best practices, and exam tips.
Terraform Associate Certification Exam Tips
📌 Exam Duration: 60 minutes
📌 Number of Questions: ~57 multiple-choice questions
📌 Passing Score: ~70% (HashiCorp does not publish passing scores; however, in practice many candidates report that **scores ≥ 70%** typically result in a pass.)
📌 Key Topics Covered:
- Terraform Basics (Commands, HCL Syntax, Providers)
- State Management (Local vs. Remote, Locking, Backends)
- HCP Terraform (formerly Terraform Cloud) & Workspaces
- Modules & Reusability
- Provisioners (Local, Remote, File)
- Security Best Practices
- Lifecycle Rules & Meta-Arguments
- Interpolation & Functions
- Terraform Import & Debugging
- Managing Infrastructure as Code (IaC)
Study Resources (official first)
- Exam Content List — Terraform Associate (003)
- Terraform Associate 003 Study GuideTerraform Tutorials
- Sample Questions- Terraform Associate(003)
Quick starts to focus on:
Courses & Practice (use what fits your style/budget):
- HashiCorp Terraform Associate Certification Course (003): https://www.youtube.com/watch?v=SPcwo0Gq9T8&t=13045s
- Terraform Hands-On Labs: https://www.udemy.com/course/terraform-hands-on-labs/
- Terraform Beginner to Advanced: https://www.udemy.com/course/terraform-beginner-to-advanced/
- Terraform Associate Practice Exam: https://www.udemy.com/course/terraform-associate-practice-exam/
- HashiCorp Certified Terraform Associate: https://www.whizlabs.com/learn/course/hashicorp-certified-terraform-associate/337
Community practice (optional)
- https://www.examtopics.com/exams/hashicorp/terraform-associate/view/ (Unofficial; use for recall/timing only — items may be outdated or mislabeled.)
Terraform Architecture
Based on the image, Terraform Architecture consists of the following key components:
1. Terraform Core
- The central engine that takes infrastructure definitions written in HCL (HashiCorp Configuration Language) and processes them.
- It reads the Terraform manifest files (
.tf), executes plan and apply commands, and manages infrastructure state.
2. Terraform State File (terraform.tfstate)
- Stores the current state of infrastructure.
- Helps Terraform determine what changes need to be made.
- Essential for tracking resources across multiple Terraform runs.
3. Providers
- Providers act as an interface between Terraform and different cloud platforms.
- Examples: AWS, Azure, GCP, VMware, OpenShift.
- They enable Terraform to create, modify, and manage resources in these cloud platforms.
4. Provisioners
- Provisioners execute scripts or commands on a resource after its creation.
- Two common types:
- Remote-exec: Runs commands on remote machines via SSH.
- Local-exec: Executes scripts on the local machine.
5. Plugins
- Terraform loads plugins to communicate with providers and execute provisioning logic.
- Each provider and provisioner has its own plugin.
6. Cloud Service Providers & Platforms
- Cloud providers: AWS, Azure, Google Cloud, VMware
- Platforms / orchestrators: Kubernetes, OpenShift
- Terraform applies configurations to these platforms using API calls.
Terraform Installation
Windows
- Download the binary from Terraform Downloads.
- Unzip and move it to a directory in
PATH. - Verify installation:
terraform version
Linux (Ubuntu/Debian) via Package Manager
# Ubuntu / Debian (recommended)
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(. /etc/os-release && echo $VERSION_CODENAME) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt-get update && sudo apt-get install -y terraform
terraform versionmacOS (Homebrew)
brew tap hashicorp/tap
brew install hashicorp/tap/terraformTerraform Workflow
- Write Configuration — Define infrastructure using HCL (HashiCorp Configuration Language).
- Initialize —
terraform init - Plan —
terraform plan - Apply —
terraform apply - Destroy —
terraform destroy
terraform init
Initialize a Terraform working directory. Downloads provider plugins and prepares the backend.
terraform init
terraform init -upgrade # Upgrade providers to latest version
terraform init -migrate-state # Migrate state to new backend
terraform init -reconfigure # Reconfigure backend ignoring existing configurationterraform validate
Check Terraform configuration files for syntax errors and internal consistency.
terraform validate
terraform validate -json # Output in JSON formatterraform plan
Preview the changes Terraform will make to the infrastructure without applying them.
terraform plan
terraform plan -out=tfplan # Save plan to a file
terraform plan -var="instance_type=t2.micro"
terraform plan -target=aws_instance.example # Plan for specific resource only
terraform plan -refresh-only # Only refresh state, don't plan changesterraform apply
Apply the changes and provision/modify the infrastructure.
terraform apply
terraform apply tfplan # Apply a saved plan
terraform apply -auto-approve # Skip interactive approval
terraform apply -replace="aws_instance.example" # Force replace a specific resource
terraform apply -target=aws_instance.example # Apply only specific resource
terraform apply -refresh-only # Only update state to match real-worldterraform destroy
Destroy all infrastructure managed by Terraform.
terraform destroy
terraform destroy -auto-approve
terraform destroy -target=aws_instance.example # Destroy only specific resource💡 Exam Tip: Always run terraform plan before terraform apply to preview changes and avoid unexpected results.
Terraform File Structure
- Main Configuration:
main.tf - Variables:
variables.tf - Outputs:
outputs.tf - State File:
terraform.tfstate - Backend Configuration:
backend.tf - Terraform Lock File:
.terraform.lock.hcl - Providers:
provider.tf
💡 Exam Tip: Organizing Terraform files properly helps in maintaining clean and scalable infrastructure.
Terraform Providers
Terraform uses providers to interact with different services.
Common Providers
- AWS:
terraform-provider-aws - Azure:
terraform-provider-azurerm - Google Cloud:
terraform-provider-google - Kubernetes:
terraform-provider-kubernetes
Example AWS Provider
terraform {
required_providers {
aws = { # provider local name
source = "hashicorp/aws" # global and unique source address
version = ">= 5.0, < 7.0"
}
}
}
provider "aws" {
region = "us-west-2"
}💡 Exam Tip: Always specify the provider and region explicitly in your configurations to avoid unintended behaviors.
- Providers can be written by individuals
- Providers can be maintained by a community of users
- Some providers are maintained by HashiCorp
- Major cloud vendors and non-cloud vendors can write, maintain, or collaborate on Terraform providers
Terraform Backends (State Management)
Terraform backend is used to store and manage Terraform state files.
Local Backend Example:
terraform {
backend "local" {}
}Remote Backend (AWS S3 + DynamoDB Locking)
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-lock"
}
}dynamodb_tableis used for state locking.- Use remote backends like AWS S3 or HashiCorp Terraform Cloud for storing the state.
💡 Exam Tip: Using remote backends allows collaboration and prevents data loss.
💡 State Locking: Prevents multiple users from making conflicting changes.
Terraform State Commands
The state is stored by default in a local file named “terraform.tfstate”
terraform state list
List all resources in the state file.
terraform state list
terraform state list aws_instance.* # Filter by resource typeterraform state show
Show detailed information about a specific resource in the state.
terraform state show aws_instance.exampleterraform state mv
Move or rename a resource in the state file.
terraform state mv aws_instance.old aws_instance.new
terraform state mv aws_instance.example module.ec2.aws_instance.exampleterraform state rm
Remove a resource from the state file without destroying it.
terraform state rm aws_instance.exampleterraform state pull
Download and output the current state file.
terraform state pull > backup.tfstateterraform state push
Upload a local state file to the remote backend.
terraform state push terraform.tfstateterraform state replace-provider
Replace the provider for resources in the state.
terraform state replace-provider "registry.terraform.io/-/aws" "registry.terraform.io/hashicorp/aws"terraform state replace-provider registry.terraform.io/hashicorp/aws registry.terraform.io/hashicorp/aws💡 Exam Tip: The terraform state command is essential for troubleshooting, renaming resources, and manually removing resources from the state file without destroying them.
Import and Output Commands
terraform import
Used to bring existing infrastructure under Terraform management.
terraform import aws_instance.example i-1234567890abcdef0
terraform import 'module.vpc.aws_vpc.main' vpc-12345678- After import, Terraform state knows about the resource but configuration must be written manually.
💡 Note: Terraform 1.5+ supports declarative import blocks:
import {
to = aws_instance.example
id = "i-1234567890abcdef0"
}terraform output
Display output values from your Terraform configuration.
terraform output # Show all outputs
terraform output instance_ip # Show specific output
terraform output -json # Output in JSON format
terraform output -raw instance_ip # Raw output without quotes (useful for scripts)💡 Exam Tip: The terraform import command does not generate configuration files; you must manually define the imported resources in your Terraform code.
Terraform Locking Mechanism
- Ensures only one process modifies state at a time.
- Enabled for Remote Backends (e.g., S3 with DynamoDB).
- Locking Error Example:
Error: Error locking state: Error acquiring state lock- Solution: Manually unlock:
terraform force-unlock <LOCK_ID>💡 Exam Tip: Always enable state locking in a remote backend (such as AWS DynamoDB) to prevent multiple users from modifying the state file simultaneously.
Workspaces
Create a new workspace:
terraform workspace new <name>Select a workspace:
terraform workspace select <name>List all workspaces:
terraform workspace listDelete an existing workspace:
terraform workspace delete stagingShow the current workspace name:
terraform workspace show💡 Exam Tip: > Tip: Workspaces separate state, not configuration. They can help for lightweight env splits, but many teams prefer separate folders/repos or distinct HCP Terraform workspaces per environment for stronger isolation.
Formatting and Validation Commands
terraform fmt
Format Terraform configuration files to a canonical style.
terraform fmt # Format files in current directory
terraform fmt -recursive # Format all files in subdirectories
terraform fmt -check # Check if files are formatted (useful in CI/CD)
terraform fmt -diff # Show formatting changesterraform console
Interactive console for evaluating Terraform expressions.
terraform console
# Then you can test expressions:
> var.instance_type
> aws_instance.example.id
> length(var.availability_zones)⚠️ Deprecated Commands (Do NOT Use)
terraform taint ❌ DEPRECATED
Old way (before Terraform 0.15.2):
terraform taint aws_instance.exampleNew way (Terraform 0.15.2+):
terraform apply -replace="aws_instance.example"terraform untaint ❌ DEPRECATED
No longer needed. Resources are not tainted anymore; use -replace flag instead.
terraform refresh ❌ DEPRECATED
Old way:
terraform refreshNew way (Terraform 0.15.4+):
terraform apply -refresh-only
# or during plan
terraform plan -refresh-onlyNote: `terraform refresh` is deprecated; use `-refresh-only` with plan/apply.
Environment Variables for Terraform Commands
# Enable detailed logging
export TF_LOG=TRACE # TRACE, DEBUG, INFO, WARN, ERROR
export TF_LOG_PATH=./terraform.log
# Input variables via environment
export TF_VAR_instance_type=t2.micro
export TF_VAR_region=us-east-1
# Configure CLI behavior
export TF_CLI_ARGS_plan="-out=tfplan"
export TF_CLI_ARGS_apply="-auto-approve"
# Disable color output
export TF_NO_COLOR=1
# Custom data directory
export TF_DATA_DIR=./.terraform-customCommand Combinations & Best Practices
Safe Apply Workflow
terraform fmt -recursive
terraform validate
terraform plan -out=tfplan
terraform show tfplan
terraform apply tfplanState Backup Before Dangerous Operations
terraform state pull > backup-$(date +%Y%m%d-%H%M%S).tfstate
terraform state rm aws_instance.exampleCheck What Will Be Destroyed
terraform plan -destroy
terraform destroy -target=aws_instance.example # Selective destroyWorking with Multiple Environments
terraform workspace new production
terraform plan -var-file="production.tfvars"
terraform apply -var-file="production.tfvars"💡 Exam Tips
- Always run
terraform planbeforeterraform applyto preview changes - Use
-outflag with plan to save and review changes before applying - Understand the difference between
terraform refresh(deprecated) andterraform apply -refresh-only - Know when to use
-replaceinstead of the oldtaintcommand - State commands (
state mv,state rm) are crucial for refactoring without destroying resources - Workspaces separate state, not configuration; for long-lived environments prefer one workspace per environment (or separate folders/repos).
terraform fmtshould be part of your CI/CD pipeline with-checkflag- Remote state locking is automatically handled by backends like S3+DynamoDB
terraform consoleis extremely useful for testing expressions and functions interactively
Terraform Resource Meta-Arguments
depends_on
Ensures that a resource is created only after another resource is available.
resource "aws_instance" "web" {
depends_on = [aws_s3_bucket.example]
}✅ Use Case: Ensures the EC2 instance is created only after the S3 bucket exists.
count (Used for creating multiple resources)
resource "aws_instance" "example" {
count = 3
ami = "ami-123456"
}for_each (For dynamic resource creation)
variable "instances" {
type = map(object({
ami = string
}))
default = {
instance1 = { ami = "ami-123456" }
instance2 = { ami = "ami-654321" }
}
}resource "aws_instance" "example" {
for_each = var.instances
ami = each.value["ami"]
}lifecycle (Managing resource behavior)
resource "aws_instance" "example" {
lifecycle {
prevent_destroy = true # Prevents accidental deletion
}
}💡 Exam Tips:
- Use
depends_ononly when needed; Terraform manages dependencies automatically. - Use
countfor simple replication andfor_eachfor dynamic resources. lifecyclehelps prevent unintended resource changes or destruction.- Avoid hardcoded values; use variables for flexibility.
Data Sources
Data sources in Terraform allow you to query and retrieve information from external systems like AWS, Azure, or other Terraform state files. This helps in using dynamically fetched data instead of hardcoded values.
Example: Fetching AWS AMI ID
data "aws_ami" "latest" {
most_recent = true
owners = ["amazon"] # ensure official images
filter {
name = "name"
values = ["amzn2-ami-hvm*"]
}
}Use in Resource:
resource "aws_instance" "example" {
ami = data.aws_ami.latest.id
}Example: Retrieving AWS VPC ID
data "aws_vpc" "default" {
default = true
}
resource "aws_subnet" "example" {
vpc_id = data.aws_vpc.default.id
}Example: Using Terraform State Data Source
You can reference resources from another Terraform state file:
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "my-terraform-state"
key = "network/terraform.tfstate"
region = "us-east-1"
}
}
resource "aws_instance" "example" {
vpc_security_group_ids = [data.terraform_remote_state.network.outputs.security_group_id]
}💡 Exam Tip: Terraform data sources allow you to fetch external information dynamically, enabling your configuration to use the latest values without hardcoding.
Dynamic Blocks
Terraform supports loops inside resource blocks using dynamic blocks:
resource "aws_security_group" "example" {
dynamic "ingress" {
for_each = var.allowed_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
}
}
}Terraform Variables and Data Types
- String:
"example" - Number:
42 - List:
[1, 2, 3] - Map:
{ key = "value" } - Boolean:
trueorfalse - Tuple:
[1, "hello", true] - Object:
{ name = "John", age = 30 } - Sensitive Variables:
sensitive = true(Hides sensitive data in Terraform output)
💡 Exam Tip: Use variable validation to enforce constraints on input variables. Avoid hardcoding values and use variable files (.tfvars).
Terraform Locals
Locals define reusable values within a module:
locals {
common_tags = {
Environment = "dev"
Owner = "team"
}
}
resource "aws_vpc" "main" {
tags = local.common_tags
}Terraform Functions
Math Functions
sum([1, 2, 3]) # Output: 6
max(3, 9, 2) # Output: 9
min(3, 9, 2) # Output: 2String Functions
upper("hello") # Output: "HELLO"
lower("HELLO") # Output: "hello"
replace("hello", "h", "y") # Output: "yello"Collection Functions
length(["a", "b", "c"]) # Output: 3
contains(["a", "b", "c"], "b") # Output: trueDate & Time Functions
formatdate("YYYY-MM-DD", timestamp())💡 Exam Tip: Terraform functions help manipulate data dynamically. Ensure you understand how to use them for automation and resource interpolation.
Interpolation
String Interpolation:
"Hello, ${var.name}!"Attribute Interpolation:
aws_instance.example.idFile Interpolation:
file("${path.module}/config.json")Length Function:
length(var.list)Conditional Logic & Loops
If Expression:
condition ? true_value : false_valueFor Loop in List:
[for element in var.list : element * 2]For Loop in Map:
{ for k, v in var.map : k => v * 2 }Count:
resource "aws_instance" "example" {
count = 3
ami = "ami-123456"
}💡 Exam Tip: Conditional logic and loops help optimize infrastructure configurations by reducing redundant code.
Splat Expressions
Used to extract values from lists of objects.
# Splat / collection extraction
# From a list of instances, collect all public IPs:
output "instance_public_ips" {
value = aws_instance.web[*].public_ip
}Terraform Modules
Declare a Module:
module "name" {
source = "path/to/module"
}Define Input Variables in Modules:
variable "instance_type" { type = string }Expose Output Values from Modules:
output "instance_id" {
value = aws_instance.example.id
}💡 Exam Tip: Use modules to structure your Terraform code for reusability and maintainability.
Lifecycle Management
Terraform lifecycle meta-argument helps control resource behavior, preventing unintended deletions, ensuring seamless updates, and ignoring specific changes to maintain stability.
Prevent Destroy:
resource "aws_instance" "example" {
lifecycle {
prevent_destroy = true
}
}Create Before Destroy:
resource "aws_instance" "example" {
lifecycle {
create_before_destroy = true
}
}Ignore Changes:
resource "aws_instance" "example" {
lifecycle {
ignore_changes = [tags]
}
}💡 Exam Tips:
- Use
prevent_destroyfor critical resources to avoid accidental deletion. - Use
create_before_destroyfor zero-downtime changes when replacing resources. - Use
ignore_changesto avoid unnecessary updates when external systems modify resources. - Terraform’s
lifecycleshould be used carefully as it impacts state management and updates.
Provisioners
Local Exec Provisioner:
resource "null_resource" "example" {
provisioner "local-exec" {
command = "echo 'Resource Created!' > log.txt"
}
}Remote Exec Provisioner:
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/id_rsa")
host = self.public_ip
} provisioner "remote-exec" {
inline = [
"sudo apt update",
"sudo apt install -y nginx"
]
}
}
Using a Script with Remote Exec
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/id_rsa")
host = self.public_ip
}
provisioner "remote-exec" {
script = "install_nginx.sh"
}
}File Provisioner:
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/id_rsa")
host = self.public_ip
} provisioner "file" {
source = "config.cfg"
destination = "/home/ubuntu/config.cfg"
}
}
💡 Exam Tip: Terraform provisioners should be used as a last resort; prefer built-in cloud-init, user_data, or configuration management tools for better automation.
Debugging
Enable Debug Logs:
export TF_LOG=DEBUG
terraform applyLogging to a File:
export TF_LOG_PATH="terraform.log"💡 Exam Tip: Debug logs help troubleshoot Terraform execution errors and state inconsistencies.
HCP Terraform (formerly Terraform Cloud)
HCP Terraform is HashiCorp’s managed service that provides secure state management, team collaboration, governance, and automation for Terraform workflows.
HCP Terraform hierarchy. An Organization contains Projects, and each Project contains one or more Workspaces where runs and state are managed. Settings (VCS connections, variables, policies, health checks) can be applied at the organization, project, or workspace level.
Why Use HCP Terraform?
✅ Remote State Management
- Eliminates the risk of local state loss
- Enforces state consistency with locking and remote backends
✅ Secure & Scalable Collaboration
- Team-based access control with RBAC (Role-Based Access Control).
- Allows multiple team members to work on Terraform without conflicts.
- Stores sensitive data securely via Terraform Cloud Variables & Workspaces.
✅ Remote Execution & Automation
- Runs Terraform plans and applies in the cloud, reducing dependency on local machines.
- Supports VCS (Version Control System) integration (GitHub, GitLab, Bitbucket).
- Automatically triggers Terraform runs on pull requests or code changes.
✅ Policy Enforcement with Sentinel
- Enforces security, cost, and compliance rules before Terraform apply.
- Example: Prevent provisioning expensive instance types.
✅ Private Module Registry
- Allows teams to publish and reuse Terraform modules securely.
- Helps standardize infrastructure across the organization.
✅ Drift Detection & Monitoring
- HCP Terraform can detect when infrastructure has changed outside of Terraform
- Uses health assessments to continuously check for drift (Plus tier and above)
- Notifications can be configured when drift is detected
- Helps identify unauthorized or unexpected infrastructure changes
✅ Multi-Cloud Deployment & Integration
- Works across AWS, Azure, GCP, Kubernetes, and private clouds.
- Integrates with Terraform Enterprise for on-premises use cases.
- Store and manage your Terraform state remotely.
- Collaborate with team members and apply infrastructure changes using Terraform Cloud.
- Enable remote execution to apply configurations without local execution.
Example: HCP Terraform Configuration
terraform {
cloud {
organization = "my-org"
workspaces {
name = "prod-environment"
}
}
}HCP Terraform Authentication
terraform login
terraform logout💡 Exam Tips:
- HCP Terraform replaces the old “Terraform Cloud” branding.
- Remote state + remote runs + policies + VCS integration are core exam points.
- Sentinel policies evaluate before apply; failed policies block the run.
- Workspaces are a unit of state/run history; use separate workspaces per environment.
Terraform Security Best Practices
✅ Use Remote Backend for State Storage
✅ Enable State Locking (DynamoDB for AWS)
✅ Never Hardcode Secrets (Use AWS SSM, Vault, or Environment Variables)
✅ Use IAM Roles for Authentication
✅ Restrict Access to the State File
✅ Enable Encryption for Backend Storage
Conclusion
Terraform is an essential tool for modern infrastructure automation, and mastering its fundamentals will greatly enhance your DevOps and cloud engineering skills. Whether you are studying for the Terraform Associate Exam or looking to optimize your workflow, this cheat sheet provides a solid foundation for Terraform proficiency.
🚀 Good luck with your Terraform certification and infrastructure automation journey!
