Day 28: How I Prepared for the Terraform Associate Exam with Practice Exams

Day 28: How I Prepared for the Terraform Associate Exam with Practice Exams

Days 9 through 27 built infrastructure: modules, remote state, multi-region failover, the works. Day 28 is a different kind of day — no `terraform apply`, no AWS console. Just two 57-question practice exams for the Terraform Associate (004) certification, the gaps they exposed, and the ten or so concepts that trip up almost every candidate. This post is the study log: what I got wrong, what the right answer actually is, and where the documentation lives.

Overview

Section What's In It
Why Practice Exams Matter The case for doing them before you think you're ready
How I Approached the Two Exams Time-boxed, no docs, mark-and-move pattern
Strong and Weak Domains Where the points came easy, where they didn't
The Ten Trickiest Concepts Sample questions, the wrong answer, why it's wrong
The 30-Minute Review Loop How to convert wrong answers into retained knowledge
What I'm Doing Differently for the Real Exam Concrete changes for Day 29's third practice exam

Why Practice Exams Matter

The Terraform Associate (004) exam is 57 multiple-choice questions in 60 minutes — roughly one minute per question. You can read the official exam guide front to back, write Terraform every day for a year, and still walk out of the testing center feeling underwater if you've never sat down with a timer and a question pool.

What practice exams measure isn't knowledge (you have it) — it's three other things:

  1. Calibration. Knowing the difference between "I'm 95% sure" and "I'm 60% sure." On the real exam you have no time to second-guess the 95s and no information to improve the 60s — so you mark the 60s, move on, and come back if there's time.
  2. Question-pattern recognition. HashiCorp's questions follow a small set of templates: "Which command does X?", "What happens when Y is removed from config?", "Which is true about Z?", "Given this snippet, what is the result?". Pattern recognition cuts read-time per question roughly in half.
  3. Stamina. Sixty minutes of high-focus reading is harder than it sounds. The third practice exam is when you find out whether your concentration holds up past question 40.

Passing is generally cited as ~70%, but HashiCorp does not publish the actual cut score — it's adaptive and varies by exam form. Don't aim for 70%; aim for consistent 85%+ across multiple practice attempts. Anything less and exam-day nerves will pull you under.

Where the questions came from

I used Bryan Krausen's HashiCorp Certified Terraform Associate 004 — Practice Exams on Udemy. Six full-length 57-question exams (~350 questions total), mapped one-to-one to the TA-004 objectives, including Terraform 1.12 and HCP Terraform topics. Two things make it stand out from the other practice-exam courses I looked at:

  • Real explanations, not just answer keys. Every wrong-answer choice has a written rationale explaining why it's wrong, plus a link to the relevant section of the official docs. That's the input my 30-minute review loop below depends on.
  • Two modes per exam. Practice mode shows the answer after each question (good for learning); Exam mode enforces the 60-minute timer and the 70% pass threshold (good for calibration). Use practice mode on exams 1–2, then switch to exam mode for the rest.

Bryan is a HashiCorp Ambassador and an Authorized Terraform Trainer, so the question style genuinely tracks the real exam's tone — scenario-based stems, multi-select traps, and distractors that look right until you read them carefully. Recommended.

How I Approached the Two Exams

A simple, repeatable protocol:

  1. Single uninterrupted sitting. Phone in another room. No Slack. Closed door. The real exam at a Pearson VUE testing center has none of these distractions — practice should match.
  2. 60-minute timer, hard stop. When the timer ends, the exam ends. Better to finish a practice exam at 75% with 5 unanswered than to "finish" at 90% in 90 minutes and convince yourself you're ready.
  3. Mark-and-move on anything > 30 seconds. First pass = answer everything I'm sure of. Second pass = work through marked questions with the remaining time. This is also how the real Pearson VUE interface works — use it.
  4. No docs, no Google, no exceptions. The whole point is to surface what I don't actually know. Looking things up while practicing trains the wrong reflex.
  5. Review every wrong answer immediately after. Not the next day, not the next week. While the question is still fresh, open the docs page, read the relevant section, and write a one-line note. (More on this in the review loop section.)

Strong and Weak Domains

The Associate 004 exam covers 8 domains. HashiCorp does not publish per-domain weightings (a change from the 003 exam), so the breakdown below is qualitative — based on where I was confident across the two practice exams and where I had to guess.

Domain How It Felt Notes
1. Understand IaC concepts Strong Conceptual, easy points if you've read the intro chapters
2. Understand the purpose of Terraform (vs. other tools) Strong Mostly "why use IaC" framing
3. Understand Terraform basics Strong Providers, init, the workflow — bread and butter
4. Use Terraform CLI Weak Where most of my wrong answers landed — flag minutiae
5. Interact with Terraform modules Strong Variables, outputs, sources — clear if you've built modules
6. Use Terraform configuration Mostly strong Loops, dynamic blocks, expressions
7. Implement and maintain state Weak The trickiest domain — backends, locking, sensitive data
8. Read, generate, and modify configuration Mixed import, moved, removed, terraform fmt, terraform validate

