Terraform AWS EC2 es la forma más eficiente de gestionar instancias en la nube mediante código. En esta guía completa, aprenderás a crear infraestructura escalable de manera declarativa, automatizar tus despliegues, y mantener un control versionado de tus recursos cloud con Infrastructure as Code (IaC).

AWS EC2 (Elastic Compute Cloud) es uno de los servicios más utilizados en Amazon Web Services, y gestionarlo con Terraform te permite replicar infraestructura, mantener consistencia entre entornos, y reducir errores humanos en configuraciones manuales. Si también trabajas con contenedores, te recomendamos explorar nuestra guía de Docker Compose para orquestación de aplicaciones.

¿Qué es Terraform?

Terraform es una herramienta de código abierto desarrollada por HashiCorp que te permite definir, provisionar y gestionar infraestructura cloud mediante archivos de configuración declarativos. A diferencia de scripts imperativos que indican paso a paso cómo crear recursos, con Terraform describes el estado final deseado y la herramienta se encarga de llegar a ese estado.

Las principales ventajas de Terraform son:

  • Multi-cloud: Funciona con AWS, Azure, Google Cloud, y más de 3000 providers
  • Declarativo: Defines qué quieres, no cómo obtenerlo
  • Versionable: El código IaC se almacena en Git como cualquier código
  • Idempotente: Puedes ejecutarlo múltiples veces con el mismo resultado
  • Plan de ejecución: Previsualizas cambios antes de aplicarlos

En 2025, el provider de AWS supera los 4.5 mil millones de descargas, siendo por mucho el más popular del ecosistema Terraform, superando a los siguientes 10 providers combinados.

Fundamentos de Terraform AWS EC2

Una instancia EC2 en AWS es esencialmente una máquina virtual que ejecuta en la infraestructura de Amazon. Con Terraform AWS EC2, defines esta instancia mediante el recurso aws_instance, que permite configurar:

  • AMI (Amazon Machine Image): La imagen base del sistema operativo
  • Instance Type: El tamaño y capacidad de la instancia (t2.micro, t3.medium, etc.)
  • VPC y Subnet: La red donde se ubicará la instancia
  • Security Groups: Reglas de firewall para tráfico entrante y saliente
  • Key Pairs: Claves SSH para acceso remoto
  • EBS Volumes: Discos de almacenamiento persistente
  • Tags: Etiquetas para organización y facturación

El flujo de trabajo típico con Terraform consta de tres comandos fundamentales:

  1. terraform init: Inicializa el directorio y descarga providers
  2. terraform plan: Previsualiza los cambios que se aplicarán
  3. terraform apply: Aplica los cambios en la infraestructura real

Requisitos Previos

Antes de empezar a trabajar con Terraform AWS EC2, necesitas:

  • Terraform instalado: Versión 1.5 o superior (verifica con terraform --version)
  • Cuenta de AWS activa: Con permisos para crear instancias EC2
  • AWS CLI configurado: Con tus credenciales (Access Key y Secret Key)
  • Editor de código: VS Code con la extensión de HashiCorp Terraform recomendada
  • Conocimientos básicos: Familiaridad con AWS, línea de comandos, y conceptos de redes

Para configurar AWS CLI, ejecuta aws configure e introduce tus credenciales. Terraform utilizará automáticamente estas credenciales para autenticarse con AWS.

Crear Terraform AWS EC2 Paso a Paso

Vamos a crear una instancia EC2 completa siguiendo las mejores prácticas de Infrastructure as Code.

Paso 1: Estructura del Proyecto

Crea una estructura de directorios organizada:

terraform-aws-ec2/
├── main.tf          # Recursos principales
├── variables.tf     # Definición de variables
├── outputs.tf       # Outputs del módulo
├── terraform.tfvars # Valores de variables
└── README.md        # Documentación

Paso 2: Configurar el Provider AWS

En main.tf, define el provider de AWS con la versión específica:

terraform {
  required_version = ">= 1.5.0"
  
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
  
  default_tags {
    tags = {
      Environment = var.environment
      ManagedBy   = "Terraform"
      Project     = "TerraformAWSEC2"
    }
  }
}

Este bloque asegura que todos los recursos creados tengan tags automáticos para trazabilidad y facturación.

Paso 3: Definir Variables

En variables.tf, declara las variables necesarias para Terraform AWS EC2:

