plan, apply and reading a diff carefully
Terraform's day-to-day workflow is a short cycle of commands, and the most important of them is plan —
because it shows you exactly what Terraform is about to do to your infrastructure before it does it. On real
infrastructure, reading that plan carefully is the difference between a safe change and an accidental outage.
This lesson is the Terraform workflow — init, plan, apply, destroy — and, above all, how to read a plan.
The core workflow
Four commands cover almost everything, run from your configuration directory:
terraform init # download providers, set up the working directory (run once, and after adding providers)
terraform plan # show what WOULD change — a dry run, changes nothing
terraform apply # actually make the changes (shows the plan again, asks you to confirm)
terraform destroy # tear down everything this configuration manages
The verified cycle for the example configuration: init downloaded the providers ("Terraform has been
successfully initialized"), plan showed "Plan: 2 to add", apply created them ("Apply complete! Resources: 2
added"), and destroy removed them ("Destroy complete! Resources: 2 destroyed"). That loop —
init once, then plan/apply as you change things — is the whole workflow.
terraform plan: the dry run that saves you
terraform plan is Terraform's superpower. It compares your configuration (desired) with the state and
real infrastructure, and prints exactly what it would do to reconcile them — without changing anything. You
read it, confirm it matches your intent, and only then apply. Reading the plan is a core operational skill,
because it is your last chance to catch a mistake before it hits real infrastructure.
A plan marks each change with a symbol, and you must know them:
+— a resource will be created.-— a resource will be destroyed. (Watch these closely.)~— a resource will be changed in place (an attribute updated).-/+— a resource will be destroyed and recreated (a "replacement"). This is the dangerous one: some changes cannot be made in place, so Terraform destroys and recreates — which, for a database or a server, can mean data loss or downtime.
The verified plan showed + for the two new resources and Plan: 2 to add, 0 to change, 0 to destroy — the
summary line you read first. On real infrastructure the summary and the symbols are what you scrutinise.
Reading a plan carefully: the habit that prevents outages
Here is the discipline that separates a safe engineer from a reckless one. Never apply without reading the
plan, and specifically:
- Check the summary line — "X to add, Y to change, Z to destroy". If you expected to change one thing and it says "5 to destroy", stop — something is wrong (a wrong variable, the wrong workspace, a typo).
- Scrutinise every
-(destroy) and-/+(replace). A destroy or replacement of a database, a disk, or a stateful resource can lose data or cause downtime. Ask: is this destruction intended? A plan that unexpectedly wants to replace your production database is a disaster you catch here, in the plan, not after. - Save the plan for apply. In automation you run
terraform plan -out=tfplanand thenterraform apply tfplan, so apply does exactly what you reviewed — nothing can change between plan and apply.
The rule to carry: the plan is a contract you review and approve; apply only executes what you already read. Most Terraform disasters are someone applying without reading the plan and destroying something they did not mean to. The plan told them; they did not look.
plan and apply in CI/CD
This workflow fits directly into a pipeline (the CI/CD module), and real teams wire it up so infrastructure changes are reviewed like code:
- On a pull request, CI runs
terraform planand posts the plan as a comment — so reviewers see exactly what the change will do to infrastructure before approving. The plan becomes part of code review. - On merge to main, CI runs
terraform apply(often the saved plan) to make the change. - State lives in a remote backend with locking (the state lesson), so the pipeline and people share one state safely.
This is IaC realised end to end: an infrastructure change is a PR, its plan is reviewed, and merging applies it — versioned, reviewed, automated, exactly like application code. It is also why reading a plan matters even more in a pipeline: the plan in the PR is what the reviewer approves.
Idempotency: apply is safe to re-run
A reassuring property: Terraform is idempotent. If you apply and nothing in your config changed, Terraform
does nothing ("No changes. Your infrastructure matches the configuration") — it only acts on the difference
between desired and actual. So running apply twice is safe; the second run is a no-op. This is the desired-state
model paying off: Terraform always moves toward the declared state and stops when it is there, so you can re-run
without fear of duplicating resources. (Run the example's plan again after apply and it reports no changes —
verified behaviour.)
Check your work
Workflow: init (download providers — once, and after adding providers) → plan (dry run, changes
nothing) → apply (make changes, confirm) → destroy (tear down). Verified: init → "2 to add" → "2 added" →
"2 destroyed".
plan is the superpower: it shows exactly what would change without changing anything — your last chance
to catch a mistake. Symbols: + create, - destroy (watch these), ~ change in place, -/+
destroy-and-recreate (dangerous — can mean data loss/downtime). Read the summary line first ("X add, Y
change, Z destroy").
Read carefully (prevents outages): if the summary is not what you expected, stop; scrutinise every - and
-/+ (a replaced database loses data); plan -out=tfplan then apply tfplan so apply does exactly what you
reviewed. The plan is a contract; apply only executes it. Most disasters are applying without reading.
In CI/CD: PR runs plan (posted as a comment — reviewed like code); merge runs apply; remote state with
locking shared by pipeline and people. Infra change = a reviewed PR.
Idempotent: apply with no config change = no-op ("No changes"); Terraform acts only on the diff, so re-runs are safe.
Practice
- Run the full cycle on the example config:
init,plan,apply, thendestroy; read each summary line. - Explain what
terraform plandoes and why it is safe to run any time. - Identify what
+,-,~and-/+mean in a plan, and which two you scrutinise most and why. - Describe how you would react to a plan that says "3 to destroy" when you expected one small change.
- Explain how
planandapplyfit into a CI/CD pipeline and why the plan is posted on the PR. - Explain Terraform's idempotency and why running
applytwice does not create duplicate resources.
Official documentation
- Terraform — terraform plan — The dry run and how to read it.
- Terraform — terraform apply — Applying changes and saved plans.
- Terraform — Core workflow — Write, plan, apply as a loop.
Next: modules and structuring a repository.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship