Técnico12 min

Terraform vs CloudFormation: ¿Cuál Elegir en 2024?

Una comparación detallada entre Terraform y CloudFormation, analizando sintaxis, ecosistema, portabilidad y casos de uso ideales para cada herramienta.

CR

Carlos Rodríguez

CEO & Co-founder

La Eterna Batalla: Terraform vs CloudFormation

Si trabajas con AWS, inevitablemente te enfrentarás a esta decisión: ¿Terraform o CloudFormation? Después de años usando ambas herramientas en producción, aquí está nuestra perspectiva honesta.

Comparación Rápida

AspectoTerraformCloudFormation
Multi-cloud✅ Sí❌ Solo AWS
SintaxisHCL (más legible)JSON/YAML
EstadoArchivo externoGestionado por AWS
RollbackManualAutomático
CostoGratis (OSS)Gratis
MódulosRegistry públicoLimitado

Sintaxis: La Primera Impresión

CloudFormation (YAML)

1Resources: 2 WebServerInstance: 3 Type: AWS::EC2::Instance 4 Properties: 5 ImageId: !Ref LatestAmiId 6 InstanceType: t3.micro 7 SecurityGroups: 8 - !Ref WebServerSecurityGroup 9 UserData: 10 Fn::Base64: !Sub | 11 #!/bin/bash 12 yum update -y 13 yum install -y httpd 14 systemctl start httpd 15 systemctl enable httpd 16 echo "<h1>Hello from ${AWS::Region}</h1>" > /var/www/html/index.html 17 18 WebServerSecurityGroup: 19 Type: AWS::EC2::SecurityGroup 20 Properties: 21 GroupDescription: Enable HTTP access 22 SecurityGroupIngress: 23 - IpProtocol: tcp 24 FromPort: 80 25 ToPort: 80 26 CidrIp: 0.0.0.0/0

Terraform (HCL)

