Module 08 of 12
Infrastructure as Code — the Mindset, Not the Syntax
"It works on my machine" isn't a technical excuse. It's a confession that your infrastructure isn't actually known or repeatable.
Picture a server that's been running for three years. It was set up by an engineer who has since left the company. Over time, half a dozen people have SSH'd into it to fix things — installed a missing library here, tweaked a config file there, applied a manual patch during an incident at 1 AM and never wrote down what they changed. Nobody currently at the company could tell you, with confidence, exactly what state that server is in or how to recreate it from scratch. This kind of server has a name in DevOps circles: a "pet." You know it by name, you nurse it back to health when it's sick, and if it dies, you're in real trouble, because nobody knows exactly how to bring it back to life.
Infrastructure as Code (IaC) is the practice of describing your servers, networks, and configuration in files — code — that get checked into version control, reviewed, and applied through an automated tool, rather than configured by hand. But the tools (Terraform, Ansible, CloudFormation, Pulumi — brief intros in the tooling module) are just the mechanism. The mindset underneath is what actually matters, and it has a memorable shorthand: treat servers like cattle, not pets.
Cattle, not pets
A pet is unique, hand-raised, and irreplaceable — you'd never casually destroy one and expect no consequences. Cattle, in this metaphor, are numbered, identical, and replaceable: if one gets sick, you don't nurse it for three days, you replace it with an identical one and move on. Applied to infrastructure: if a server is described entirely by code, you can destroy it and recreate an exact replacement in minutes, with total confidence it will behave identically, because nothing about it depends on undocumented manual steps someone did once and forgot to write down.
The real test of Infrastructure as Code isn't whether your infrastructure is described in a file. It's whether you'd be comfortable deleting a production server right now, confident that running the code would bring it back exactly as it was.
Why this matters beyond convenience
It's tempting to file IaC under "nice automation that saves typing." That undersells it. Treating infrastructure as code changes several things that connect directly back to earlier modules:
- Reproducibility becomes a fact, not a hope. "It works on my machine" stops being a valid excuse, because if the infrastructure is code, the same code produces the same environment everywhere — locally, in staging, in production — closing exactly the kind of environment-mismatch gap that contributed to the Knight Capital incident in Module 7 (their staging environment didn't mirror all eight production servers).
- Changes become reviewable. A pull request that modifies a Terraform file can be read, discussed, and approved by a teammate before it touches anything real — the same code-review feedback loop from Module 4, now applied to infrastructure instead of just application code.
- Changes become auditable and reversible. Because every change to infrastructure is a commit in version control, you can see exactly what changed, when, and by whom, and — critically — you can revert it, the same way you'd revert a bad application code change, instead of trying to manually undo an ad hoc server tweak nobody wrote down.
- Disaster recovery stops being theoretical. If a whole environment can be destroyed and rebuilt from code, "what happens if we lose this data center" has a tested, concrete answer instead of a hopeful one.
Configuration drift: the problem IaC is really solving
The specific failure mode IaC targets has a name: configuration drift — the slow, invisible process by which a server's actual state diverges from what anyone believes it to be, one small manual change at a time. No single manual fix during an incident feels reckless in the moment; each one is a reasonable, local decision made under time pressure. But six months and a dozen such fixes later, the server is now a unique, undocumented snowflake that no one fully understands — a pet, created by an accumulation of individually-reasonable manual actions. IaC prevents drift not by making people more disciplined, but by removing the manual path entirely: if the only way to change a server is by changing the code and re-applying it, there's no longer a side door for silent, undocumented drift to sneak in through.
The mindset shift, in one sentence
Stop asking "how do I fix this server" and start asking "how do I change the description of this server, so that fixing it is just re-applying the description." That single reframe — from imperative, one-off manual actions to declarative, version-controlled descriptions — is what separates infrastructure as code from just "using scripts sometimes." A folder full of ad hoc bash scripts that someone runs by hand, in whatever order they remember, is not infrastructure as code, even if every line of it is technically "code" — because it doesn't give you the reproducibility, reviewability, or drift resistance that's the actual point.
Think it through
Real situations, no single "correct" checkbox — reason about it first, then compare your thinking to ours.
Scenario 1
A team uses Terraform to define its cloud infrastructure, but during a recent incident, an engineer manually changed a firewall rule directly in the cloud provider's console to resolve the issue quickly, intending to "add it to the Terraform file later." Three weeks later, no one has updated the file, and a new engineer runs a routine Terraform apply, which reverts the firewall rule — reopening the original incident.
What went wrong here, and is this a tooling failure or a mindset failure?
Scenario 2
A company wants to move to Infrastructure as Code and starts by writing detailed shell scripts that SSH into each server and run a sequence of setup commands. The scripts work, and are stored in a Git repository.
Does storing scripts in Git make this "Infrastructure as Code" in the meaningful sense this module describes?
Check your understanding
Answer all questions, then submit to see explanations.
1. In the "cattle, not pets" metaphor, what makes a server a "pet"?
2. What is "configuration drift"?
3. According to this module, what is the real test of whether infrastructure is genuinely "as code"?
4. How does Infrastructure as Code connect to the Knight Capital case study from the previous module?