RESUMEN
[DevOps & Cloud] Cómo gestionar infraestructura en AWS con Terraform: Guía completa para 2026
Aprende a automatizar y provisionar tu infraestructura en Amazon Web Services (AWS) utilizando Terraform.
Keywords: Terraform, AWS, Infraestructura como Código
ÍNDICE
1. Introducción a la Infraestructura como Código y Terraform en AWS
2. Fundamentos de Terraform para AWS: Primeros Pasos
3. Conceptos Avanzados de Terraform para Escalabilidad y Reusabilidad
4. Gestión de Recursos AWS Comunes con Terraform
5. Resolución de Problemas Comunes y Mejores Prácticas
6. Aplicación Práctica: Despliegue de una Aplicación Web en AWS con Terraform
7. Conclusión y Perspectivas Futuras
CONTEXTO
Introducción a la Infraestructura como Código y Terraform en AWS
En el dinámico panorama de la tecnología de 2026, la gestión eficiente de la infraestructura en la nube se ha vuelto más crítica que nunca. La Infraestructura como Código (IaC) ha emergido como una metodología fundamental para automatizar el aprovisionamiento, la configuración y la gestión de la infraestructura, transformando la forma en que los equipos de DevOps interactúan con entornos complejos como Amazon Web Services (AWS).
Tradicionalmente, la configuración manual de servidores, bases de datos y redes era un proceso propenso a errores, lento y difícil de escalar. Con IaC, la infraestructura se define en archivos de configuración que pueden versionarse, revisarse y desplegarse de manera consistente, al igual que el código de una aplicación. Esto no solo reduce la posibilidad de errores humanos, sino que también acelera los ciclos de despliegue, mejora la colaboración entre equipos y garantiza la reproducibilidad de los entornos.
Dentro del ecosistema IaC, Terraform de HashiCorp se ha consolidado como una herramienta líder, especialmente para infraestructuras multi-cloud y, de manera destacada, para AWS. Su enfoque declarativo permite a los ingenieros especificar el estado deseado de su infraestructura, y Terraform se encarga de realizar los pasos necesarios para alcanzar ese estado. Esto significa que, en lugar de escribir scripts imperativos que dictan «cómo» hacer algo, los equipos se concentran en «qué» infraestructura quieren tener.
La combinación de Terraform y AWS ofrece una potente sinergia. AWS proporciona una vasta gama de servicios de infraestructura escalables y flexibles, mientras que Terraform ofrece un marco unificado para orquestar y gestionar estos servicios de manera programática. Desde el aprovisionamiento de máquinas virtuales EC2 y bases de datos RDS hasta la configuración de redes VPC complejas y servicios sin servidor como Lambda, Terraform simplifica enormemente la administración de la nube. Esta guía exhaustiva te llevará a través de los pasos esenciales para dominar Terraform en AWS en 2026, preparándote para construir y gestionar infraestructuras robustas y automatizadas.
PUNTO CLAVE
La Infraestructura como Código (IaC) con Terraform es esencial en 2026 para la automatización y gestión consistente de entornos AWS, reduciendo errores y acelerando los despliegues.
CONTENIDO PRINCIPAL
Fundamentos de Terraform para AWS: Primeros Pasos
Para comenzar a gestionar tu infraestructura AWS con Terraform, es fundamental entender los conceptos básicos y configurar tu entorno de desarrollo. Terraform utiliza un lenguaje de configuración llamado HashiCorp Configuration Language (HCL), que es declarativo y fácil de leer. Primero, necesitarás instalar Terraform y configurar tus credenciales de AWS.
Instalación de Terraform y Configuración de AWS CLI
La instalación de Terraform es sencilla y multiplataforma. Puedes descargar el binario directamente desde el sitio web de HashiCorp o usar un gestor de paquetes. Para macOS, por ejemplo, se usa Homebrew:
EXPLICACIÓN DEL CÓDIGO
Este comando instala Terraform en sistemas macOS usando Homebrew.
brew tap hashicorp/tap
brew install hashicorp/tap/terraformPara interactuar con AWS, necesitarás el AWS Command Line Interface (CLI) configurado. Asegúrate de tener una cuenta de AWS activa y credenciales de usuario IAM con los permisos adecuados. Configura el CLI ejecutando aws configure y proporcionando tu Access Key ID, Secret Access Key, región por defecto y formato de salida.
EXPLICACIÓN DEL CÓDIGO
Ejemplo de configuración del AWS CLI, solicitando credenciales y región. Es crucial usar las credenciales de un usuario IAM con permisos mínimos necesarios.
$ aws configure
AWS Access Key ID [****************ABCD]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [****************ABCD]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [us-east-1]: eu-west-1
Default output format [json]: jsonCreando tu Primer Recurso AWS con Terraform: Un S3 Bucket
Creemos un simple bucket de S3. Crea un archivo llamado main.tf en un directorio vacío.
EXPLICACIÓN DEL CÓDIGO
Este bloque de código define el proveedor de AWS y un bucket de S3 con una política de bloqueo de acceso público, un estándar de seguridad recomendado en 2026.
# main.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "mi_bucket_ejemplo" {
bucket = "kwonsejo-mi-bucket-ejemplo-2026" # Los nombres de bucket deben ser globalmente únicos
}
resource "aws_s3_bucket_acl" "mi_bucket_ejemplo_acl" {
bucket = aws_s3_bucket.mi_bucket_ejemplo.id
acl = "private"
}
resource "aws_s3_bucket_public_access_block" "mi_bucket_ejemplo_public_access_block" {
bucket = aws_s3_bucket.mi_bucket_ejemplo.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
output "bucket_name" {
description = "El nombre del bucket S3 creado."
value = aws_s3_bucket.mi_bucket_ejemplo.bucket
}
output "bucket_arn" {
description = "El ARN del bucket S3 creado."
value = aws_s3_bucket.mi_bucket_ejemplo.arn
}El Ciclo de Vida de Terraform: Init, Plan, Apply
Una vez que tienes tu archivo main.tf, sigue estos pasos:
1
Inicializar Terraform
Ejecuta terraform init. Esto descarga los plugins del proveedor de AWS necesarios para interactuar con sus servicios y configura el backend.
2
Planificar el Despliegue
Ejecuta terraform plan. Este comando genera un plan de ejecución que muestra qué acciones (crear, modificar, destruir) realizará Terraform para alcanzar el estado deseado. Es crucial revisar este plan para evitar sorpresas.
3
Aplicar los Cambios
Ejecuta terraform apply. Terraform te pedirá confirmación antes de ejecutar el plan. Una vez confirmado, creará el bucket de S3 en tu cuenta de AWS.
4
Destruir la Infraestructura
Para eliminar los recursos creados, ejecuta terraform destroy. Esto eliminará todos los recursos gestionados por este archivo main.tf, lo que es útil para entornos de prueba o para limpiar recursos no deseados.

PUNTO CLAVE
El ciclo de vida de Terraform (init, plan, apply) es fundamental para una gestión controlada y predecible de la infraestructura en AWS. Siempre revisa el plan antes de apply.
CONTENIDO PRINCIPAL
Conceptos Avanzados de Terraform para Escalabilidad y Reusabilidad
Para construir infraestructuras complejas y mantenibles, es crucial ir más allá de los conceptos básicos. Terraform ofrece varias características avanzadas que promueven la modularidad, la reusabilidad y la colaboración en equipos grandes.
Variables, Outputs y Data Sources
Las variables permiten parametrizar tus configuraciones, haciendo que tus módulos sean más flexibles y reusables. Los outputs exponen información sobre los recursos creados, que puede ser consumida por otros módulos o por el usuario final. Los data sources permiten a Terraform leer información de recursos existentes en AWS que no fueron creados por Terraform.
EXPLICACIÓN DEL CÓDIGO
Este ejemplo muestra cómo definir una variable para la región de AWS, usarla en el proveedor y luego exponer el ARN del bucket como una salida. También se usa un data source para obtener información sobre las zonas de disponibilidad de AWS.
# variables.tf
variable "aws_region" {
description = "La región de AWS donde se desplegarán los recursos."
type = string
default = "eu-west-1"
}
# main.tf (modificado)
provider "aws" {
region = var.aws_region
}
resource "aws_s3_bucket" "mi_bucket_ejemplo" {
bucket = "kwonsejo-mi-bucket-ejemplo-con-var-2026"
}
data "aws_availability_zones" "disponibles" {
state = "available"
}
output "bucket_id_con_var" {
description = "El ID del bucket S3 creado usando una variable."
value = aws_s3_bucket.mi_bucket_ejemplo.id
}
output "available_azs" {
description = "Zonas de disponibilidad disponibles en la región."
value = data.aws_availability_zones.disponibles.names
}Módulos: La Clave de la Reusabilidad
Los módulos son la forma en que Terraform organiza y reutiliza el código. Permiten encapsular un conjunto de recursos relacionados en una unidad lógica que puede ser instanciada múltiples veces con diferentes parámetros. Esto es ideal para componentes comunes como VPCs, grupos de seguridad o configuraciones de bases de datos.
Puedes crear tus propios módulos locales o utilizar módulos de registro públicos, como los del Terraform Registry, que ofrecen soluciones predefinidas y bien probadas para una amplia gama de servicios AWS.
EXPLICACIÓN DEL CÓDIGO
Este ejemplo muestra cómo se define y se consume un módulo local simple para crear un bucket S3. La estructura de directorios sería ./modules/s3_bucket/main.tf y luego se llama desde el root.
# modules/s3_bucket/main.tf
resource "aws_s3_bucket" "this" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_acl" "this" {
bucket = aws_s3_bucket.this.id
acl = "private"
}
resource "aws_s3_bucket_public_access_block" "this" {
bucket = aws_s3_bucket.this.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
output "bucket_id" {
value = aws_s3_bucket.this.id
}
output "bucket_arn" {
value = aws_s3_bucket.this.arn
}
# modules/s3_bucket/variables.tf
variable "bucket_name" {
description = "Nombre único del bucket S3."
type = string
}
# root/main.tf
provider "aws" {
region = "eu-west-1"
}
module "app_bucket" {
source = "./modules/s3_bucket"
bucket_name = "kwonsejo-app-bucket-2026"
}
module "logs_bucket" {
source = "./modules/s3_bucket"
bucket_name = "kwonsejo-logs-bucket-2026"
}
output "app_bucket_arn" {
value = module.app_bucket.bucket_arn
}Gestión de Estados Remotos y Workspaces
El archivo de estado de Terraform (terraform.tfstate) es crucial, ya que mapea los recursos reales de la nube con tu configuración. En un entorno de equipo o de producción, almacenar este archivo localmente es arriesgado. Se recomienda usar un backend remoto, como un bucket S3 de AWS, para almacenar el estado de forma segura y habilitar el bloqueo de estado para evitar conflictos.
EXPLICACIÓN DEL CÓDIGO
Configuración de un backend S3 para el estado de Terraform. Es crucial tener un bucket S3 ya creado para este propósito, preferiblemente con versionado habilitado y cifrado. También se recomienda un DynamoDB para el bloqueo de estado.
# backend.tf (o main.tf)
terraform {
backend "s3" {
bucket = "kwonsejo-terraform-state-2026" # Asegúrate de que este bucket exista
key = "path/to/my/app/terraform.tfstate"
region = "eu-west-1"
encrypt = true
dynamodb_table = "kwonsejo-terraform-locks-2026" # Asegúrate de que esta tabla DynamoDB exista
}
}Los workspaces de Terraform (terraform workspace) permiten gestionar múltiples instancias de la misma configuración, por ejemplo, para entornos de desarrollo, staging y producción. Cada workspace tiene su propio archivo de estado, lo que permite mantenerlos aislados.
EXPLICACIÓN DEL CÓDIGO
Estos comandos muestran cómo crear, seleccionar y listar workspaces. Esto es ideal para entornos como dev, staging y prod.
# Crear un nuevo workspace
terraform workspace new dev
# Listar los workspaces existentes
terraform workspace list
# Seleccionar un workspace
terraform workspace select prod
PUNTO CLAVE
La modularización con modules, la parametrización con variables y la gestión de estados remotos con backends son pilares para construir infraestructuras AWS escalables y colaborativas con Terraform.
CONTENIDO PRINCIPAL
Gestión de Recursos AWS Comunes con Terraform
Terraform es capaz de gestionar prácticamente cualquier servicio de AWS. Aquí cubriremos algunos de los recursos más utilizados y cómo definirlos en HCL.
Redes: VPC, Subredes y Grupos de Seguridad
Una Virtual Private Cloud (VPC) es tu red aislada en AWS. Dentro de la VPC, defines subredes para segmentar tu red y grupos de seguridad (Security Groups) para actuar como firewalls virtuales a nivel de instancia.
EXPLICACIÓN DEL CÓDIGO
Este fragmento crea una VPC con un bloque CIDR específico, dos subredes (pública y privada) y un grupo de seguridad que permite tráfico HTTP/S y SSH. La etiqueta Name es crucial para la identificación.
# main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "kwonsejo-vpc-2026"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "eu-west-1a" # Asegúrate de que esta AZ esté disponible en tu región
tags = {
Name = "kwonsejo-public-subnet-2026"
}
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "eu-west-1b" # Asegúrate de que esta AZ esté disponible en tu región
tags = {
Name = "kwonsejo-private-subnet-2026"
}
}
resource "aws_security_group" "web_sg" {
vpc_id = aws_vpc.main.id
name = "kwonsejo-web-sg-2026"
description = "Permitir tráfico web y SSH"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Restringir en producción
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "kwonsejo-web-sg-2026"
}
}Instancias EC2 y Auto Scaling Groups
Las instancias EC2 son los servidores virtuales de AWS. Para alta disponibilidad y escalabilidad, se suelen desplegar dentro de un Auto Scaling Group (ASG) detrás de un Load Balancer.
EXPLICACIÓN DEL CÓDIGO
Este código define una configuración de lanzamiento para EC2 y un Auto Scaling Group que mantiene al menos una instancia t2.micro en una subred pública. Se usa un user_data para instalar Nginx al iniciar la instancia.
# main.tf (continuación)
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
resource "aws_launch_configuration" "web_lc" {
name_prefix = "kwonsejo-web-lc-2026-"
image_id = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
security_groups = [aws_security_group.web_sg.id]
key_name = "tu-clave-ssh" # Reemplaza con tu clave SSH
associate_public_ip_address = true
user_data = <<-EOF
#!/bin/bash
sudo apt update -y
sudo apt install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx
echo "<h1>Hola desde Kwonsejo en $(hostname -f)</h1>" | sudo tee /var/www/html/index.nginx-debian.html
EOF
}
resource "aws_autoscaling_group" "web_asg" {
launch_configuration = aws_launch_configuration.web_lc.name
vpc_zone_identifier = [aws_subnet.public.id] # Asocia con la subred pública
min_size = 1
max_size = 3
desired_capacity = 1
tag {
key = "Name"
value = "kwonsejo-web-instance-2026"
propagate_at_launch = true
}
}Bases de Datos RDS
Amazon RDS (Relational Database Service) facilita la configuración, operación y escalado de bases de datos relacionales. Puedes aprovisionar diferentes motores de base de datos como MySQL, PostgreSQL, etc.
EXPLICACIÓN DEL CÓDIGO
Este ejemplo crea un grupo de subredes para RDS (que abarca múltiples AZs para alta disponibilidad) y una instancia de base de datos MySQL pequeña. Es crucial almacenar las credenciales de la base de datos de forma segura, no directamente en el código HCL (por ejemplo, usando AWS Secrets Manager).
# main.tf (continuación)
resource "aws_db_subnet_group" "rds_subnet_group" {
name = "kwonsejo-rds-subnet-group-2026"
subnet_ids = [aws_subnet.private.id, aws_subnet.public.id] # Incluye subredes en diferentes AZs
tags = {
Name = "kwonsejo-rds-subnet-group-2026"
}
}
resource "aws_db_instance" "mysql_db" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "8.0.28"
instance_class = "db.t3.micro"
name = "kwonsejodb"
username = "admin"
password = "SuperSecretPassword2026" # ¡Usar Secrets Manager en producción!
port = 3306
vpc_security_group_ids = [aws_security_group.web_sg.id] # Asocia un SG para el acceso a la DB
db_subnet_group_name = aws_db_subnet_group.rds_subnet_group.name
skip_final_snapshot = true
publicly_accessible = false # Mantener la DB privada es una buena práctica de seguridad
tags = {
Name = "kwonsejo-mysql-db-2026"
}
}
Tabla Comparativa: Herramientas IaC para AWS (2026)
Aunque Terraform es una opción excelente, no es la única herramienta de IaC. Aquí hay una comparación rápida con otras opciones populares en el entorno AWS.
Comparación de Herramientas IaC
Terraform — Multi-cloud, declarativo, HCL. Gran ecosistema y comunidad. Ideal para entornos híbridos y complejos.
AWS CloudFormation — Específico de AWS, declarativo, YAML/JSON. Integración nativa con AWS, control de versiones de plantillas, StackSets.
AWS CDK (Cloud Development Kit) — Específico de AWS, imperativo/declarativo (construye CloudFormation), lenguajes de programación (Python, TypeScript, Java, etc.). Permite usar lógica de programación para definir la infraestructura.
Ansible — Multi-cloud, imperativo, YAML. Más orientado a la configuración de servidores y despliegue de software que al aprovisionamiento de infraestructura base.
PUNTO CLAVE
Terraform destaca por su capacidad multi-cloud y su lenguaje declarativo HCL, lo que lo hace versátil para gestionar una amplia gama de recursos AWS, desde redes básicas hasta servicios de cómputo y bases de datos.
RESOLUCIÓN DE PROBLEMAS
Resolución de Problemas Comunes y Mejores Prácticas
Trabajar con IaC y Terraform, aunque poderoso, puede presentar desafíos. Conocer los problemas comunes y sus soluciones es clave para una operación fluida.
Desafíos Técnicos y Soluciones
PROBLEMA 01
Drift de Configuración (Configuration Drift)
El drift de configuración ocurre cuando los cambios se realizan manualmente en la consola de AWS o a través de scripts externos, haciendo que el estado real de la infraestructura difiera del estado definido en tus archivos de Terraform.
SOLUCIÓN — Regularmente, ejecuta terraform plan para detectar diferencias. Considera usar terraform refresh (aunque plan lo hace implícitamente) o herramientas de auditoría. Implementa políticas de IAM estrictas para restringir cambios manuales.
terraform plan
terraform refresh # Actualiza el estado local con la infraestructura real sin aplicar cambiosPROBLEMA 02
Gestión de Estados Concurrentes y Bloqueos
Cuando varios desarrolladores intentan aplicar cambios simultáneamente, pueden ocurrir conflictos en el archivo de estado de Terraform, llevando a corrupción del estado o a despliegues inconsistentes.
SOLUCIÓN — Utiliza un backend remoto que soporte bloqueo de estado, como S3 con una tabla DynamoDB. Esto garantiza que solo una operación de Terraform pueda modificar el estado a la vez, previniendo la corrupción. Terraform Cloud/Enterprise ofrece gestión de estado y bloqueos avanzados.
# Configuración del backend S3 con DynamoDB para bloqueo
terraform {
backend "s3" {
bucket = "mi-bucket-estado-terraform"
key = "prod/terraform.tfstate"
region = "eu-west-1"
dynamodb_table = "terraform-state-locks" # Tabla DynamoDB para el bloqueo
}
}PROBLEMA 03
Errores de Aprovisionamiento o Dependencias
Los errores pueden ocurrir si un recurso intenta referenciar a otro que aún no ha sido creado, o si hay un problema con los permisos de AWS o la configuración del recurso.
SOLUCIÓN — Terraform gestiona las dependencias implícitamente la mayoría de las veces. Si un error persiste, puedes usar la propiedad depends_on para forzar un orden de creación explícito. Revisa los logs de Terraform y AWS CloudTrail para identificar la causa raíz. Asegúrate de que las políticas de IAM de tu usuario o rol tengan los permisos correctos para todos los recursos que intentas gestionar.
resource "aws_instance" "web" {
# ...
depends_on = [aws_s3_bucket.logs] # Forzar que el bucket de logs se cree primero
}
PUNTO CLAVE
La adopción de buenas prácticas como el uso de backends remotos con bloqueo de estado, la revisión constante de los planes de ejecución y una gestión granular de permisos de IAM son fundamentales para mitigar los problemas comunes en la gestión de infraestructura AWS con Terraform.
APLICACIÓN PRÁCTICA
Aplicación Práctica: Despliegue de una Aplicación Web en AWS con Terraform
Vamos a consolidar lo aprendido desplegando una aplicación web simple en AWS utilizando Terraform. Esta arquitectura incluirá una VPC, subredes, un Application Load Balancer (ALB) y un Auto Scaling Group de instancias EC2 con Nginx.
Arquitectura de Despliegue
La arquitectura consistirá en:
- VPC Personalizada: Una red aislada.
- Subredes Públicas: Para el ALB e instancias EC2 accesibles desde internet.
- Internet Gateway (IGW): Para permitir la comunicación de la VPC con internet.
- Application Load Balancer (ALB): Distribuye el tráfico entrante a las instancias EC2.
- Auto Scaling Group (ASG): Gestiona un grupo de instancias EC2 para escalabilidad y alta disponibilidad.
- Instancias EC2: Ejecutando Nginx como servidor web.
- Grupos de Seguridad: Para controlar el tráfico de red.

