Infrastructure as Code

The IaC landscape, declarative vs imperative, and why state management is the hard part.

Overview

Infrastructure as software

Infrastructure as Code (IaC) treats provisioning as software: version-controlled, code-reviewed, deployed by automation. It has been the SRE standard since about 2015; the question now is which tool, not whether.

The major players

  • Terraform / OpenTofu — Declarative HCL, state file; AWS, GCP, Azure plus 1000+ providers. OpenTofu is the 2023 community fork after Terraform's license change — The de facto multi-cloud standard
  • Pulumi — Same declarative, state-driven model in real languages: Python, Go, TypeScript, C#. Smaller but fast-growing ecosystem — Teams preferring code abstractions to HCL
  • AWS CDK — TypeScript, Python or Java that synthesizes to CloudFormation — AWS-only teams wanting tight integration
  • Crossplane — Infrastructure as Kubernetes Custom Resources: "everything as Kubernetes objects" — K8s-heavy organizations; cleaner GitOps, less universal

The shared architecture

  • 1. Declarative configuration — "I want a VPC with these subnets, an RDS instance with these specs, an EKS cluster with these node groups," not "create a VPC, then a subnet, then..."
  • 2. State file — Tracks what's deployed; the diff between code and state determines changes
  • 3. Plan / apply cycle — terraform plan shows what would change; terraform apply makes it so. Always plan before apply in production
  • 4. Provider abstraction — AWS, GCP, Cloudflare providers expose resources your config references

Why state is the hardest problem

The state file is the tool's belief about what is deployed. When it disagrees with reality, everything breaks.

  • Drift — Someone clicks in the AWS console; state thinks the resource is unchanged; the next apply may re-create or modify it unexpectedly
  • State corruption — Damaged or out-of-sync state needs manual reconciliation
  • Concurrent modification — Two engineers apply at once; one overwrites the other

State best practices

  • Remote backend — S3, GCS, Azure Blob, Terraform Cloud; never local-only state
  • Locking — DynamoDB for the S3 backend, Cloud Storage for GCS; prevents concurrent applies
  • Backups — S3 versioning + lifecycle, or Terraform Cloud's automatic backups
  • Workspace per environment — dev / staging / prod, to avoid cross-environment applies
  • No console changes — Or detect drift with continuous terraform plan

Module design

  • Reusable modules — Common patterns (VPC, RDS, EKS) invoked by environment-specific configs
  • Composition over inheritance — Modules call other modules
  • Versioned modules — Tagged releases, so prod can run a different module version than dev

The OpenTofu split (2023)

HashiCorp relicensed Terraform under the BUSL (not OSI-approved), and the community forked OpenTofu under the MPL. Most public usage is moving to OpenTofu; commercial users may stay on Terraform for support contracts. Compatibility holds for now; divergence is likely over 2-3 years.

Crossplane vs Terraform

  • Model — Imperative-feeling apply cycle; an engineer runs commands — Continuous reconciliation in Kubernetes; submit YAML and it works toward it indefinitely
  • GitOps — Usually wrapped with Atlantis or Terraform Cloud — Fits natively

Key concepts

Declarative IaC
Describe desired state; tool figures out how to reach it. Standard pattern across Terraform, Pulumi, CDK.
State file
Tool's record of what's deployed. Drift between state and reality is the leading source of IaC bugs.
Plan / apply
Plan shows proposed changes; apply executes them. Production-grade discipline: always plan first.
Remote state + locking
State stored in S3/GCS with DynamoDB/equivalent for concurrent-apply prevention. Never local-only state.
OpenTofu fork
Community fork (2023) after HashiCorp BUSL license change. Compatibility maintained; gradual divergence expected.
Crossplane
Kubernetes-native IaC. Resources are CRDs; controller reconciles continuously. Fits GitOps cleanly.

When to use it

  • Greenfield infrastructure project — IaC from day 1, never click-ops
  • Migration from manual to IaC — incremental import; terraform import for existing resources
  • Multi-cloud or vendor-portable infrastructure — Terraform / OpenTofu (Pulumi second)
  • Kubernetes-heavy, GitOps-driven shop — Crossplane is a natural fit

Interview questions

  • Compare Terraform, Pulumi, and Crossplane.
  • Why is state management the hardest IaC problem?
  • How do you organize Terraform code at scale?

Sign up free to read the full topic

More SRE topics

Start free on Cariara · Coding problems · System design studio