1resource "aws_instance" "web_server" { 2 ami = data.aws_ami.latest.id 3 instance_type = "t3.micro" 4 5 vpc_security_group_ids = [aws_security_group.web_server.id] 6 7 user_data = <<-EOF 8 #!/bin/bash 9 yum update -y 10 yum install -y httpd 11 systemctl start httpd 12 systemctl enable httpd 13 echo "<h1>Hello from ${data.aws_region.current.name}</h1>" > /var/www/html/index.html 14 EOF 15 16 tags = { 17 Name = "WebServer" 18 } 19} 20 21resource "aws_security_group" "web_server" { 22 name = "web-server-sg" 23 description = "Enable HTTP access" 24 25 ingress { 26 from_port = 80 27 to_port = 80 28 protocol = "tcp" 29 cidr_blocks = ["0.0.0.0/0"] 30 } 31 32 egress { 33 from_port = 0 34 to_port = 0 35 protocol = "-1" 36 cidr_blocks = ["0.0.0.0/0"] 37 } 38}
<div class="info-box"> 💡 **Observación:** HCL es generalmente más conciso y legible que YAML/JSON, especialmente en configuraciones complejas. </div>

Gestión del Estado: La Gran Diferencia

CloudFormation

  • Estado gestionado automáticamente por AWS
  • No necesitas preocuparte por archivos de estado
  • Drift detection integrado

Terraform

  • Archivo de estado local o remoto (S3, Terraform Cloud)
  • Requiere gestión cuidadosa del estado
  • Posibilidad de corrupción del estado
1# Backend remoto en S3 para Terraform 2terraform { 3 backend "s3" { 4 bucket = "my-terraform-state" 5 key = "prod/terraform.tfstate" 6 region = "us-east-1" 7 encrypt = true 8 dynamodb_table = "terraform-locks" 9 } 10}

Ecosistema y Módulos

Terraform Registry

1# Usar un módulo del registry público 2module "vpc" { 3 source = "terraform-aws-modules/vpc/aws" 4 version = "5.0.0" 5 6 name = "my-vpc" 7 cidr = "10.0.0.0/16" 8 9 azs = ["us-east-1a", "us-east-1b", "us-east-1c"] 10 private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] 11 public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] 12 13 enable_nat_gateway = true 14 enable_vpn_gateway = true 15}

CloudFormation Nested Stacks

1Resources: 2 VPCStack: 3 Type: AWS::CloudFormation::Stack 4 Properties: 5 TemplateURL: https://s3.amazonaws.com/my-bucket/vpc-template.yaml 6 Parameters: 7 VPCCidr: 10.0.0.0/16 8 EnableNatGateway: true

Funcionalidades Avanzadas

1. Condicionales

CloudFormation:

1Conditions: 2 CreateProdResources: !Equals [!Ref Environment, production] 3 4Resources: 5 Database: 6 Type: AWS::RDS::DBInstance 7 Condition: CreateProdResources 8 Properties: 9 DBInstanceClass: db.t3.large

Terraform:

1resource "aws_db_instance" "database" { 2 count = var.environment == "production" ? 1 : 0 3 4 instance_class = "db.t3.large" 5 # ... 6}

2. Loops y Generación Dinámica

Terraform (más poderoso):

1# Crear múltiples instancias con configuración dinámica 2resource "aws_instance" "web" { 3 for_each = var.instance_config 4 5 ami = each.value.ami 6 instance_type = each.value.type 7 8 tags = { 9 Name = each.key 10 Type = each.value.type 11 } 12} 13 14variable "instance_config" { 15 default = { 16 web1 = { ami = "ami-123", type = "t3.micro" } 17 web2 = { ami = "ami-123", type = "t3.small" } 18 web3 = { ami = "ami-456", type = "t3.medium" } 19 } 20}

Casos de Uso Ideales

Usa CloudFormation cuando:

  • 🔸 Tu infraestructura es 100% AWS
  • 🔸 Quieres rollbacks automáticos
  • 🔸 Prefieres no gestionar estado
  • 🔸 Necesitas integración profunda con AWS (StackSets, Service Catalog)
  • 🔸 Tu equipo ya conoce YAML/JSON

Usa Terraform cuando:

  • 🔹 Necesitas multi-cloud o híbrido
  • 🔹 Quieres sintaxis más expresiva
  • 🔹 Necesitas módulos reutilizables complejos
  • 🔹 Prefieres un ecosistema más amplio
  • 🔹 Planeas usar Terraform Cloud/Enterprise

Migración Entre Herramientas

De CloudFormation a Terraform

1# Usar cf2tf para convertir templates 2pip install cf2tf 3cf2tf my-stack.yaml > my-stack.tf 4 5# Importar recursos existentes 6terraform import aws_instance.web i-1234567890abcdef0

De Terraform a CloudFormation

1# Usar former2 para generar templates desde recursos existentes 2# https://github.com/iann0036/former2

Nuestra Experiencia en InfraUX

En InfraUX soportamos ambas herramientas, pero internamente usamos Terraform por estas razones:

  1. Multi-cloud: Necesitamos soportar AWS, Azure y GCP
  2. Modularidad: Nuestros módulos son complejos y reutilizables
  3. Programabilidad: HCL nos permite lógica más compleja
  4. Ecosistema: El Terraform Registry es invaluable

Ejemplo Real: Despliegue de EKS

Terraform (usando módulo oficial):

1module "eks" { 2 source = "terraform-aws-modules/eks/aws" 3 version = "19.0.0" 4 5 cluster_name = "my-cluster" 6 cluster_version = "1.27" 7 8 vpc_id = module.vpc.vpc_id 9 subnet_ids = module.vpc.private_subnets 10 11 eks_managed_node_groups = { 12 general = { 13 desired_size = 2 14 min_size = 1 15 max_size = 10 16 17 instance_types = ["t3.large"] 18 } 19 } 20}

CloudFormation (más verboso):

1# Requiere ~300 líneas de YAML para la misma funcionalidad 2# Incluyendo roles IAM, security groups, node groups, etc.

Métricas de Adopción (2024)

MétricaTerraformCloudFormation
Usuarios activos5M+2M+
Contribuidores1,700+N/A (cerrado)
Providers3,000+1 (AWS)
Módulos públicos15,000+~500

Conclusión

No hay una respuesta correcta universal. La elección depende de tu contexto:

<div class="success-box"> ✅ **CloudFormation** es excelente si estás 100% en AWS y valoras la simplicidad operacional sobre la flexibilidad. </div> <div class="success-box"> ✅ **Terraform** brilla cuando necesitas flexibilidad, multi-cloud, o tienes requisitos complejos de infraestructura. </div>

En InfraUX, creemos que ambas herramientas tienen su lugar. Por eso nuestro editor visual puede exportar a ambos formatos, permitiéndote elegir la mejor herramienta para cada situación.

Pro Tip: Usa Ambas

1# Terraform puede gestionar stacks de CloudFormation 2resource "aws_cloudformation_stack" "legacy_app" { 3 name = "legacy-application" 4 5 template_body = file("${path.module}/legacy-app.yaml") 6 7 parameters = { 8 InstanceType = "t3.medium" 9 } 10}

La infraestructura como código no se trata de elegir un bando, sino de usar la herramienta correcta para el trabajo correcto.

#terraform#cloudformation#iac#aws#devops