# Infrastructure as Code: Mistakes I Made So You Don't Have To
After managing infrastructure with Terraform for years, I've made every mistake in the book. Here are the ones that hurt the most.
1. Hardcoding Everything
- The Mistake:* My first Terraform config looked like this:
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
}Seems fine until you need to deploy to another region or environment.
- The Fix:* Use variables and data sources:
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*"]
}
} ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
}2. Not Using Remote State
- The Mistake:* Keeping
terraform.tfstatelocally. Lost my state file once. Never again.
- The Fix:* Always use remote state:
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
}
}Enable versioning on that S3 bucket. Trust me.
3. Massive Monolithic Configs
- The Mistake:* One giant
main.tfwith 2000 lines. Good luck finding anything.
- The Fix:* Break it up:
main.tf- Main resourcesvariables.tf- Input variablesoutputs.tf- Output valuesversions.tf- Provider versions- Separate modules for reusable components
4. Not Locking Provider Versions
- The Mistake:*
provider "aws" {
region = "us-east-1"
}Provider updates, breaks everything. Classic.
- The Fix:*
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}5. Destroying Production by Accident
- The Mistake:* Running
terraform destroyin the wrong terminal window. We've all been there.
- The Fix:*
- Use workspace prefixes in your terminal
- Add lifecycle prevent_destroy blocks:
resource "aws_instance" "critical" {
# ...
lifecycle {
prevent_destroy = true
}
}- Use Terraform Cloud with proper RBAC
Lessons Learned
Infrastructure as Code is powerful, but it's also dangerous. Treat your Terraform code like production code because it literally creates your production.
- My golden rules:
- Always use remote state
- Lock your provider versions
- Use modules for reusability
- Test in dev first (obvious but ignored)
- Plan before apply, always
Made any catastrophic Terraform mistakes? You're not alone. Share yours!