Hedronite · Cert Lesson · Cert-Prep/HashiCorp · Associate 003 + Pro-depth · Sprint Day 21 · Wed 2026-08-12 · Trio #87

TF Associate 003 — IaC Concepts, Terraform's Purpose, and the Execution Graph — objectives 1 and 2, and the last two on the arc

The two objectives that read like preamble are the ones whose wrong answers come from the tools next door.

Lesson Class: Cert (HashiCorp — Terraform Authoring & Operations Associate 003)
Sprint Track: TF — Deep Terraform, day 21, seventh TF visit
Objectives: 1 — IaC concepts · 2 — the purpose of Terraform vs other IaC
Blueprint Coverage: 9 of 9 objectives now open on this arc
Paired Ops: Terraform's Resource Lifecycle on AWS
Paired Dev: Terratest Under Change (Go)
Grounding: Brikman TU&R 3ed Ch.1 pp.33-56 · Ch.2 pp.107-110 · tfpro-labs 01
Practice Questions: 6 — tap to reveal
The code is the record
Nothing stops an engineer opening the console. What IaC claims is that when they do, the files are now wrong, and being wrong is detectable.
Configure, or create
Configuration management configures a machine that exists. Provisioning creates the machine. The tell is what each does when pointed at something that already looks right.
The graph is the program
Edges come from references, never from declarations. Destroy walks it backwards. Parallelism defaults to ten.
Why is Terraform declarative? Because it keeps a record of what it made, and a tool with a record can tell the difference between four and four more.

TF Associate 003 — IaC Concepts, Terraform's Purpose, and the Execution Graph

Section IFrame

Seven cert lessons on this arc have opened seven objectives. State, backends, the core workflow, modules, providers, HCP Terraform, testing and validation, state manipulation, sensitive values. All the machinery.

Two objectives were skipped every time, and they sit at the top of the blueprint: understand infrastructure as code concepts, and understand the purpose of Terraform against other IaC tools. They read like the throat-clearing before a course starts.

They are not, on the exam. Objectives 1 and 2 carry question weight, and the questions are built to be missable by a candidate who can write a module and has never had to say what category of tool Terraform belongs to. The wrong answers on those questions are drawn from the tools next door: Ansible, Chef, Packer, Docker, CloudFormation, Pulumi. A candidate who has only ever used Terraform has no vocabulary to separate them.

This lesson closes both. Blueprint coverage after it stands at nine objectives of nine.

Section IIObjective 1: What Infrastructure as Code Actually Claims

The claim in one sentence

Infrastructure as code means the infrastructure is defined in files, the files are the source of truth, and changes reach the world by changing the files.

The consequence that matters is the second clause. Nothing prevents an engineer from opening the AWS console and clicking. What IaC claims is that when they do, the files are now wrong, and being wrong is detectable. The code is the record. A console change is not a fifth way of doing the work; it is drift against the record.

Brikman lists five benefits and they are worth having in the order he gives them: self-service, speed and safety, documentation, version control, validation and reuse (Ch. 1, pp. 49-50). Documentation is the one candidates undervalue and the one exam writers like, because the configuration is not a description of the system that can rot separately from the system. It is the system's definition.

Four categories of tool, and the word that hides them

The exam wants a candidate who can place tools in categories. Brikman gives five; four of them appear in questions.

Category What it produces Examples
Ad hoc scripts Whatever the author wrote, in whatever order Bash, Python, PowerShell
Configuration management A configured server, from an existing server Ansible, Chef, Puppet, SaltStack
Server templating An image, built once, deployed many times Packer, Docker, Vagrant
Provisioning Infrastructure itself, from the cloud API Terraform, CloudFormation, Pulumi, OpenTofu

Say the distinction plainly: configuration management configures a machine that exists; provisioning creates the machine. Ansible installs nginx on a server. Terraform creates the server for Ansible to configure. Packer bakes an image so that neither has to install nginx at boot.

The category boundary is not a wall, and the exam does not pretend it is. Ansible can create EC2 instances; Terraform can run a provisioner that installs a package. The question to answer is what the tool is for, and the tell is what the tool does when it is pointed at a machine that already looks right. Configuration management converges it. Provisioning compares it to a recorded state and reports the difference.

Brikman is direct about the practical pairing, and it is the answer most likely to be the correct one on a scenario question: use a provisioning tool for the infrastructure and a server templating tool for the images, and reach for configuration management only where the fleet is mutable by design (Ch. 1, pp. 33-34 and pp. 46-47).

Mutable and immutable