variable "aws_region" {
  description = "Región de AWS donde desplegar la instancia"
  type        = string
  default     = "us-east-1"
}

variable "environment" {
  description = "Entorno de despliegue"
  type        = string
  default     = "production"
}

variable "instance_type" {
  description = "Tipo de instancia EC2"
  type        = string
  default     = "t3.micro"
}

variable "ami_id" {
  description = "ID de la AMI de Amazon Linux 2023"
  type        = string
  # AMI de Amazon Linux 2023 en us-east-1
  default     = "ami-0c55b159cbfafe1f0"
}

variable "key_name" {
  description = "Nombre del key pair para acceso SSH"
  type        = string
}

variable "allowed_ssh_cidr" {
  description = "CIDR permitido para conexiones SSH"
  type        = list(string)
  default     = ["0.0.0.0/0"]  # ⚠️ Restringir en producción
}

Paso 4: Crear Security Group

El Security Group actúa como firewall virtual. Añade esto a main.tf:

resource "aws_security_group" "ec2_sg" {
  name        = "terraform-ec2-security-group"
  description = "Security group para instancia EC2 gestionada con Terraform"
  
  # SSH desde IPs permitidas
  ingress {
    description = "SSH access"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = var.allowed_ssh_cidr
  }
  
  # HTTP para servidor web
  ingress {
    description = "HTTP access"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  # HTTPS
  ingress {
    description = "HTTPS access"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  # Permitir todo el tráfico saliente
  egress {
    description = "Allow all outbound"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  tags = {
    Name = "terraform-ec2-sg"
  }
}

Paso 5: Crear la Instancia EC2

Ahora el recurso principal de Terraform AWS EC2:

resource "aws_instance" "web_server" {
  ami           = var.ami_id
  instance_type = var.instance_type
  key_name      = var.key_name
  
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]
  
  # Disco raíz con 20GB
  root_block_device {
    volume_type = "gp3"
    volume_size = 20
    encrypted   = true
    
    tags = {
      Name = "terraform-ec2-root-volume"
    }
  }
  
  # Script de inicialización
  user_data = <<-EOF
              #!/bin/bash
              yum update -y
              yum install -y httpd
              systemctl start httpd
              systemctl enable httpd
              echo "<h1>Servidor EC2 gestionado con Terraform</h1>" > /var/www/html/index.html
              EOF
  
  # Protección contra terminación accidental
  disable_api_termination = true
  
  # Monitoreo detallado (costo adicional)
  monitoring = false
  
  tags = {
    Name        = "terraform-ec2-web-server"
    Application = "WebServer"
  }
  
  lifecycle {
    create_before_destroy = true
  }
}

Paso 6: Definir Outputs

En outputs.tf, exporta información útil:

output "instance_id" {
  description = "ID de la instancia EC2 creada"
  value       = aws_instance.web_server.id
}

output "instance_public_ip" {
  description = "IP pública de la instancia"
  value       = aws_instance.web_server.public_ip
}

output "instance_public_dns" {
  description = "DNS público de la instancia"
  value       = aws_instance.web_server.public_dns
}

output "security_group_id" {
  description = "ID del security group"
  value       = aws_security_group.ec2_sg.id
}

output "ssh_connection_command" {
  description = "Comando para conectar por SSH"
  value       = "ssh -i ~/.ssh/${var.key_name}.pem ec2-user@${aws_instance.web_server.public_ip}"
}

Paso 7: Valores de Variables

Crea terraform.tfvars con tus valores específicos:

aws_region       = "us-east-1"
environment      = "production"
instance_type    = "t3.micro"
key_name         = "mi-key-pair"  # Reemplazar con tu key pair
allowed_ssh_cidr = ["203.0.113.0/24"]  # Tu IP pública/32

Paso 8: Desplegar la Infraestructura

Ejecuta los comandos de Terraform:

# Inicializar Terraform
terraform init

# Validar la sintaxis
terraform validate

# Formatear el código
terraform fmt

# Previsualizar cambios
terraform plan

# Aplicar cambios
terraform apply

# Confirmar con 'yes' cuando se solicite

Terraform mostrará un plan detallado de los recursos a crear. Verifica que todo sea correcto antes de confirmar. Una vez desplegada tu infraestructura, considera implementar monitoreo con herramientas como Uptime Kuma para vigilar el estado de tus servicios.

Variables y Configuración de Terraform AWS EC2

Las variables en Terraform permiten reutilizar código y adaptarlo a diferentes entornos. Aquí algunas mejores prácticas:

Variables Sensibles

Para datos sensibles como contraseñas o claves API, marca las variables como sensibles. Si gestionas secretos para aplicaciones autohospedadas, también puedes utilizar Vaultwarden como gestor de contraseñas seguro:

variable "db_password" {
  description = "Contraseña de la base de datos"
  type        = string
  sensitive   = true
}

Data Sources para AMIs Dinámicas

En lugar de hardcodear AMI IDs, usa data sources para obtener la AMI más reciente automáticamente:

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]
  
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
  
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

resource "aws_instance" "web_server" {
  ami           = data.aws_ami.amazon_linux_2023.id
  # ... resto de la configuración
}

Esto garantiza que siempre uses la última versión de Amazon Linux 2023.

Locals para Valores Calculados

Los valores locales son útiles para cálculos o composiciones:

locals {
  common_tags = {
    Environment = var.environment
    ManagedBy   = "Terraform"
    CostCenter  = "Engineering"
  }
  
  instance_name = "${var.environment}-web-server-${formatdate("YYYYMMDD", timestamp())}"
}

Módulos Avanzados con Terraform AWS EC2

Los módulos permiten encapsular y reutilizar configuraciones de Terraform AWS EC2 en múltiples proyectos.

Usar el Módulo Oficial de AWS

El módulo terraform-aws-modules/ec2-instance/aws tiene más de 96 millones de descargas y simplifica enormemente la creación de instancias:

module "ec2_instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "~> 5.0"

  name = "terraform-managed-instance"

  instance_type          = "t3.micro"
  key_name               = var.key_name
  monitoring             = true
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]
  subnet_id              = data.aws_subnet.selected.id

  tags = {
    Environment = "production"
    Terraform   = "true"
  }
}

