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:
terraform init: Inicializa el directorio y descarga providersterraform plan: Previsualiza los cambios que se aplicaránterraform 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 = trueen 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 workspacepara 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:RunInstancesec2:DescribeInstancesec2:CreateSecurityGroupec2: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
- Terraform Registry – AWS Provider EC2 Instance
- HashiCorp Official AWS Tutorial
- AWS EC2 Documentation
- Terraform AWS EC2 Module
- GitHub – Terraform AWS EC2 Module