Pattern: strong on conceptual and configuration-writing domains, weak on CLI flag minutiae (Domain 4), state management edge cases (Domain 7), and the newer 004-specific blocks (Domain 8 — import, moved, removed, check). Those weak areas drove the next section.

The Ten Trickiest Concepts

These are the question types that tripped me up across both exams. Each one includes a sample question, the answer most people pick (wrongly), and the actual right answer with the underlying rule.

1. terraform init -upgrade vs. terraform init

Sample question. You've changed the version constraint on the AWS provider from ~> 4.0 to ~> 5.0 in your configuration. Which command should you run?

  • A) terraform init
  • B) terraform init -upgrade
  • C) terraform plan -refresh-only
  • D) terraform providers lock

Wrong-answer magnet: A. People assume terraform init will just notice the change.

Right answer: B. Plain terraform init honors the lock file (.terraform.lock.hcl) and will not upgrade past the locked version, even if the constraint allows it. -upgrade tells Terraform to ignore the lock file and pick the newest version that satisfies the new constraint, then rewrite the lock file.

Rule: Lock file is sticky. Provider version bumps need -upgrade.

2. terraform plan with -refresh=false

Sample question. Which of the following is true about terraform plan -refresh=false?

  • A) It skips reading the current state file
  • B) It skips refreshing the real-world status of resources before computing the plan
  • C) It prevents Terraform from updating the state file
  • D) It is equivalent to terraform plan -lock=false

Wrong-answer magnet: A. The state file is always read; -refresh=false only skips the call to the cloud API that reconciles state with reality.

Right answer: B. Useful for fast plans in CI when you trust state and want to skip the (potentially slow) refresh step.

Rule: "Refresh" = "ask the cloud what's actually there." It's distinct from reading the state file.

3. State locking — what does it actually lock?

Sample question. State locking with the S3 backend + DynamoDB table prevents:

  • A) Two engineers from running terraform plan simultaneously
  • B) Two engineers from running terraform apply simultaneously against the same state file
  • C) Concurrent reads of the state file
  • D) Concurrent runs against different workspaces in the same state file

Wrong-answer magnet: A. Many people think any Terraform operation acquires the lock.

Right answer: B. Plans that don't write state (terraform plan without -out) acquire a lock briefly to read state, then release. Apply holds the lock for the full duration. Different workspaces have separate state files (and therefore separate locks).

Rule: The lock protects state-file writes, not reads.

4. sensitive = true and what it actually does

Sample question. An output is marked sensitive = true. Which of the following is true?

  • A) The value is encrypted in the state file
  • B) The value is hidden from terraform plan and terraform apply output but stored in plain text in state
  • C) The value cannot be referenced by other modules
  • D) The value is automatically rotated on every apply

Wrong-answer magnet: A. sensitive does not encrypt anything.

Right answer: B. The state file is plain JSON. Sensitivity only affects what gets printed to stdout. To actually protect state contents, you need backend-level encryption (S3 SSE, Terraform Cloud's encrypted state, etc.).

Rule: sensitive = display filter, not encryption.

5. terraform taint vs. terraform apply -replace

Sample question. You want to force replacement of a single resource on the next apply. Which is the recommended approach in current Terraform?

  • A) terraform taint aws_instance.web
  • B) terraform apply -replace="aws_instance.web"
  • C) Delete the resource block and re-add it
  • D) terraform state rm aws_instance.web

Wrong-answer magnet: A. terraform taint was the canonical answer for years.

Right answer: B. terraform taint is deprecated as of Terraform 0.15.2. The plan/apply -replace flag does the same thing without mutating state ahead of time, so the change is visible in the plan output.

Rule: taint is dead. Use -replace.

6. terraform state mv vs. the moved {} block

Sample question. You renamed aws_instance.web to aws_instance.app_server in your configuration. Without intervention, Terraform will plan to destroy aws_instance.web and create aws_instance.app_server. What's the modern way to fix this?

  • A) terraform state mv aws_instance.web aws_instance.app_server
  • B) Add a moved {} block to your configuration
  • C) Use terraform import
  • D) Use terraform refresh

Wrong-answer magnet: A. State mv works, but it's a one-time CLI invocation that other engineers won't see in version control.

Right answer: B. The moved {} block (introduced in 1.1) declares the rename in code, so anyone applying the configuration handles it correctly without coordination. State mv is still valid; the moved block is preferred.

moved {
  from = aws_instance.web
  to   = aws_instance.app_server
}