Auto Scaling Group

Para ambientes de producción, combina Terraform AWS EC2 con Auto Scaling:

resource "aws_launch_template" "app" {
  name_prefix   = "terraform-ec2-"
  image_id      = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"
  
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]
  
  user_data = base64encode(file("${path.module}/user-data.sh"))
}

resource "aws_autoscaling_group" "app" {
  name                = "terraform-ec2-asg"
  vpc_zone_identifier = data.aws_subnet_ids.private.ids
  
  min_size         = 2
  max_size         = 10
  desired_capacity = 3
  
  launch_template {
    id      = aws_launch_template.app.id
    version = "$Latest"
  }
  
  tag {
    key                 = "Name"
    value               = "terraform-ec2-asg-instance"
    propagate_at_launch = true
  }
}

Optimización y Best Practices

Seguridad

  • Nunca hardcodear credenciales: Usa AWS CLI configurado o variables de entorno
  • Encriptar volúmenes EBS: Activa encrypted = true en todos los discos
  • Principio de mínimo privilegio: Asigna IAM roles específicos, no permisos amplios
  • Security Groups restrictivos: Limita SSH solo a IPs conocidas
  • Rotate keys regularmente: Cambia key pairs cada 90 días
  • Enable VPC Flow Logs: Para auditoría de tráfico de red

State Management

El archivo terraform.tfstate contiene el estado de tu infraestructura. Para equipos, usa backend remoto:

