Skip to content
back to the map
technique
stage: provision
2 min read

Infrastructure as code

When infrastructure is code, a change has a diff, a reviewer, a history and a way back. When it is clicks in a console, nobody can say what exists or why.

Terraform / OpenTofuPulumiAnsibleCloudFormationCrossplaneterraform-docs

Declarative and imperative

  • Declarative tools (Terraform, CloudFormation, Kubernetes manifests) describe the desired end state; the tool works out how to get there.
  • Imperative tools and scripts describe the steps. They are flexible but easier to run twice with different results.
  • Configuration management (Ansible, Chef) installs and configures software on machines; provisioning tools create the machines and cloud resources. Many teams use both, or avoid mutable servers by baking images.
  • Prefer immutable infrastructure: replace instead of patching in place.

The plan and apply loop

Terraform compares your code with the recorded state and the real world, shows a plan of what it will create, change or destroy, and applies it on approval. The plan is the review artifact: read it, and run it in CI so that humans review diffs instead of console actions.

main.tfhcl
terraform {
  required_version = ">= 1.6"
  required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
  }
  backend "s3" {
    bucket         = "example-terraform-state"
    key            = "network/prod.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  tags                 = merge(var.tags, { Name = "main" })
}
workflowbash
terraform fmt -check && terraform validate
terraform plan -out=tfplan             # review this in the pull request
terraform apply tfplan                 # run by the pipeline, not by a laptop

Practices

  • Remote, locked, encrypted state; never commit state files (they may contain secrets).
  • Small modules with clear inputs and outputs, versioned and reused; avoid one giant root module.
  • Separate environments by state and by account, not by a variable you can forget to change.
  • Detect and fix drift: schedule a plan and alert when reality differs from code.
  • Scan the code and the plan for insecure settings before apply (see security in the Engineering domain).
  • Keep secrets out of the code; reference a secret manager.

Pitfalls

  • Manual changes in the console that the code then overwrites or fights.
  • A destroy hidden in a large plan: read what is being replaced, not just what is added.
  • Provider and module versions left floating, so a plan changes without a code change.
  • One state for everything: a small error blocks every team and the is the whole company.
IaCinfrastructure as codeDescribing infrastructure in versioned files (Terraform, Ansible). It brings review, history and testing to configuration, but replicates mistakes at scale if it is not scanned.see in glossary →Blast radiusblast radiusThe size of the damage when something breaks: one account, an entire region, a tenant. Good cloud design limits the radius through isolation (separate accounts, separate VPCs, narrow roles) so that a failure or an attack does not become a full-blown disaster.see in glossary →

connections on the map

updated on 14/10/2026 · sources to go deeper · report an error

in other domains

Study before

test what you learned

Loading questions…