There’s a special kind of anxiety that comes from manually configuring infrastructure in the AWS Console.

“Did I check that security group rule?” “Wait, which subnet was that in?” “Why doesn’t this look like the staging environment?”

Then one day, everything changes. You discover Infrastructure as Code (IaC), and suddenly you’re wondering how you ever lived without it.

The Before Times

Picture this: It’s 2 AM. Production is down. You need to spin up a replacement server exactly like the one that just died.

You open the AWS Console and start clicking. Security groups, IAM roles, VPC settings, environment variables…

Twenty minutes later, you’ve got something running. But is it the same? Did you miss something? You won’t know until something else breaks.

This was my life. And it was terrible.

Enter Terraform

Terraform changed everything. Instead of clicking, I describe what I want:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  
  vpc_security_group_ids = [aws_security_group.web.id]
  subnet_id              = aws_subnet.public.id
  
  tags = {
    Name        = "web-server"
    Environment = "production"
  }
}

resource "aws_security_group" "web" {
  name        = "web-server-sg"
  description = "Security group for web server"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Now that 2 AM incident? terraform apply. Done. Identical infrastructure, every time.

The Real Benefits

1. Version Control

Your infrastructure is now code. Code lives in Git. Git has history, branches, and pull requests.

1
2
3
4
git log --oneline
a3f2b1c Add Redis cache cluster
8d4e2a1 Increase web server instance size
2c1f8b3 Add CloudFront distribution

When something breaks, git blame tells you exactly what changed and when. Roll back with git revert. Review changes before they hit production with PRs.

2. Environment Parity

Staging should match production. With IaC, it does — by definition.

1
2
3
4
5
6
7
module "environment" {
  source = "./modules/web-stack"
  
  environment   = var.environment  # "staging" or "production"
  instance_type = var.environment == "production" ? "t3.large" : "t3.micro"
  replicas      = var.environment == "production" ? 3 : 1
}

Same code, different variables. No more “works in staging” surprises.

3. Documentation That Can’t Lie

Comments get stale. Wikis get forgotten. But your Terraform code? It’s always accurate because it’s literally what’s running.

New team member wants to understand the architecture? Read the code. It’s the single source of truth.

4. Disaster Recovery

Your entire infrastructure is a text file. Back it up, version it, store it anywhere.

If AWS nuked your account tomorrow, you could rebuild everything in a new account with a single command.

The Learning Curve

I won’t lie — there’s a learning curve. Terraform has its own syntax (HCL), its own state management, its own gotchas.

Common pitfalls:

  • State file management: Use remote state (S3 + DynamoDB) from day one
  • Secrets in code: Never commit secrets. Use AWS Secrets Manager or environment variables
  • Blast radius: Start small. Don’t terraform your entire org on day one

My recommended learning path:

  1. Start with a simple project (static S3 website)
  2. Add complexity gradually (EC2, RDS, etc.)
  3. Learn modules for reusability
  4. Implement CI/CD for your Terraform code

Beyond Terraform

Terraform isn’t the only option:

  • AWS CloudFormation: AWS-native, tightly integrated, YAML/JSON syntax
  • Pulumi: Write infrastructure in real programming languages (Python, TypeScript, Go)
  • Ansible: Better for configuration management than provisioning, but overlaps
  • CDK: AWS’s answer to Pulumi

I stick with Terraform for its cloud-agnostic approach and mature ecosystem, but pick what fits your team.

The Bottom Line

Infrastructure as Code isn’t just a DevOps buzzword. It’s the difference between:

  • Hoping your infrastructure is configured correctly vs. knowing it is
  • Spending hours recreating environments vs. running one command
  • Tribal knowledge locked in someone’s head vs. documented, reviewable code

The first time you run terraform plan and see exactly what will change before it happens, you’ll wonder how you ever lived without it.

Stop clicking. Start coding.


What’s your IaC journey been like? Still clicking around in consoles, or have you seen the light? Let me know on Twitter.