The distinction runs underneath every category above. Mutable infrastructure means a server is upgraded in place: the machine that ran version 3 now runs version 4, and its history is whatever happened to it. Immutable means the machine that ran version 3 is destroyed and a machine built for version 4 replaces it.

Configuration management is native to the mutable model. Server templating plus provisioning is native to the immutable one. Brikman names the failure mode of the mutable model as configuration drift, where the fleet diverges because each server accumulated a slightly different history of upgrades (Ch. 1, p. 56).

Two things to carry into the exam room. Terraform's default replacement behavior is immutable, which is why the day's Ops lesson had to work so hard to keep a service up during a replacement. And immutable is a claim about servers rather than about state files; the state file is mutable by definition, and it is the one thing in the system that records history.

Declarative and imperative

An imperative tool is told the steps. A declarative tool is told the result.

Terraform is declarative. The configuration says there are four instances of this shape, and Terraform works out whether that means creating four, creating one more, destroying two, or doing nothing. A Bash script that creates four instances, run twice, creates eight.

The property this buys is idempotence: applying the same configuration to the same world twice produces the world once. This is exactly the claim the day's Dev lesson turns into a test assertion, and it is worth noticing that the property has to be tested rather than assumed, because a configuration can be written that never settles.

Section IIIObjective 2: The Purpose of Terraform

What Terraform is for

Terraform provisions infrastructure across many providers from one declarative language, and records what it created in a state file so that the next run knows what already exists.

The state file is the answer to more exam questions than any other single fact in this objective. It is what makes the tool declarative in practice. Without it, Terraform would have to ask the cloud what exists and guess which of those things it owns.

Brikman's description of the mechanism is compact and worth reciting: Terraform reads the configuration, reads the state, queries the providers for real-world status, computes a diff, and executes the diff through provider API calls (Ch. 1, pp. 51-52). Five steps. The plan is step four made visible.

Terraform against the neighbours

Tool Category Scope Language State
Terraform Provisioning Multi-cloud, any provider HCL, declarative Explicit state file
CloudFormation Provisioning AWS only YAML/JSON, declarative Managed by AWS, invisible
ARM / Bicep Provisioning Azure only JSON / Bicep DSL Managed by Azure
Pulumi Provisioning Multi-cloud General-purpose languages Explicit state
Ansible Config management Any host YAML, procedural-ish Stateless, converges
Chef / Puppet Config management Any host Ruby DSL Agent-reported

Two rows carry the exam weight.

CloudFormation is the cloud-native comparison, and the distinction that matters is not the language. It is that AWS holds the state and Terraform hands it to you. AWS holding it means no bucket to configure and no lock table to create. It also means no terraform state mv, no import into a file you can inspect, and no way to read what the tool believes without asking AWS. The 08-03 lesson on state manipulation only exists because Terraform's state is a file the operator can reach.

Ansible is the category comparison, and the tell is idempotence versus convergence. Ansible modules are written to be idempotent, and Ansible has no record of what it did last time. Point it at a fresh server and it configures it; point it at a configured one and it changes nothing. Terraform knows what it made, which is why it can destroy.

Why HCL rather than a programming language

Pulumi's pitch is that infrastructure should be written in TypeScript or Go, where loops, functions, and unit tests come free. The Terraform answer is that a domain-specific language constrains what can be expressed, and a constrained configuration is one a reader can predict and a policy engine can evaluate.

The 08-09 lesson is the practical version of that argument. A Sentinel or Rego rule reads a plan and decides. That works because the plan is a bounded, documented artifact rather than the output of arbitrary program execution.

Objective 2 also expects a candidate to know what HCP Terraform adds on top: remote state with locking, remote runs, a private module registry, policy enforcement, cost estimation, and workspace-level access control. The 07-28 and 08-09 lessons cover those in depth. For this objective, knowing the list is enough.

Section IVPro-Depth: The Execution Graph

The Associate objectives stop at Terraform builds a dependency graph. The Professional exam expects more, and the day's Ops lesson makes no sense without it.

The graph is derived from references

Terraform builds a directed acyclic graph where nodes are resources, data sources, providers, and outputs, and edges come from references between them. Write vpc_id = aws_vpc.main.id and the edge is created. No author declares it.

Brikman demonstrates this with a security group and an instance in the first working example, and the demonstration is the point: the dependency is a consequence of using a value, not of announcing an intention (Ch. 2, pp. 107-110). The graph is the program. The configuration is a set of declarations; the graph is what actually runs.

terraform graph prints it in DOT format, which is the exam-answerable command.

