What is infrastructure as code?
Defining servers, networks, databases and everything else supporting an application in files that are version-controlled and executed, rather than configuring them by hand through a console or by following a document.
The problem it addresses: configuration drift. Manually configured environments diverge. Someone changes a setting to resolve an incident and does not record it; a staging environment was built six months after production from a document that was already out of date; nobody knows what is actually deployed. "It works in staging" becomes meaningless, and rebuilding after a failure becomes an archaeological exercise.
What defining it as code gives you:
Reproducibility. The same definition produces the same environment, repeatedly.
Version control. Changes are reviewed, attributed and reversible, with a history explaining why things are as they are.
Review. Infrastructure changes go through the same process as application changes, which catches errors before they reach production.
Disaster recovery. Rebuilding is running the definition, rather than remembering.
Documentation that cannot go stale, because the definition is the system.
The two approaches:
Declarative — you describe the desired state, and the tool works out what to change. Terraform, CloudFormation and Kubernetes manifests work this way. Generally preferred, because the definition describes what should exist rather than the steps taken.
Imperative — you specify the steps. Simpler to reason about for one-off actions, and harder to apply repeatedly.
Configuration management tools — Ansible, Chef, Puppet — sit alongside, configuring what is inside machines.
The concepts that matter:
Idempotency. Applying the same definition repeatedly produces the same result rather than compounding changes.
State. Declarative tools track what they created, so they know what to change. The state file is critical and is a common source of trouble — losing it, or two people applying simultaneously, causes real problems, which is why remote state with locking exists.
Immutable infrastructure, where servers are replaced rather than modified, which eliminates drift entirely.
The discipline required: manual changes must stop. One console change outside the definition reintroduces drift, and the tool will either revert it unexpectedly or fail confusingly.
Secrets do not belong in the repository, and need a secrets manager.