Concepto clave
En Terraform, los recursos AWS son bloques fundamentales que representan componentes de infraestructura en la nube, como instancias EC2, buckets S3 o VPCs. Cada recurso se define con un tipo especifico (ej: aws_instance) y parametros de configuracion. Los modulos son contenedores reutilizables que agrupan multiples recursos para crear componentes mas complejos, permitiendo encapsular logica y promover la reutilizacion de codigo.
Piensa en los recursos como piezas individuales de Lego: cada una tiene una funcion especifica (un bloque, una rueda, una ventana). Los modulos son como sets pre-ensamblados de Lego que combinan multiples piezas para crear estructuras complejas como una casa o un vehiculo, que puedes reutilizar en diferentes proyectos sin reconstruir desde cero cada vez.
Como funciona en la practica
Cuando defines un recurso en Terraform, declaras el estado deseado de tu infraestructura. Terraform compara esta declaracion con el estado actual y genera un plan de ejecucion para alcanzar ese estado. Los modulos permiten organizar estos recursos logicamente: por ejemplo, un modulo 'network' podria contener todos los recursos relacionados con VPC, subnets y gateways.
Paso a paso: 1) Defines un recurso basico como una instancia EC2. 2) Identificas patrones repetitivos en tu codigo. 3) Refactorizas esos patrones en un modulo. 4) Reutilizas el modulo en diferentes entornos (dev, staging, prod) con diferentes parametros.
Codigo en accion
Antes: Recursos definidos directamente en el archivo principal
# main.tf - Version sin modulos
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "public-subnet"
}
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
tags = {
Name = "private-subnet"
}
}Despues: Usando un modulo para la red
# main.tf - Version con modulo
module "network" {
source = "./modules/network"
vpc_cidr = "10.0.0.0/16"
public_cidr = "10.0.1.0/24"
private_cidr = "10.0.2.0/24"
environment = "production"
}
# modules/network/main.tf
resource "aws_vpc" "this" {
cidr_block = var.vpc_cidr
tags = {
Name = "${var.environment}-vpc"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.this.id
cidr_block = var.public_cidr
tags = {
Name = "${var.environment}-public-subnet"
}
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.this.id
cidr_block = var.private_cidr
tags = {
Name = "${var.environment}-private-subnet"
}
}Errores comunes
- No usar outputs en modulos: Olvidar definir outputs en modulos limita su reutilizacion. Siempre expone los IDs de recursos creados para que otros modulos puedan referenciarlos.
- Hardcodear valores en modulos: Usar valores fijos en lugar de variables hace que los modulos sean inflexibles. Parametriza todo lo que pueda variar entre implementaciones.
- Ignorar el estado de Terraform: No versionar el archivo de estado (.tfstate) o no usar backend remoto puede causar conflictos en equipos. Usa S3 con DynamoDB para bloqueo de estado.
- Crear modulos demasiado especificos: Modulos que hacen demasiado son dificiles de reutilizar. Diseña modulos que hagan una cosa bien y sean composibles.
- No probar modulos aisladamente: Implementar modulos directamente en infraestructura productiva sin pruebas unitarias. Crea ejemplos de uso y prueba con terraform plan antes de integrar.
Checklist de dominio
- Puedo definir al menos 5 tipos diferentes de recursos AWS en Terraform (EC2, S3, RDS, VPC, IAM)
- Comprendo la diferencia entre argumentos requeridos y opcionales en definiciones de recursos
- He creado y utilizado al menos un modulo propio con variables y outputs
- Puedo explicar cuando es apropiado refactorizar recursos en un modulo
- Se como referenciar outputs de un modulo en otro modulo o recurso
- Puedo usar count o for_each para crear multiples instancias de un recurso
- Comprendo el ciclo de vida de un recurso: plan, apply, destroy
Refactorizacion de infraestructura EC2 a modulo reutilizable
En este ejercicio, transformaras una configuracion basica de EC2 en un modulo reutilizable que pueda desplegarse en multiples entornos.
- Analiza la configuracion inicial: Examina el siguiente codigo que define una instancia EC2 con seguridad basica:
- Crea la estructura del modulo: Crea un directorio llamado 'modules/ec2-instance' con los archivos: main.tf, variables.tf, outputs.tf
- Parametriza el modulo: Identifica que valores deberian ser variables (ej: ami, instance_type, environment, puertos de ingress)
- Implementa el modulo: Mueve los recursos al modulo y asegurate de que todas las dependencias esten correctamente referenciadas
- Usa el modulo: Crea un archivo principal que use tu modulo para desplegar 2 instancias: una para 'staging' y otra para 'production' con diferentes AMIs
- Verifica: Ejecuta 'terraform plan' para confirmar que el modulo funciona correctamente sin errores
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
subnet_id = "subnet-abc123"
tags = {
Name = "production-web-server"
Environment = "production"
}
}
resource "aws_security_group" "web_sg" {
name = "web-security-group"
description = "Security group for web server"
ingress {
from_port = 80
to_port = 80
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"]
}
}- Piensa en que valores podrian cambiar entre entornos (dev/staging/prod) - esos son candidatos a variables
- Recuerda que los security groups necesitan referenciar el VPC ID si no esta en el modulo, considera si debes incluirlo como variable
- Usa count o for_each en el modulo principal para crear multiples instancias con diferentes parametros
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.