Exam Details: 57 Questions ยท 60 Minutes ยท 70% to Pass ยท Multiple Choice
1. ๐๏ธ IaC CONCEPTS
Core Concepts
- Infrastructure as Code (IaC) โ Manage & provision infrastructure via machine-readable config files instead of manual processes
- Declarative โ You define WHAT the end state should be; Terraform figures out HOW to get there
- Imperative โ You define HOW step-by-step (not Terraform's approach)
- Idempotent โ Running the same config multiple times always produces the same result
Infrastructure Lifecycle
- Day 0 โ Initial provisioning of brand-new infrastructure
- Day 1+ โ Ongoing changes and maintenance of existing infrastructure
- Immutable Infra โ Replace resources when changes are needed (Terraform's approach)
- Mutable Infra โ Update resources in-place (traditional approach)
2. โ๏ธ CORE WORKFLOW COMMANDS
| Command |
Purpose |
terraform init |
Initialize directory; download providers & modules |
terraform init -upgrade |
Upgrade providers to latest allowed version |
terraform init -reconfigure |
Reconfigure backend, ignore existing state |
terraform plan |
Preview changes โ shows create/change/destroy |
terraform plan -out=tfplan |
Save plan to file for deterministic apply |
terraform apply |
Execute plan; prompts for approval |
terraform apply -auto-approve |
Skip interactive approval (use in CI/CD) |
terraform apply tfplan |
Apply a previously saved plan file |
terraform apply -replace=ADDR |
Force replacement of a specific resource |
terraform destroy |
Destroy ALL managed infrastructure |
terraform destroy -target=ADDR |
Destroy only a specific resource |
terraform fmt |
Reformat .tf files to canonical HCL style |
terraform fmt -check |
Check formatting without changing files |
terraform validate |
Check syntax and internal consistency |
terraform show |
Display current state or a saved plan |
terraform output |
Show all output values |
terraform output NAME |
Show a specific output value |
terraform refresh |
โ ๏ธ DEPRECATED โ use -refresh-only |
terraform apply -refresh-only |
Safer replacement for terraform refresh |
terraform import ADDR ID |
Import existing resource into state |
terraform get |
Download and update child modules |
terraform console |
Interactive console for evaluating expressions |
terraform graph |
Generate visual dependency graph |
terraform providers |
Show providers required by current config |
terraform version |
Print current Terraform version |
terraform taint |
โ ๏ธ DEPRECATED โ use -replace flag instead |
3. ๐ HCL CONFIGURATION & SYNTAX
Block Types
| Block |
Purpose |
Example |
resource |
Managed infrastructure object |
resource "aws_instance" "web" { ... } |
data |
Read-only data source |
data "aws_ami" "ubuntu" { ... } |
variable |
Input parameters |
variable "region" { default = "us-east-1" } |
output |
Export values |
output "ip" { value = aws_instance.web.public_ip } |
locals |
Local named values |
locals { env = "prod" } |
module |
Call a reusable module |
module "vpc" { source = "./modules/vpc" } |
terraform |
Settings & backend config |
terraform { required_version = ">= 1.0" } |
provider |
Configure a provider plugin |
provider "aws" { region = "us-east-1" } |
count = N โ Create N copies; use count.index to differentiate
for_each = map/set โ One resource per item; use each.key / each.value
depends_on = [list] โ Explicit dependency on another resource/module
provider = alias โ Use alternate provider config (e.g. multi-region)
lifecycle { } โ Control resource creation/destruction behavior
Lifecycle Options
create_before_destroy = true โ Create new before destroying old (zero-downtime)
prevent_destroy = true โ Block destroy; Terraform errors if attempted
ignore_changes = [list] โ Ignore changes to specified attributes after creation
replace_triggered_by = [list] โ Replace resource when referenced value changes
Variable Types
| Type |
Example |
string |
"hello" |
number |
42 / 3.14 |
bool |
true / false |
list(T) |
["a", "b", "c"] |
map(T) |
{ key = "value" } |
set(T) |
Like list but unordered & unique |
object() |
Complex structured type with named attributes |
tuple() |
Fixed-length sequence with mixed types |
any |
Accepts any type โ use sparingly |
Variable Precedence (lowest โ highest)
- Default value in variable block
terraform.tfvars (auto-loaded)
*.auto.tfvars (auto-loaded, alphabetical order)
-var-file flag on command line
-var flag on command line
TF_VAR_name environment variables โ highest
4. ๐พ STATE MANAGEMENT
State Files
terraform.tfstate โ Default local file storing current infrastructure state
terraform.tfstate.backup โ Previous state backup; auto-created before each apply
- Remote state โ Store state in S3, GCS, or Terraform Cloud โ required for teams
- State locking โ Prevents concurrent modifications; supported by S3+DynamoDB, TF Cloud, GCS
- โ ๏ธ Sensitive data warning โ State may contain secrets & passwords โ always secure it!
State Commands
| Command |
Purpose |
terraform state list |
List all resources tracked in state |
terraform state show ADDR |
Show details of a specific resource |
terraform state mv SRC DST |
Move/rename resource in state without destroying |
terraform state rm ADDR |
Remove from state (does NOT destroy real resource) |
terraform state pull |
Download and output current remote state |
terraform state push |
Upload local state to remote backend (use carefully) |
terraform force-unlock ID |
Manually release a stuck state lock |
Backends
| Backend |
Notes |
local |
Default โ state on local disk |
s3 |
AWS S3; add DynamoDB table for locking |
gcs |
Google Cloud Storage |
azurerm |
Azure Blob Storage |
http |
Generic REST client |
Terraform Cloud |
Full locking, history, collaboration |
consul |
HashiCorp Consul KV store |
5. ๐ PROVIDERS & REGISTRY
Provider Concepts
- Provider โ Plugin that lets Terraform interact with external APIs (AWS, Azure, GCPโฆ)
- Terraform Registry โ
registry.terraform.io โ public source for providers & modules
- Official provider โ Maintained by HashiCorp; labeled "official" (e.g.
hashicorp/aws)
- Partner provider โ Maintained by tech company partner (e.g.
datadog/datadog)
- Community provider โ Maintained by community members โ use with caution
.terraform.lock.hcl โ Records exact provider versions selected; commit to VCS!
- Provider alias โ Use multiple configs of same provider (e.g. two AWS regions)
Version Constraint Operators
| Operator |
Meaning |
>= 1.0 |
Greater than or equal to 1.0 |
<= 1.0 |
Less than or equal to 1.0 |
~> 1.0 |
Allows 1.x but NOT 2.0 (pessimistic constraint) |
~> 1.0.4 |
Allows 1.0.x but NOT 1.1.0 |
!= 1.2.0 |
Exclude a specific version |
>= 1.0, < 2.0 |
Intersection โ combine multiple constraints |
6. ๐ฆ MODULES
Module Concepts
- Module โ Container for multiple resources used together as a logical unit
- Root module โ Your main working directory with .tf files (always exists)
- Child module โ Any module called/referenced by another module
- Published module naming โ Must follow:
<NAMESPACE>/<MODULE_NAME>/<PROVIDER>
- Module inputs โ Variables passed INTO the module
- Module outputs โ Values returned FROM the module; access via
module.NAME.OUTPUT
Module Sources
| Source Type |
Example |
| Local path |
./modules/vpc |
| Terraform Registry |
hashicorp/consul/aws |
| GitHub HTTPS |
github.com/hashicorp/example |
| GitHub SSH |
git@github.com:hashicorp/example.git |
| Generic Git |
git::https://example.com/vpc.git?ref=v1.2.0 |
| S3 Bucket |
s3::https://s3.amazonaws.com/bucket/vpc.zip |
| GCS Bucket |
gcs::https://storage.googleapis.com/bucket/vpc.zip |
Key Features
- Terraform Cloud (TFC) โ SaaS for remote state, runs, team collaboration, policy enforcement
- Terraform Enterprise โ Self-hosted TFC for air-gapped or compliance requirements
- Workspace โ Isolated environment with its own state, variables, and run history
- Remote backend โ Stores state in TFC; runs can also execute in TFC infrastructure
- Sentinel โ Policy-as-code framework (Team & Governance / Plus plan)
- OPA โ Open Policy Agent โ alternative policy enforcement supported by TFC
- Private Registry โ Host private modules & providers within your TFC organization
- VCS Integration โ Connect to GitHub/GitLab/Bitbucket; auto-trigger runs on Git push
- Agent Pools โ Self-hosted runners that execute Terraform runs in your environment
- Air Gap โ Terraform Enterprise can operate with no internet access
- Cost Estimation โ Estimate infra cost before applying (TFC feature)
- SSO โ SAML 2.0 single sign-on (Enterprise)
- Audit Logging โ Full audit trail of all actions (Enterprise)
8. ๐ง BUILT-IN FUNCTIONS (KEY ONES)
String Functions
| Function |
Purpose |
Example |
tostring(val) |
Convert to string |
tostring(42) โ "42" |
format(fmt, args) |
String formatting |
format("Hello, %s!", "World") |
lower/upper(str) |
Change case |
lower("HELLO") โ "hello" |
trimspace(str) |
Remove whitespace |
trimspace(" hi ") โ "hi" |
split(sep, str) |
Split into list |
split(",", "a,b") โ ["a","b"] |
join(sep, list) |
Join into string |
join(",", ["a","b"]) โ "a,b" |
replace(str,old,new) |
Replace substring |
replace("a-b", "-", "_") |
substr(str,off,len) |
Extract substring |
substr("hello", 0, 3) โ "hel" |
Collection Functions
| Function |
Purpose |
Example |
length(val) |
Count items |
length(["a","b"]) โ 2 |
flatten(list) |
Flatten nested lists |
flatten([[1,2],[3]]) โ [1,2,3] |
distinct(list) |
Remove duplicates |
distinct([1,1,2]) โ [1,2] |
concat(lists...) |
Combine lists |
concat([1,2],[3,4]) โ [1,2,3,4] |
merge(maps...) |
Merge maps |
merge({a=1},{b=2}) โ {a=1,b=2} |
keys/values(map) |
Extract keys or values |
keys({a=1,b=2}) โ ["a","b"] |
lookup(map,key,def) |
Safe map lookup |
lookup(var.m, "k", "default") |
contains(list,val) |
Check if value exists |
contains([1,2,3], 2) โ true |
element(list,idx) |
Get by index (wraps) |
element(["a","b"], 0) โ "a" |
toset(list) |
Convert to set |
toset(["a","a","b"]) โ {"a","b"} |
Filesystem & Encoding Functions
| Function |
Purpose |
file(path) |
Read file contents as string |
templatefile(path, vars) |
Render template file with variables |
filebase64(path) |
Read file as base64 string |
jsonencode(val) |
Encode value as JSON string |
jsondecode(str) |
Decode JSON string to value |
base64encode/decode |
Base64 encoding/decoding |
Type & Logic Functions
| Function |
Purpose |
can(expr) |
Returns true if expression produces no error |
try(exprs...) |
Returns first successful expression value |
tonumber/tobool/tostring |
Type conversion functions |
Network Functions
| Function |
Purpose |
cidrsubnet(prefix,newbits,num) |
Calculate subnet CIDR |
cidrhost(prefix, hostnum) |
Calculate host IP within CIDR |
9. ๐ EXPRESSIONS, LOOPS & DYNAMIC BLOCKS
Expression Types
- Conditional (ternary) โ
condition ? true_val : false_val
- for (list) โ
[for item in list : upper(item)]
- for (map) โ
{for k, v in map : k => upper(v)}
- for with filter โ
[for s in var.list : s if s != "skip"]
- Splat expression โ
var.list[*].id (shorthand for extracting attribute from all items)
- String interpolation โ
"Hello ${var.name}!"
- Heredoc โ
<<EOT ... EOT for multi-line strings
- dynamic block โ Generate repeated nested blocks using
for_each inside a block
- sensitive() โ Mark a value as sensitive to suppress from output
- nonsensitive() โ Unmark a value previously marked as sensitive
10. ๐ RESOURCE ADDRESSING & DEPENDENCIES
| Format |
Example |
| Basic resource |
aws_instance.web |
| With module |
module.vpc.aws_instance.web |
| Nested module |
module.parent.module.child.aws_instance.web |
| With count index |
aws_instance.web[0] |
| With for_each key |
aws_instance.web["key_name"] |
| Data source |
data.aws_ami.ubuntu.id |
| Module output |
module.vpc.subnet_id |
| Local value |
local.env_name |
| Variable |
var.region |
| Self reference |
self.id (in provisioners/lifecycle) |
Dependencies
- Implicit dependency โ Auto-detected via resource attribute references (preferred)
- Explicit dependency โ
depends_on = [resource] โ use only when no attribute ref exists
11. ๐ DEBUGGING, LOGGING & ENV VARIABLES
| Variable |
Purpose |
TF_LOG |
Log level: TRACE, DEBUG, INFO, WARN, ERROR |
TF_LOG_PATH |
Write logs to a file instead of stderr |
TF_VAR_name |
Set variable value (e.g. TF_VAR_region=us-east-1) |
TF_CLI_ARGS |
Default CLI arguments for all commands |
TF_CLI_ARGS_plan |
Default arguments for terraform plan specifically |
TF_INPUT=false |
Disable interactive input prompts |
TF_IN_AUTOMATION |
Adjust output for CI/CD contexts |
TF_DATA_DIR |
Override .terraform directory location |
TF_WORKSPACE |
Set active workspace via env variable |
CHECKPOINT_DISABLE |
Disable version check service |
12. ๐๏ธ WORKSPACES
Workspace Commands
| Command |
Purpose |
terraform workspace list |
List all workspaces |
terraform workspace new NAME |
Create a new workspace |
terraform workspace select NAME |
Switch to a workspace |
terraform workspace show |
Show current workspace |
terraform workspace delete NAME |
Delete a workspace (can't be active) |
Workspace Concepts
- Default workspace โ Always exists; called "default"; cannot be deleted
- State per workspace โ Each workspace has its own isolated state file
terraform.workspace โ Built-in variable containing current workspace name
- Use case โ Manage dev/staging/prod from one config
- โ ๏ธ CLI workspaces โ Terraform Cloud workspaces (TFC workspaces are more feature-rich)
13. โก PROVISIONERS (LAST RESORT ONLY)
โ ๏ธ HashiCorp recommends avoiding provisioners โ prefer user_data, cloud-init, or purpose-built providers.
Provisioner Types
local-exec โ Runs a command on the machine running Terraform
remote-exec โ Runs commands on the remote resource via SSH or WinRM
file โ Copies files/directories to the remote resource
Provisioner Options
when = destroy โ Provisioner runs only on resource destruction
on_failure = continue โ Continue even if provisioner fails
on_failure = fail โ Taint resource and fail (default behavior)
connection block โ Defines SSH/WinRM connection details
14. ๐ SENSITIVE VALUES & SECURITY
Security Best Practices
sensitive = true โ Mark variable or output; Terraform redacts from CLI output
sensitive() function โ Mark any value as sensitive programmatically
- State contains secrets โ State stores ALL values including sensitive ones โ secure it!
- Vault provider โ HashiCorp Vault integration for dynamic secrets
- Environment variables โ Use
TF_VAR_* to pass secrets without storing in files
Always .gitignore These:
terraform.tfvars
*.tfstate
*.tfstate.backup
.terraform/
Backend Encryption
- S3 backend supports server-side encryption (SSE) at rest
15. โ ๏ธ EXAM TRAPS & GOTCHAS
Deprecated Commands
- โ
terraform taint โ โ
Use terraform apply -replace=RESOURCE_ADDRESS
- โ
terraform refresh โ โ
Use terraform apply -refresh-only
Common Pitfalls
- count vs for_each โ
count uses index (fragile on delete); for_each uses keys (more stable)
- terraform.tfvars auto-loaded โ also
*.auto.tfvars; other .tfvars need explicit -var-file
- .terraform.lock.hcl โ Commit to VCS! Ensures consistent provider versions across team
- ~> 3.0 โ Allows 3.x but NOT 4.0;
~> 3.0.0 allows 3.0.x only
- Backend config not in plan โ Plan only shows resource changes, not backend config
- CLI workspace โ TFC workspace โ Conceptually different things
- Data sources evaluated at plan time โ Not just at apply
- No partial apply โ Terraform applies all changes; no partial rollback
- terraform import requires config โ Must have resource block BEFORE importing
- -target flag โ Not recommended for routine use; use only in emergencies
- Implicit over explicit deps โ Prefer attribute references; use
depends_on only when no attribute ref exists
16. ๐ฏ EXAM OBJECTIVE WEIGHTINGS
| Domain |
Weight |
| IaC Concepts |
16% |
| Terraform's Purpose |
9% |
| Terraform Basics |
32% |
| Terraform State |
16% |
| Terraform Cloud |
25% |
| Advanced Concepts |
2% |
๐ Quick Reference Tips
Before the Exam
- โ
Understand the difference between declarative vs imperative
- โ
Know all core workflow commands by heart
- โ
Practice with workspaces and remote backends
- โ
Understand state management thoroughly
- โ
Know when to use
count vs for_each
- โ
Memorize variable precedence order
- โ
Understand provider versioning constraints
- โ
Know the key built-in functions
- โ
Practice with modules and module sources
- โ
Understand Terraform Cloud features
During the Exam
- Read questions carefully โ look for keywords like "best practice", "recommended", "deprecated"
- Eliminate obviously wrong answers first
- Watch for traps around deprecated commands
- Remember: Terraform is declarative and idempotent
- When in doubt, choose the answer that follows HashiCorp's recommendations
Good luck with your Terraform Associate 004 certification! ๐