Infrastructure as Code in Practice
also called IaC
Defining infrastructure declaratively in version-controlled code so environments are reproducible, reviewable and auditable.
Definition
Infrastructure is described in files that are committed, reviewed and applied by automation. The running environment should be derivable from the repository, and any difference between them is drift to be reconciled.
What it actually buys
- Reproducibility. A new environment is an apply, not a fortnight of clicking.
- Review. An infrastructure change goes through the same scrutiny as a code change, which is the point where a wide-open security group gets caught.
- Audit. Version control answers "who changed this and why" without a ticketing archaeology exercise.
- Disaster recovery. Rebuilding a region is executing code rather than reconstructing knowledge from memory.
The practices that separate working IaC from a repository of aspirations
- No console changes, ever. One manual fix during an incident, never reconciled, and the code no longer describes reality. Detect drift automatically and treat it as a defect.
- Remote state with locking. Two engineers applying concurrently against local state is how infrastructure gets destroyed.
- Modules with narrow interfaces, so a team provisions a compliant database by calling a module rather than by copying 200 lines of someone else's configuration.
- Plan output reviewed in the pull request, so the reviewer sees what will actually change rather than inferring it from the diff.
- Policy as code in the pipeline — no public storage buckets, encryption required, mandatory tags — so compliance is enforced rather than requested.
- Separate state per environment and per blast radius. One enormous state file means every change risks everything and every apply takes twenty minutes.
Industry example
Organisations running large fleets with small platform teams — Shopify's pod-based partitioning is a clear example — depend on this absolutely: standing up another complete self-contained partition has to be a parameterised, repeatable operation rather than a project. When the scaling unit is an entire environment, the ability to create one reliably is the scaling mechanism.
That reframes IaC from hygiene to architecture. A design whose scaling strategy is "add another cell" is only viable if creating a cell is code.
Failure scenarios
- Drift, unmonitored, until an apply reverts a manual fix and causes an outage.
- A monolithic state file, so blast radius is the entire estate.
- Secrets committed to the repository, or state files containing them stored without encryption.
- Copy-paste per environment, so production and staging diverge in ways nobody can enumerate.
- Destructive changes not caught in review, because nobody read the plan and a resource replacement recreated a database.
Trade-offs
Bought: reproducibility, reviewability, auditability, and disaster recovery that works. Sold: speed of ad-hoc change, a learning curve, and a new class of failure where the automation itself is the outage. Both halves are real, and the second is why plan review and staged rollout matter as much for infrastructure as for code.
Interview question
"Someone made a manual change in the console during an incident. What should happen next, and what should have prevented it?"