Back to articles
blog — devops — zsh$ cat devops.md# Apr 20, 2023Terraform turns clickinginto code
6 min read

Stop clicking in the AWS console and copying resources manually. Write your infrastructure as code with Terraform and deploy it everywhere.

TerraformIaCDevOpsAWS

A startup I know had their entire infrastructure in one AWS account. No code, just someone who knew which buttons to click in the right order

That person quit. Two weeks notice. On their last day, they wrote a 47-page Google Doc explaining how everything was set up. Security groups, load balancers, RDS configs, the works. Printed it out, handed it over, left

Three months later, they need to give the new analytics service access to the production database. Should be simple. Except there are six security groups, three IAM roles, and two VPCs involved. The doc says “use the database security group” but which one? There’s prod-db-sg, database-prod-sg, and rds-production-sg

They try adding rules to different security groups. Nothing works. Then someone remembers there’s also a network ACL somewhere. And wait, which subnet is the analytics service even running in?

Four hours later, it’s working. Nobody’s entirely sure which of the twelve changes they made actually fixed it. Better not touch it again

That company now uses Terraform. Their entire infrastructure is 300 lines of code. Want to know which security group does what? Read the file. Takes two minutes

The recipe vs winging it

Clicking in a console is like cooking without a recipe. Sure, you might nail it once. But try making the same meal next week. Different amounts, forgot an ingredient, oven temperature wrong. Close, but not quite right

Terraform is the recipe. Same ingredients, same steps, same result every time. And you can hand that recipe to someone else. They’ll make the exact same dish

Here’s actual infrastructure as code:

resource "aws_s3_bucket" "my_bucket" {
  bucket = "my-cool-bucket"

  tags = {
    ManagedBy = "terraform"
  }
}

Save this, run terraform apply, boom. S3 bucket. Want ten more? Copy the block ten times, change the names, run apply. Or better yet, use a loop. Two minutes, ten identical buckets

Try doing that by clicking. I’ll wait

What goes wrong without code

Let me tell you about a real incident. Company had three environments: dev, staging, prod. Different people set them up at different times by clicking through AWS console

Dev had a t2.micro database. Staging had a t2.small. Prod had a t2.large. Except someone fat-fingered prod and it was actually a t2.xlarge. Nobody noticed for six months

Then staging broke. Someone tried to fix it by “making it like prod.” Guess what they copied? The t2.xlarge. Now staging costs four times what it should and nobody knows why

This stuff happens every day. Someone clicks something. Forgets to document it. Six months later it breaks and nobody remembers what was there

With Terraform, your infrastructure is literally in a file. You can read it. You can version control it. You know exactly what’s running because it’s right there in git

The basics

Terraform uses HCL. It’s like JSON but less annoying. Write what you want, Terraform makes it happen

Simple web server:

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  tags = {
    Name = "my-web-server"
  }
}

That’s it. Run terraform apply, you get an EC2 instance

Want to change it to t3.small? Edit the file, run apply again. Terraform sees the diff and updates the instance. No clicking, no console, no chance of fat-fingering something

State: Terraform’s memory

Terraform keeps a state file. This is how it remembers what it created. When you run terraform plan, it compares your code to this state and tells you what will change

Default state is local. Fine alone, disaster in teams. Someone else runs Terraform without your state file? They’ll try to create everything from scratch. Duplicate resources, conflicts, bad times

Store state remotely:

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "prod/terraform.tfstate"
    region = "us-east-1"
  }
}

Now everyone on the team uses the same state. No more “it worked on my machine”

Modules: write once, use everywhere

You set up a VPC once. Three subnets, routing tables, internet gateway, the works. Took you an hour to get it right

Now you need the same VPC in staging. And dev. And that demo environment for sales

Without Terraform, you’re clicking for three more hours

With Terraform modules, you package that VPC setup once:

module "vpc" {
  source = "./modules/vpc"

  environment = "staging"
}

Same code, different environment. Dev, staging, prod all get identical networking. Change the module, update everywhere. One source of truth

The clickops horror story

Real story from a friend. Company had no infrastructure as code. Everything hand-configured through AWS console

New dev joins. Needs AWS access. Someone gives them admin because “easier than figuring out specific permissions”

Dev is experimenting in console. Thinks they’re in dev. They’re in prod. Terminates an RDS instance. “It said database-test, I thought it was the test environment”

It was the prod database. Backups? There were manual snapshots. From three weeks ago. Because someone had to remember to click the backup button

With Terraform, that database config is in code:

resource "aws_db_instance" "prod" {
  identifier = "production-database-do-not-touch"
  # ...
  backup_retention_period = 7
  skip_final_snapshot = false
}

Clear name. Automatic backups. In version control. You can see who changed what and when. You can revert to last week’s config if needed

More importantly, that database is protected. Terraform won’t let you delete it by accident. You’d have to explicitly remove it from code, commit, push, pass review, then apply. Multiple chances to catch the mistake

When Terraform makes sense

Use it if:

  • You need more than one environment
  • Multiple people touch infrastructure
  • You want to sleep well at night
  • You value your time

Skip it if:

  • One-off experiment you’ll delete in an hour
  • You’re learning AWS and need to click around to understand

If you’re doing something more than once, Terraform saves time. If you’re exploring, clicking is fine

Three commands you need

terraform init    # Download providers, set up backend
terraform plan    # See what will change
terraform apply   # Make it happen

That’s it. Write config, plan, apply. Your infrastructure updates

Want to tear it all down?

terraform destroy

Everything you created, gone. Try doing that by clicking. You’ll miss something and pay for it for months

The point

Infrastructure should be:

  • In version control
  • Reviewable
  • Repeatable
  • Documented automatically

Clicking gives you none of this. Terraform gives you all of it

Your infrastructure is code. Treat it like code. Review it, test it, version it. Stop clicking in production

Enjoyed this article?

Let me know! A share is always appreciated.

About the author

Sofiane Djerbi

Sofiane Djerbi

Cloud & Kubernetes Architect, FinOps Expert. I help companies build scalable, secure, and cost-effective infrastructures.

Comments