Infrastructure as Code

Clicking through a cloud console to set up infrastructure is fast, fun, and a disaster you'll regret — because nobody can reproduce it, review it, or remember what you did. Infrastructure as code turns your servers, networks, and databases into version-controlled, reviewable, reproducible code. It's the practice that makes infrastructure an engineering discipline instead of an artisanal craft.

The CI/CD pipeline deploys to infrastructure — and how you manage that infrastructure is the next foundational practice: Infrastructure as Code (IaC). Instead of manually configuring servers, networks, and cloud resources by clicking consoles or running ad-hoc commands, you define infrastructure in version-controlled code and apply it automatically. This makes infrastructure reproducible, reviewable, and automatable — and it’s what a platform uses to provision environments for developers. This post covers what IaC is, declarative vs imperative, key concepts (idempotency, state, drift), and why it matters.

The problem: manual infrastructure

The old way — click-ops — is setting up infrastructure by hand: clicking through a cloud console, SSHing into servers to configure them, running one-off commands. It works for a moment and fails as a practice, because manual infrastructure is:

Infrastructure as Code fixes all of this by making infrastructure code: you write the desired infrastructure in files, version-control them, and apply them with tooling. Infrastructure becomes reproducible (re-apply the code to get an identical environment), reviewable (it’s code, in git, code-reviewed), documented (the code is the documentation of what exists), and automatable (the pipeline applies it). This is the shift from infrastructure as artisanal craft to infrastructure as engineering.

Declarative vs imperative

There are two styles of IaC, and the declarative style dominates for good reason:

Declarative IaC (the dominant approach, used by Terraform, and Kubernetes manifests, CloudFormation, and others) is preferred because you describe the goal and the tool computes the actions:

Declarative (Terraform-style): "I want this VPC, these 3 instances, this database"
   → tool compares desired state to actual state → creates/updates/deletes to match

The advantage: you don’t have to script the steps or handle “does it already exist?” logic — you declare what you want, and the tool reconciles reality to match. This makes the code simpler (state, not procedure), naturally idempotent (below), and safe to re-run. The declarative model — desired state, tool reconciles — is central to modern infrastructure (and to GitOps, the next post). Some tools are imperative or hybrid, but declarative is the mainstream because “describe the destination, let the tool find the path” scales far better than scripting every step.

Key concepts: idempotency, state, drift

Three concepts define how IaC works in practice:

These three — idempotency (safe re-apply), state (track reality to compute changes), drift (reality diverging from code, prevented by all-changes-through-code) — are the mechanics you must understand to use IaC well. The overarching rule: the code is the source of truth; change infrastructure by changing the code, never by hand.

IaC in the pipeline and platform

IaC connects to the rest of the platform:

Infrastructure as code turns infrastructure into a version-controlled, reviewable, reproducible, automatable engineering artifact — the foundation the platform provisions and the pipeline deploys to. The next post covers the modern evolution of applying IaC: GitOps, where git becomes the operational source of truth and the system continuously reconciles reality to match it.

Key takeaways

Further reading

Sources & References

Declarative infrastructure as code