How to review infrastructure as code and config changes
Othman Shareef · August 21, 2026 · 6 min read · The Craft of Code Review
Every team has the story: a three-line YAML change sails through review with a thumbs-up in ninety seconds, and twenty minutes after deploy, production is down. Nobody was careless by their own standards. The reviewer applied the calibration that works for application code, where small diffs are usually safe diffs. To review infrastructure as code well, you have to unlearn that instinct, because in config the two are unrelated, and often inverted.
Why config diffs under-signal
Application code advertises its complexity. A 400-line refactor looks scary and gets attention; a two-line change to a values file looks trivial and gets a glance. But config is dense with leverage: one value in a base template is inherited by every environment and every service that extends it. Diff size is a terrible proxy for risk, which is the whole argument of reviewing by blast radius, and infra is where the mismatch is worst. The smaller and more central the file, the more it usually touches. A reviewer who spends ten minutes on a three-line Terraform change is not being slow. They are being calibrated.
Which environment does this actually hit?
The first question, and the one most often skipped. Overlays, inheritance chains, workspaces, and templating all mean the file path lies about the scope: a change to base/ hits everything that inherits from it, and a file named staging.yaml can feed a module that production also consumes. Make the author say it in the PR description: which clusters, which accounts, which stages this lands in. The postmortems where a staging tweak turned out to be global almost always contain a reviewer who assumed the filename was the answer.
A checklist to review infrastructure as code
- Environment scoping. Name every environment the change touches. If the author cannot enumerate them, that is the review finding.
- Implicit defaults. A provider bump or chart upgrade can change defaults underneath a file that did not change at all. If versions moved, ask what defaults moved with them.
- Secrets and permissions. Any widening of IAM roles, security groups, or service account scopes is a security review, not a config review. Treat a new
*in a policy as a finding until justified. - Plan output in the PR. Require
terraform plan,kubectl diff, or the equivalent as a PR artifact, generated by CI so it reflects real state. - Rollout and rollback story. How does this deploy, and does reverting the commit actually revert the change? Some infra changes are one-way doors the same way database migrations are: the revert is a second migration, not an undo.
The plan is the review artifact
The diff is what you wrote. The plan is what will happen, and they diverge constantly: state drift, module version bumps, and provider defaults all produce changes the diff never mentions. Reviewing a Terraform PR without plan output is reviewing a function by reading its name. The workable pattern is CI posting the plan into the PR on every push, so the reviewer reads intended edits and actual effects side by side. Read the plan with a simple priority: anything that destroys or replaces a resource first, permission changes second, everything else after. A plan that replaces a database to rename a tag is exactly the kind of thing the diff will never tell you.
AI wrote the YAML; who owns the why?
More and more infra is generated: an agent writes the Terraform, the human skims it, CI is green, merge. Osmani made the general argument that generation got cheap while understanding stayed expensive, and infra is where that gap bites hardest, because generated config looks authoritative while embedding defaults nobody chose. The instance size, the retention window, the ingress rule: were those requirements, or fill? The review has to distinguish the two, and the author has to capture the intent while it still exists. Six months from now, someone will stare at that retention value during an incident and need to know whether it was a decision or an accident. The PR is the only place that answer can live.
None of this makes config review slow. It makes it proportionate: ninety seconds was never the real cost of that three-line change, it was just the part paid before the incident.