Infrastructure as Code (IaC)
Build infra such as servers, network, load balancers and databases by writing code and keeping it in Git, instead of clicking in a console.
48.1 Why is it used?
- Infra built by clicking in a console is hard to recreate identically; with code you get the same setup in 10 regions within minutes.
- Every infra change is reviewed in Git (PR), and you get a history of who changed what.
- In a disaster you can stand the whole environment up again from code.
- Dev, staging and prod are all built from the same template, so 'worked on staging, not on prod' happens less.
- Adding extra capacity before a sale and removing it afterwards is just a variable change + apply.
48.2 How it works
- Declarative: you state the final state you want (3 EC2, 1 ALB) and the tool decides what to create/change (Terraform, CloudFormation).
- Imperative/procedural: you write steps, 'do this, then do that' (Ansible playbook, shell script).
- Provisioning vs Configuration: Terraform/CloudFormation create the infra; Ansible sets up packages/config inside an existing server.
- State file: Terraform remembers what exists in a state file; in a team keep it in a remote backend (S3 + DynamoDB lock).
- Plan -> Apply: terraform plan first shows the diff, and after review terraform apply makes the real change.
- Modules: build reusable blocks such as a VPC or an EKS cluster, and let every team use the same module.
- Drift detection: if someone changed something manually in the console, the plan shows the drift.
- Immutable infra: instead of patching a server, build a new image (AMI), launch a new server and remove the old one.
- 1.envs/prod-hyd: region = ap-south-2, cidr = 10.20.0.0/16, modules same
- 2.Pull Request: CI runs terraform plan, + 142 to add
- 3.Review: a senior engineer reads the diff
- 4.On merge the pipeline runs terraform apply
- 5.Region ready in ~40-60 min (manually: weeks)
The same reusable modules (vpc, eks-cluster, rds-aurora, alb, redis) are used in both Mumbai and Hyderabad; only the variables differ.
- 1.Engineer A: terraform apply is running
- 2.State: terraform.tfstate in S3
- 3.Lock: DynamoDB state lock
- 4.Engineer B: lock busy, waits
- 5.As soon as nodes come up, Ansible installs the monitoring agent + hardening config
- 1.Terraform declarative: 'I want 3 EC2 + 1 ALB', the tool works out the diff (CloudFormation, Pulumi)
- 2.Ansible procedural: 'do this first, then this', packages/config inside the server, stateless
- 3.Drift detection: someone changed an SG from the console, terraform plan shows a diff, fix it back from code
- 4.Immutable infra: do not patch the server, build a new AMI/image, launch a new server, remove the old one
48.3 Tools
| Tool | Type | How it is used |
|---|---|---|
| Terraform / OpenTofu | Multi-cloud declarative IaC | Infra for AWS, Azure, GCP, Cloudflare and more in the HCL language; the most popular IaC tool. OpenTofu is its open-source fork. |
| AWS CloudFormation | AWS native IaC | AWS stacks from YAML/JSON templates; AWS manages the state itself, with automatic rollback on failure. |
| AWS CDK | IaC in a programming language | Write in TypeScript/Python, and CDK converts it into a CloudFormation template. |
| Pulumi | Multi-cloud IaC in real languages | Write infra in Python, Go, TypeScript; loops, functions and unit tests work like normal code. |
| Ansible | Configuration management | Agentless; run YAML playbooks over SSH to set up packages, config files and users on servers. |
| Azure Bicep / ARM | Azure native IaC | Declarative templates for Azure resources; Bicep is a simpler version of ARM JSON. |
48.4 Comparison: Terraform vs CloudFormation vs Pulumi vs Ansible
| Point | Terraform | CloudFormation | Pulumi | Ansible |
|---|---|---|---|---|
| Main job | Infra provisioning | AWS infra provisioning | Infra provisioning | Server configuration, app deploy |
| Cloud support | Multi-cloud + SaaS providers | AWS only | Multi-cloud | Multi-cloud, on-prem, network devices |
| Language | HCL (declarative) | YAML / JSON | Python, TS, Go, C# | YAML playbooks (procedural) |
| State | You manage the state file (S3 backend) | AWS manages it | Pulumi Cloud or a self-hosted backend | Stateless |
| Rollback | Not automatic, re-apply the old code | Automatic stack rollback on failure | Not automatic | No, write a reverse playbook |
| Learning curve | Medium | Medium, YAML gets long | Easy for developers | Easy |
| Best for | Multi-cloud, large teams | Pure AWS shops | Dev-heavy teams, complex logic | VM config, network gear, patching |
48.5 When to choose which
- Terraform: the default choice when you are multi-cloud or use a mix of providers such as AWS + Cloudflare + Datadog.
- CloudFormation/CDK: when you are AWS-only and want AWS-managed state and automatic rollback.
- Pulumi: when the team is made of developers and wants loops, conditions and tests in infra as normal code.
- Ansible: to configure servers after creating them with Terraform, or to automate Cisco/Juniper network devices (very useful for networking engineers).
48.6 Real-world example
Launching a new region with Terraform (an illustrative scenario).
- A company runs in Mumbai (ap-south-1) and wants a Hyderabad (ap-south-2) region for DR.
- The platform team already has Terraform modules: vpc, eks-cluster, rds-aurora, alb, redis.
- They create a new folder envs/prod-hyd, change the region variable, give CIDR 10.20.0.0/16, and keep the other modules the same.
- When the PR opens, CI runs terraform plan and shows '+ 142 resources to add', and a senior engineer reviews it.
- On merge the pipeline runs terraform apply; the state is saved in S3, and the DynamoDB lock stops two people applying at once.
- As soon as the EKS nodes come up, Ansible/user-data installs the monitoring agent and hardening config.
- The whole region is ready in roughly 40-60 minutes, which would take weeks manually and come with mistakes.
48.7 Interview tips
- Explain declarative vs imperative and provisioning (Terraform) vs configuration (Ansible).
- Common mistake: keeping the Terraform state file on a local laptop or committing it to Git; it leaks secrets and causes team conflicts.
- Making manual console changes while using IaC; this creates drift and the next apply overwrites them.
- Do not hardcode passwords/keys in code; use Secrets Manager or Vault. Trade-off to quote: a region in 40-60 min vs weeks by hand.