terraform {
  backend "s3" {
    bucket         = "mi-terraform-state-bucket"
    key            = "terraform-aws-ec2/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }
}

Beneficios del backend remoto en S3:

  • Colaboración en equipo
  • State locking con DynamoDB (evita conflictos)
  • Versionado del state
  • Backups automáticos
  • Encriptación en reposo

Organización del Código

  • Un recurso por archivo: Para proyectos grandes, separa recursos en archivos individuales (ec2.tf, sg.tf, etc.)
  • Módulos reutilizables: Crea módulos internos para patrones repetitivos
  • Workspaces para entornos: Usa terraform workspace para dev/staging/prod
  • Comentarios descriptivos: Documenta decisiones arquitectónicas importantes
  • README actualizado: Incluye instrucciones de uso y diagramas

Costos

  • Usa t3.micro para pruebas (free tier elegible)
  • Implementa Auto Scaling para optimizar costos en producción
  • Configura Instance Scheduler para parar instancias fuera de horario laboral
  • Monitorea con AWS Cost Explorer y establece alarmas
  • Usa Spot Instances para cargas de trabajo no críticas (hasta 90% de descuento)

Troubleshooting Terraform AWS EC2

Error: «InvalidAMIID.NotFound»

Causa: La AMI especificada no existe en la región configurada.

Solución: Verifica que la AMI exista en tu región con:

aws ec2 describe-images --image-ids ami-XXXXXXXXX --region us-east-1

O usa data sources como mostré anteriormente para AMIs dinámicas.

Error: «UnauthorizedOperation»

Causa: Las credenciales de AWS no tienen permisos suficientes.

Solución: Verifica los permisos IAM. Necesitas al menos:

  • ec2:RunInstances
  • ec2:DescribeInstances
  • ec2:CreateSecurityGroup
  • ec2:AuthorizeSecurityGroupIngress

Error: «Instance failed status checks»

Causa: La instancia arrancó pero el sistema operativo no está respondiendo.

Solución:

# Ver logs del sistema
aws ec2 get-console-output --instance-id i-XXXXXXXXX

# Verificar user_data script
terraform show | grep user_data

Debugging con TF_LOG

Para logs detallados de Terraform:

export TF_LOG=DEBUG
export TF_LOG_PATH=./terraform-debug.log
terraform apply

State Corrupto

Si el state file se corrompe:

# Hacer backup del state
terraform state pull > backup.tfstate

# Listar recursos en el state
terraform state list

# Remover recurso problemático
terraform state rm aws_instance.problematic

# Importar recurso existente
terraform import aws_instance.problematic i-XXXXXXXXX

FAQ sobre Terraform AWS EC2

¿Cuánto cuesta usar Terraform AWS EC2?

Terraform es gratuito y open source. Solo pagas por los recursos de AWS que crees. Una instancia t3.micro cuesta aproximadamente $0.0104/hora (~$7.5/mes). Las primeras 750 horas/mes de t2.micro o t3.micro son gratuitas durante 12 meses en AWS Free Tier.

¿Puedo usar Terraform con CloudFormation?

Sí, aunque no es común. Puedes usar el recurso aws_cloudformation_stack para desplegar stacks de CloudFormation desde Terraform. Sin embargo, generalmente se recomienda elegir una herramienta u otra para evitar complejidad innecesaria.

¿Cómo actualizo una instancia EC2 existente?

Modifica el archivo main.tf con los cambios deseados (por ejemplo, cambiar instance_type), ejecuta terraform plan para previsualizar, y luego terraform apply. Ten en cuenta que algunos cambios (como cambiar la AMI) requieren reemplazar la instancia completamente.

¿Es seguro para producción?

Absolutamente. Terraform AWS EC2 es ampliamente utilizado en producción por empresas de todos los tamaños. Empresas como Uber, Airbnb, y Netflix gestionan miles de instancias con Terraform. La clave está en seguir best practices: usar backend remoto, implementar peer reviews del código IaC, y aplicar el principio de mínimo privilegio en IAM.

¿Cómo gestiono el state file de forma segura?

Nunca almacenes el terraform.tfstate en Git. Usa un backend remoto como S3 con encriptación y state locking mediante DynamoDB. Configura versionado en el bucket S3 para poder recuperar estados anteriores. Para equipos, considera Terraform Cloud que ofrece gestión de state empresarial gratuita para hasta 5 usuarios.

Conclusión

Has aprendido a dominar Terraform AWS EC2 desde cero hasta configuraciones avanzadas con Auto Scaling y módulos reutilizables. La gestión de infraestructura como código te permite mantener consistencia, facilitar colaboración, y reducir errores en tus despliegues cloud. Si además quieres complementar tu stack con servicios de IA local, te recomendamos explorar Ollama con Docker Compose.

Los próximos pasos recomendados son:

  • Implementar un pipeline CI/CD para aplicar cambios automáticamente
  • Explorar módulos de VPC para redes avanzadas
  • Configurar Application Load Balancer para alta disponibilidad
  • Integrar con herramientas de monitoreo como CloudWatch y Datadog
  • Implementar disaster recovery con backups automatizados

Recuerda siempre ejecutar terraform plan antes de apply, mantener tu código versionado en Git, y documentar decisiones arquitectónicas importantes en tu README. Para proyectos de automatización del hogar que integren con tu infraestructura cloud, también puedes revisar nuestra guía de Home Assistant.

Recursos Adicionales

Avatar

Por Mid

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x