What the graph gives you

Order on create: dependencies first. Order on destroy: the graph reversed, dependents first. Parallelism: any two nodes with no path between them are walked concurrently, ten at a time by default, tunable with -parallelism=n.

That default is worth knowing for two reasons. It is a common question, and it is the first thing to lower when a provider starts returning rate-limit errors on a large apply.

depends_on and where it belongs

depends_on adds an edge the references did not create. It is for hidden dependencies: an IAM policy attachment that must land before an instance can call an API, where no attribute of the policy appears in the instance's configuration.

The discipline is to use it rarely. An edge added by hand is an edge that stays after the reason for it is gone, and a graph with hand-added edges serializes work that could have run in parallel. Prefer restructuring the configuration so the reference exists.

Where lifecycle sits in the graph

The day's Ops lesson turns on this. create_before_destroy does not add or remove edges. It inverts the order of the two operations at a single node during a replacement, and Terraform then propagates that inversion to every node upstream in the dependency chain, because a dependent that still points at the old resource cannot be destroyed while the new one is being created.

The asymmetry is the exam-grade detail: the propagation travels toward dependents, never toward dependencies, and a resource with the flag depending on one without it produces a cycle error.

Section VPractice Questions

Question 1
A team runs Ansible playbooks against long-lived EC2 instances to keep packages current, and uses Terraform to create the instances. Which statement describes the categories correctly?
Tap to reveal
Terraform is a provisioning tool creating the infrastructure; Ansible is a configuration management tool configuring machines that already exist. The pairing is conventional. The fleet is mutable by design, which is the case where configuration management still earns its place.
Question 2
What does the Terraform state file provide that CloudFormation's managed state does not?
Tap to reveal
Direct operator access. Because the file is yours, terraform state list, state mv, state rm, import, and show -json all work against it. CloudFormation's state is held by AWS and cannot be inspected or surgically edited the same way. The tradeoff is that Terraform's state must be stored, locked, and protected, and CloudFormation's does not.
Question 3
A configuration applies cleanly. A second terraform plan immediately afterward shows a change. What does this indicate?
Tap to reveal
The configuration is not idempotent. Something is fighting: a computed attribute the configuration keeps overwriting, a provider normalization, or an externally-written value with no ignore_changes. A declarative tool should produce an empty plan against a world it just built.
Question 4
Which command prints the dependency graph, and what is the default parallelism during an apply?
Tap to reveal
terraform graph, output in DOT format. Default parallelism is 10 concurrent node operations, adjustable with -parallelism=n. Lowering it is the standard response to provider rate-limiting on a large apply.
Question 5
An IAM role policy attachment must exist before an EC2 instance boots, but no attribute of the attachment appears in the instance resource. What is the correct mechanism, and what is the cost?
Tap to reveal
depends_on on the instance, naming the attachment. The cost is a hand-maintained edge: it survives the reason for its existence, and it serializes work the graph would otherwise parallelize. Restructuring so a real reference exists is better where it is possible.
Question 6
Two engineers describe their approach. One rebuilds and replaces servers for every release. The other upgrades packages on the running fleet. Name the models and the failure mode of the second.
Tap to reveal
Immutable and mutable infrastructure. The mutable model's failure mode is configuration drift: each server accumulates a different upgrade history, so the fleet diverges and bugs stop reproducing across machines.

Section VIClosing

Objectives 1 and 2 are not warm-up. They are the vocabulary the rest of the blueprint assumes, and a candidate who cannot place Ansible, Packer, and CloudFormation on a category map will lose points on questions that have nothing to do with HCL.

Learn four categories and the one-line test that separates them. Learn the five-step mechanism: configuration, state, real-world query, diff, API calls. Learn that the graph comes from references, that destroy walks it backwards, that parallelism defaults to ten, and that create_before_destroy inverts an order at a node and propagates toward dependents.

Then read the day's Ops lesson again with the graph in mind, and notice that every rule in it follows from the shape of the graph rather than from Terraform's preferences.

Nine objectives of nine are now open on this arc. The work ahead is depth, not coverage.

Examine well.

Cross-ReferencesRelated

🫡 ⚖️ 📜
Leo.Syri — Praetor Consulate, Imperium Luminaura
Filed 2026-08-12 · Fajr trio #87 · sprint day 21 · TF track
Paired: 01-Earth-DevOps/Synthesis-Lessons/2026-08-12-terraform-resource-lifecycle-on-aws/ · Polyglot-Dev/Go/2026-08-12-terratest-under-change/