Provider
A plugin that knows how to talk to a specific API — AWS, GCP, Azure, Datadog, GitHub. Every resource block belongs to one.
Lesson 3 of 4
Someone hand-edited a resource in the console, and now the next plan wants to destroy it. Knowing why that happens is most of what IaC fluency actually is.
A script describes steps; a declarative config describes an end state — and the tool figures out the steps to get there.
An imperative script ("create this, then attach that") has to account for every possible starting state to stay correct. A declarative tool like Terraform instead compares your config against its state — its record of what it last created — and computes only the changes needed to close the gap. When reality (the actual cloud resources) no longer matches either the config or the state, that mismatch is called drift, and it's the single most common source of Terraform surprises.
Four terms cover most of what you'll need to read someone else's config or plan output.
A plugin that knows how to talk to a specific API — AWS, GCP, Azure, Datadog, GitHub. Every resource block belongs to one.
A single piece of managed infrastructure — an EC2 instance, an S3 bucket, a DNS record — declared, not scripted.
Terraform's record of what it last created, mapping your config to real-world resource IDs. Losing or corrupting it is one of the most common ways teams get hurt.
`plan` shows what would change without touching anything; `apply` actually makes the change. Never skip reading a plan you didn't write yourself.
Same underlying idea, three different authoring experiences and levels of vendor lock-in.
Cloud-agnostic, HCL syntax, the most widely adopted — the safe default when a job description just says "IaC."
The same declarative model, but written in a real programming language (TypeScript, Python, Go) instead of HCL.
AWS-native, JSON/YAML — no separate state file to manage since AWS tracks it, but locked to one provider.
Look at the sanitized plan output below, then work through both exercises.
$ terraform plan
# aws_instance.web must be replaced
-/+ resource "aws_instance" "web" {
~ ami = "ami-0a1b2c3d4e5f6g7h8" -> "ami-0z9y8x7w6v5u4t3s2" # forces replacement
id = "i-0abc123def456"
instance_type = "t3.micro"
tags = {
"Name" = "web-server"
}
}
Plan: 1 to add, 0 to change, 1 to destroy.Answer in your head first, then click a question to reveal the answer.
Work through the sample plan output and check each item off. Progress is saved in your browser.
These primers are a starting point. Read the primary sources to build real fluency.
What building this project taught me.
Infrastructure as Code isn't a separately flagged gap, but it's the natural follow-on to Cloud Platforms & Core Ops — reading a plan diff assumes the vocabulary (compute, DNS, networking) from that lesson.
Real Terraform plan output includes far more noise — provider metadata, computed fields — that is rarely relevant to the actual question of what is changing and why.