Skip to content

Why Infrastructure as Code

The overview made the case that building infrastructure by clicking through a console is a trap. This page makes the positive case: what you actually gain once infrastructure lives in a repo. There are five payoffs, and they all flow from one idea — infrastructure you can rebuild from a repo. Hold that sentence; everything else is a consequence of it.

When a VM is the output of terraform apply on a committed file, you can produce that exact VM again — next week, in another region, in a fresh account — by running the same command. Environments stop being snowflakes.

This is the cure for the oldest line in operations: “works on staging.” Staging and production drift apart because they were built at different times by different hands. When both are built from the same code, with only a variable like instance_count differing, the difference between them is visible in the diff instead of hiding in someone’s memory. A bug that “only happens in prod” almost always traces back to an environment difference — and reproducible infrastructure makes those differences impossible to hide.

Infrastructure-as-text means infrastructure gets everything Git already gave your application code:

Git capabilityWhat it means for infrastructure
History (log)A complete record of every change to the platform, ever
Blame”Who opened port 22 to the world, and in which commit?” — answerable
DiffSee exactly what a change will alter before it happens
BranchExperiment with a new network layout without touching prod
RevertRoll back a bad infrastructure change like any other commit
TagPin “the infra that shipped with release 2.4”

Before IaC, the answer to “when did this firewall rule change?” was a forensic dig through console audit logs, if they existed at all. After IaC, it’s git log. The platform gains an honest, queryable history.

Because a change is a diff in a pull request, infrastructure changes go through the same review gate as code. A second engineer reads the diff before it touches reality. Opening a security group to 0.0.0.0/0, deleting a database, resizing a production cluster — all of it surfaces as reviewable text, not a private action someone took in a console at 2 a.m.

Without IaC With IaC
───────────────── ─────────────────────────────
engineer clicks in console engineer opens a pull request
change is live instantly reviewer reads the diff
first review is the outage plan shows what will change
merge → pipeline applies it

This is shift-left applied to infrastructure: catch the mistake while it’s still text, where it’s cheap, instead of in production, where it’s an incident.

Drift is the gap between what your code says should exist and what actually exists — usually because someone made a manual “quick fix” in the console. Drift is corrosive: it silently breaks the promise that your repo describes reality, so reproducibility and disaster recovery quietly stop working.

IaC tools fight drift directly. Running a plan (covered in State & Drift) compares code to reality and reports the difference; re-applying brings reality back in line with code. The code becomes the single source of truth, and any divergence becomes visible and correctable rather than a hidden landmine.

This is the payoff that makes engineers true believers. A region goes dark. An account is compromised and must be abandoned. A junior engineer runs a delete they shouldn’t have. With ClickOps, recovery means rebuilding from memory under maximum pressure — the worst possible time to be remembering checkboxes.

With IaC, recovery is a command:

Terminal window
# Point at a fresh region/account and rebuild the entire platform
terraform apply -var="region=us-west-2"

Your infrastructure is re-derivable from text you already have in Git. The repo isn’t documentation of how the platform was built — it is the platform, in latent form. That turns a multi-day, heroics-driven catastrophe into a routine, tested procedure. (It connects directly to Multi-Region & Disaster Recovery, where rebuildability is the whole game.)

The manual, error-prone step IaC removes is the broadest one in this book: building and changing infrastructure from human memory and human clicks. Every payoff above is a face of that single removal. Reproducibility, version control, review, drift elimination, and disaster recovery are not five separate features — they’re five things that become automatically true once infrastructure is text that a tool applies.

And production gets safer in a very concrete way: a reviewed, version-controlled, drift-checked platform that you can rebuild on demand has a dramatically smaller blast radius when something goes wrong. The mistake is caught in review; the divergence is caught in plan; the disaster is recovered with apply. That’s the safety dividend. Next, the design decision that makes it all robust: Declarative vs Imperative.

Five questions for the decision to put infrastructure in code at all:

  • Why does it exist? Because infrastructure built by hand can’t be reviewed, reproduced, or rebuilt — everything here flows from one idea: infrastructure you can rebuild from a repo.
  • What problem does it solve? ClickOps’s failures in one move — it buys reproducibility (no more “works on staging”), git history and blame, pull-request review, drift detection via plan, and disaster recovery as a single apply.
  • What are the trade-offs? “Same code in, same infrastructure out” only holds if you pin every input — provider versions, the .terraform.lock.hcl, exact AMI IDs; float them and reproducibility silently becomes a hope (the mutable-tag problem again).
  • When should I avoid it? A genuine one-off experiment or a throwaway learning sandbox — ClickOps is fine when nothing has to survive, scale, or be rebuilt.
  • What breaks if I remove it? Recovery becomes rebuilding from memory under pressure, “who opened port 22?” becomes a forensic dig through console logs, and staging and prod quietly diverge until a bug “only happens in prod.”
  1. All five benefits of IaC flow from one sentence. What is it, and why is it the root of the others?
  2. “Works on staging” is a perennial ops complaint. Explain mechanically how reproducible infrastructure makes the staging/prod difference visible instead of hidden.
  3. Pick three Git capabilities and describe what each one concretely lets you do once your infrastructure is text.
  4. Define drift in your own words. What is the single most common way it’s created, and how does an IaC plan help?
  5. Walk through disaster recovery with and without IaC. Why does IaC turn a catastrophe into a routine procedure?
Show answers
  1. Infrastructure you can rebuild from a repo. It’s the root because every other payoff — reproducibility, version control, review, drift elimination, disaster recovery — is just a consequence of infrastructure being text that a tool applies, rather than clicks no one can replay.
  2. When both staging and prod are built from the same code with only a variable (like instance_count) differing, any difference between them shows up in the diff instead of hiding in someone’s memory. A bug that “only happens in prod” almost always traces to an environment difference that reproducible infra makes impossible to hide.
  3. Any three, e.g.: history — a complete, queryable record of every platform change; blame — answer “who opened port 22 to the world, in which commit?”; diff — see exactly what a change will alter before it happens; revert — roll back a bad infra change like any other commit; branch — try a new network layout without touching prod.
  4. Drift is the gap between what your code says should exist and what actually exists. The most common way it’s created is a manual “quick fix” in the console during an incident. An IaC plan compares code to reality and reports the difference, so the divergence becomes visible and correctable instead of a hidden landmine.
  5. Without IaC, recovery means rebuilding from memory under maximum pressure — remembering every checkbox at the worst possible time. With IaC, recovery is a command (terraform apply pointed at a fresh region/account): the platform is re-derivable from text you already have in Git, which turns a multi-day heroics-driven catastrophe into a routine, tested procedure.