Rule: Refactors that need to survive across teams belong in code, not CLI history.

7. The removed {} block (new in 004)

Sample question. You want to remove a resource from your Terraform configuration without destroying the underlying infrastructure. What's the cleanest way?

  • A) terraform state rm aws_instance.legacy
  • B) Comment out the resource block
  • C) Add a removed {} block with lifecycle { destroy = false }
  • D) Delete the resource block and run apply

Wrong-answer magnet: A. Works, but again — invisible to other engineers.

Right answer: C. The removed {} block (Terraform 1.7+) is the declarative way to remove a resource from state without destroying it.

removed {
  from = aws_instance.legacy
  lifecycle {
    destroy = false
  }
}

If lifecycle { destroy = false } is omitted, Terraform will destroy the resource on the next apply. Don't forget the lifecycle block — that's the question's trap.

Rule: removed {} removes from state; lifecycle { destroy = false } is what makes it non-destructive.

8. terraform import block vs. CLI

Sample question. Which is true about the import {} configuration block (Terraform 1.5+)?

  • A) It replaces the terraform import CLI command, which is now deprecated
  • B) It allows planning the import as part of terraform plan before any state changes
  • C) It can only be used once per resource
  • D) It requires the resource to already exist in the state file

Wrong-answer magnet: A. The CLI is not deprecated. Both coexist.

Right answer: B. The killer feature of the import block is that it's planable — you see the import as part of terraform plan output and can review it before applying. The CLI command imports immediately with no preview.

import {
  to = aws_instance.web
  id = "i-0abc123def456"
}

resource "aws_instance" "web" {
  # ... config that matches the existing instance
}

Rule: Use the import {} block for anything you'll review in PR. Use the CLI for one-off, throwaway imports.

9. Provisioners — when (almost never) to use them

Sample question. Per HashiCorp's official guidance, when should you use a provisioner block?

  • A) For configuration management (installing packages, copying files)
  • B) Whenever cloud-init or user data isn't sufficient
  • C) Only as a last resort, when no other option exists
  • D) Whenever you need to run a script after resource creation

Wrong-answer magnet: D. Provisioners can do this, so people assume they should.

Right answer: C. The official docs are explicit: provisioners are a last resort because they don't show up in plan output, can leave resources in inconsistent states on failure, and tightly couple Terraform to imperative scripts. Prefer cloud-init / user data, or post-deployment configuration tools (Ansible, Chef, custom AMIs baked with Packer).

Rule: If the question mentions provisioners, the answer almost certainly involves not using them.

10. terraform workspace vs. directory-per-environment

Sample question. Your team manages dev, staging, and prod environments. Which of the following best describes the recommended pattern?

  • A) Use terraform workspace new dev, staging, prod against a single configuration
  • B) Use a separate directory (or branch) per environment with its own state file
  • C) Use a single state file with a var.environment variable
  • D) Either A or B is acceptable depending on team conventions

Wrong-answer magnet: A. CLI workspaces are easy to demo, so they look like the right answer.

Right answer: D, but with a strong lean toward B for production environments. CLI workspaces share the same configuration — meaning a typo in main.tf affects all three environments simultaneously. Directory-per-environment isolates blast radius and is the pattern HashiCorp recommends for production. CLI workspaces are fine for ephemeral or feature-branch environments.

Rule: Workspaces ≠ environments. They're a state-file isolation primitive that can be used for environments but isn't the recommended way for prod.

What I'm Doing Differently for the Real Exam

Concrete changes for Day 29's third practice exam and the certification attempt that follows:

  • Spend 30 minutes per day in the docs, specifically on the State, CLI, and Configuration syntax sections. These map directly to my weak domains (4, 7, 8).

  • Build one example for every 004-new feature. A throwaway directory with a moved {} block, a removed {} block, an import {} block, and a check {} block.

  • Re-do exam #1 cold in three days. If I land in the same place as the first attempt, I haven't actually learned anything from the review.

  • Time-box the review loop too. No more than 30 minutes per exam — otherwise it bleeds into "infinite study" and I never schedule the real test.

  • Schedule the actual exam. Nothing focuses preparation like a $70 deadline on the calendar.

Where I Am At

The real takeaway from Day 28 isn't a number on a results page — it's that practice exams are a diagnostic, not a study technique. The hour you spend taking the exam is worth maybe 10% of the value; the 30 minutes of structured review afterward is worth the other 90%.


This post is part of a 30-day Terraform learning journey.

Share This Article

Did you find this helpful?

💬 Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

Get In Touch

I'm always open to discussing new projects and opportunities.

Location Yassa/Douala, Cameroon
Availability Open for opportunities

Connect With Me

Send a Message

Have a project in mind? Let's talk about it.