THE DEV SPECTRUM

Back to Spectrum

Infrastructure as Code: Why I Switched from CloudFormation to Terraform

In the AWS ecosystem, CloudFormation is the "safe" default. But as my infrastructure grew to include Cloudflare for edge routing, PagerDuty for alerting, and GitHub for CI/CD, CloudFormation became a silo. Here is the technical breakdown of why I migrated the entire "Spectrum" to HashiCorp Terraform.

1. The State of the Union: State Management

The biggest hurdle in IaC is "drift"—when someone manually changes a security group in the AWS Console.

  • CloudFormation manages state internally; if the stack gets out of sync, you often hit the dreaded UPDATE_ROLLBACK_FAILED state.
  • Terraform stores state in a tfstate file (which we store in an S3 bucket with DynamoDB locking). This allows for terraform plan, giving you a dry-run of exactly what will change before a single API call is made.

2. Provider Versatility

A modern DevOps stack isn't just AWS. In my current setup, a single terraform apply handles:

  • AWS: Provisioning the EKS cluster and EMR nodes.
  • Cloudflare: Updating DNS A-records to point to the new Load Balancer.
  • GitHub: Configuring repository secrets for the CI/CD pipeline.
# Example of a Cross-Provider Resource Dependency
resource "aws_lb" "prod_alb" {
  name               = "prod-alb"
  load_balancer_type = "application"
  # ...
}

resource "cloudflare_record" "app_dns" {
  zone_id = var.cloudflare_zone_id
  name    = "api"
  value   = aws_lb.prod_alb.dns_name
  type    = "CNAME"
  proxied = true
}

3. The Migration Strategy (The "Import" Trick)

You don't have to rebuild from scratch. Use the terraform import command to bring existing AWS resources into your state file. This allows for a "brownfield" migration where you slowly wrap code around existing infrastructure.