Paso a Paso con Terraform
1
Configuración Inicial y VPC
Define el proveedor de AWS, la VPC, las subredes públicas y el Internet Gateway para permitir la conectividad a internet.
EXPLICACIÓN DEL CÓDIGO
Este código establece la base de red para nuestra aplicación, incluyendo la VPC, subredes en dos Zonas de Disponibilidad (AZs) y un Internet Gateway para la conectividad externa. También define las tablas de ruteo.
# main.tf
provider "aws" {
region = "eu-west-1"
}
resource "aws_vpc" "app_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "kwonsejo-app-vpc-2026"
}
}
resource "aws_internet_gateway" "app_igw" {
vpc_id = aws_vpc.app_vpc.id
tags = {
Name = "kwonsejo-app-igw-2026"
}
}
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_subnet" "public_subnets" {
count = 2
vpc_id = aws_vpc.app_vpc.id
cidr_block = cidrsubnet(aws_vpc.app_vpc.cidr_block, 8, count.index) # 10.0.0.0/24, 10.0.1.0/24
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "kwonsejo-public-subnet-${count.index + 1}-2026"
}
}
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.app_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.app_igw.id
}
tags = {
Name = "kwonsejo-public-rt-2026"
}
}
resource "aws_route_table_association" "public_rt_assoc" {
count = 2
subnet_id = aws_subnet.public_subnets[count.index].id
route_table_id = aws_route_table.public_rt.id
}2
Grupos de Seguridad para ALB y EC2
Configura los grupos de seguridad para permitir el tráfico necesario hacia el ALB y desde el ALB hacia las instancias EC2.
EXPLICACIÓN DEL CÓDIGO
Definimos dos grupos de seguridad: uno para el ALB que permite tráfico HTTP/S desde cualquier lugar, y otro para las instancias EC2 que solo permite tráfico HTTP/S desde el ALB y SSH para administración (restringir en producción).
# main.tf (continuación)
resource "aws_security_group" "alb_sg" {
vpc_id = aws_vpc.app_vpc.id
name = "kwonsejo-alb-sg-2026"
description = "Permitir tráfico HTTP/S hacia el ALB"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "kwonsejo-alb-sg-2026"
}
}
resource "aws_security_group" "ec2_sg" {
vpc_id = aws_vpc.app_vpc.id
name = "kwonsejo-ec2-sg-2026"
description = "Permitir tráfico desde el ALB y SSH"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.alb_sg.id] # Solo desde el ALB
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
security_groups = [aws_security_group.alb_sg.id] # Solo desde el ALB
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # ¡Restringir en producción!
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "kwonsejo-ec2-sg-2026"
}
}3
Application Load Balancer (ALB)
Configura el ALB para distribuir el tráfico entrante a un grupo de destino de instancias EC2.
EXPLICACIÓN DEL CÓDIGO
Este bloque crea un ALB, un grupo de destino para nuestras instancias Nginx y un listener HTTP que reenvía el tráfico al grupo de destino. El ALB se despliega en las subredes públicas.
# main.tf (continuación)
resource "aws_lb" "app_alb" {
name = "kwonsejo-app-alb-2026"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb_sg.id]
subnets = [for subnet in aws_subnet.public_subnets : subnet.id] tags = {
Name = "kwonsejo-app-alb-2026"
}
}
resource "aws_lb_target_group" "app_tg" {
name = "kwonsejo-app