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.
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
Aspecto | Terraform | CloudFormation |
---|---|---|
Multi-cloud | ✅ Sí | ❌ Solo AWS |
Sintaxis | HCL (más legible) | JSON/YAML |
Estado | Archivo externo | Gestionado por AWS |
Rollback | Manual | Automático |
Costo | Gratis (OSS) | Gratis |
Módulos | Registry público | Limitado |
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}
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:
- Multi-cloud: Necesitamos soportar AWS, Azure y GCP
- Modularidad: Nuestros módulos son complejos y reutilizables
- Programabilidad: HCL nos permite lógica más compleja
- 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étrica | Terraform | CloudFormation |
---|---|---|
Usuarios activos | 5M+ | 2M+ |
Contribuidores | 1,700+ | N/A (cerrado) |
Providers | 3,000+ | 1 (AWS) |
Módulos públicos | 15,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.