Reviewing infrastructure changes
🎯You'll be able to
Run plans in pull requests, apply exactly the plan that was reviewed, and add automatic checks that catch dangerous or non-compliant changes.
🏠The everyday picture
Before a bank transfer above a limit goes out, a second officer checks the details on the form and signs. The transfer that goes out is the one on the signed form, not a new one typed again later.
📘What it really is
- The pull request flow:
- someone changes
.tffiles on a branch and opens a pull request; - CI runs
terraform fmt -check,terraform validateandterraform plan, and posts the plan summary on the pull request; - a reviewer reads the plan, not only the code. "3 to destroy" in a plan deserves questions;
-
after approval and merge, the pipeline applies.
-
Apply what was reviewed:
terraform plan -out=tfplansaves the plan;terraform apply tfplanapplies exactly those changes. If state has changed since (someone else applied), Terraform refuses the stale plan, and you plan again. -
Automatic checks on every plan or file:
- linters such as TFLint catch mistakes and deprecated settings;
- security scanners such as Checkov and Trivy flag open firewall rules, unencrypted storage and public buckets;
- policy tools (Open Policy Agent with Conftest, HCP Terraform's Sentinel) read
terraform show -json tfplanand can fail a run, for example "no plan may destroy a database" or "every resource must have an owner tag". - Tools that run Terraform from pull requests: Atlantis (self-hosted), HCP Terraform, Spacelift, or plain GitHub Actions (CD7).
- Who may apply production? Ideally only the pipeline, using credentials that people don't have day to day, with a person's approval in the pipeline (GitHub environments, CD7).
📝A worked example
Input: in the finished kit, run terraform plan -out=tfplan -var app_count=3, then terraform show -json tfplan > plan.json and
node -e "const p=require('./plan.json'); console.log(p.resource_changes.filter(r => r.change.actions.includes('delete')).map(r => r.address))".
Expected output: the printed list shows the resources the plan would delete, here none (the third copy is only added). terraform apply tfplan
then applies exactly that. Running terraform apply tfplan a second time fails because the saved plan is now stale. This is the idea behind
a policy check that stops plans which delete something important.
🌍Where it's used
- Regulated companies (banks, insurers, hospitals) must show that every production change was reviewed and approved.
- Large platform teams block plans that open SSH to the internet or create unencrypted storage.
- Change logs: the pull request, its plan and its approval form the record of each change.
📝Case scenario
A logistics company let engineers apply from laptops after a quick code review. A reviewer approved a one-line change to a subnet's address range; nobody looked at the plan, which replaced the subnet and every server in it. Afterwards, plans ran in pull requests, any plan with deletions needed a second reviewer, and only the pipeline could apply to production.
🖱️Try it
Save a plan, apply it, then try to apply the same file again. Then add -var app_count=1 to a new plan and run the delete-listing command.
Success: you see the stale-plan refusal, and the second list shows the copies that would be removed.
⚠️Common mistakes
- Reviewing code, not the plan. Sign: "the change was one line" after a large outage. Fix: post the plan on the pull request and read it.
- Planning again at apply time. Sign: what was applied differs from what was approved. Fix: save the plan with
-outand apply that file. - Everyone can apply prod. Sign: production changes that skipped review. Fix: apply prod only from the pipeline, with approval.
🛠️For your project
Project 2's workflow checks formatting and validity in pull requests. As a stretch, add a plan step and a check that fails if the plan deletes the database.
✅Quick check
What does terraform apply tfplan add over a plain apply?
Show the answer
It applies exactly the saved, reviewed plan, and refuses if state has changed since.
Name one kind of automatic check for infrastructure changes.
Show the answer
A linter (TFLint), a security scanner (Checkov, Trivy) or a policy check (OPA, Sentinel).
