Concepto clave
En DevOps, la infraestructura como código (IaC) transforma la gestión de recursos cloud de un proceso manual y propenso a errores en uno automatizado y repetible. Terraform es una herramienta clave que permite definir, aprovisionar y gestionar infraestructura mediante archivos de configuración declarativos. Imagina que construir un entorno web en AWS es como armar un mueble de IKEA: sin instrucciones, es caótico; con un manual claro (tu código Terraform), cualquier persona puede replicar el mismo resultado de forma consistente.
En esta lección, aprenderás a orquestar tres servicios AWS fundamentales: EC2 para servidores web, S3 para almacenamiento estático, y RDS para bases de datos. La magia de Terraform está en su capacidad de gestionar dependencias entre recursos: por ejemplo, asegura que la base de datos RDS esté disponible antes de que la instancia EC2 intente conectarse a ella, evitando fallos en el despliegue.
Cómo funciona en la práctica
El flujo típico implica cuatro pasos: 1) Escribir archivos .tf que definen los recursos AWS, 2) Ejecutar terraform init para inicializar el proyecto y descargar proveedores, 3) Usar terraform plan para revisar los cambios propuestos sin aplicarlos, y 4) Aplicar con terraform apply para crear la infraestructura real. Por ejemplo, para un entorno web básico, definirías una VPC, subredes, un grupo de seguridad para EC2, la instancia misma, un bucket S3 para assets, y una instancia RDS MySQL.
Un aspecto crítico es el uso de módulos de Terraform, que son contenedores reutilizables de configuración. En lugar de escribir todo desde cero, puedes usar módulos de la comunidad (como los de Terraform Registry) o crear los tuyos propios para encapsular configuraciones comunes, como una "plantilla" de instancia EC2 con ciertas políticas IAM adjuntas. Esto acelera el desarrollo y estandariza las implementaciones.
Código en acción
Aquí tienes un ejemplo básico de un archivo main.tf que define una instancia EC2 con un bucket S3 asociado. Nota cómo se usa el proveedor AWS y se referencian recursos entre sí:
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "web_assets" {
bucket = "mi-bucket-web-${random_id.suffix.hex}"
acl = "private"
tags = {
Name = "Assets del sitio web"
}
}
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2
instance_type = "t2.micro"
key_name = "mi-key-pair"
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
EOF
tags = {
Name = "Servidor Web"
}
}
resource "random_id" "suffix" {
byte_length = 4
}Ahora, mejoremos esto refactorizando en un módulo. Antes: Código monolítico en un solo archivo. Después: Separamos la configuración en módulos reutilizables. Crea una carpeta modules/ec2 con su propio main.tf:
# modules/ec2/main.tf
variable "ami_id" {
type = string
default = "ami-0c55b159cbfafe1f0"
}
variable "instance_type" {
type = string
default = "t2.micro"
}
resource "aws_instance" "this" {
ami = var.ami_id
instance_type = var.instance_type
# ... más configuraciones
}
output "instance_id" {
value = aws_instance.this.id
}Luego, en tu raíz, llamas al módulo así:
module "web_server" {
source = "./modules/ec2"
ami_id = "ami-0c55b159cbfafe1f0"
}Errores comunes
- No gestionar el estado de Terraform: El archivo
terraform.tfstateguarda el estado real de tu infraestructura. Si lo pierdes o no lo versionas (por ejemplo, en S3 con bloqueo DynamoDB), puedes causar inconsistencias graves. Solución: Configura siempre un backend remoto. - Hardcodear valores sensibles: Incluir contraseñas o keys directamente en el código es un riesgo de seguridad. En su lugar, usa variables de entorno, AWS Secrets Manager, o el bloque
sensitive = trueen Terraform. - Ignorar las dependencias implícitas: Terraform deduce dependencias basado en referencias, pero a veces necesitas
depends_onexplícito. Por ejemplo, si EC2 depende de un rol IAM que se crea en otro recurso, asegúrate de declararlo. - No usar
terraform planantes de apply: Aplicar cambios sin revisarlos puede llevar a costos inesperados o tiempo de inactividad. Siempre ejecutaplanpara previsualizar. - Olvidar etiquetar recursos: Las etiquetas (tags) son cruciales para gestión de costos y organización en AWS. Incluye al menos
NameyEnvironmenten todos los recursos.
Checklist de dominio
- Puedo escribir un archivo Terraform que despliegue una instancia EC2 con un grupo de seguridad personalizado.
- Sé configurar un backend remoto en S3 para el estado de Terraform, con bloqueo DynamoDB.
- Puedo crear y usar un módulo de Terraform para encapsular lógica común, como una configuración de VPC.
- Entiendo cómo manejar salidas (outputs) de módulos para pasar información entre recursos.
- Puedo integrar RDS en mi configuración, manejando contraseñas de forma segura con AWS Secrets Manager.
- Sé usar
terraform destroypara limpiar recursos y evitar costos innecesarios. - Puedo leer y depurar errores comunes de Terraform, como problemas de sintaxis HCL o permisos IAM insuficientes.
Despliega un entorno web completo con EC2, S3 y RDS usando módulos
Objetivo: Crear una infraestructura AWS que incluya un servidor web (EC2), almacenamiento para archivos estáticos (S3), y una base de datos (RDS MySQL), utilizando módulos de Terraform para promover reusabilidad.
- Preparación: Asegúrate de tener AWS CLI configurado con credenciales y Terraform instalado. Crea un directorio nuevo para el proyecto.
- Configura el proveedor y backend: En un archivo
provider.tf, define el proveedor AWS para la regiónus-east-1. Configura un backend remoto en S3 (simulado localmente para este ejercicio, pero menciona cómo sería en producción). - Crea módulos:
- En
modules/ec2, define un módulo para una instancia EC2 con Amazon Linux 2, tipot2.micro, y un script de user_data que instale Apache. - En
modules/s3, define un módulo para un bucket S3 con políticas básicas de acceso privado. - En
modules/rds, define un módulo para una instancia RDS MySQL (db.t2.micro) con almacenamiento de 20 GB.
- En
- Integra los módulos: En el archivo principal
main.tf, llama a los tres módulos. Asegúrate de que el módulo EC2 tenga una dependencia explícita (depends_on) al módulo RDS para garantizar que la base de datos esté lista antes de que el servidor intente conectarse. - Maneja variables y salidas: Usa un archivo
variables.tfpara parámetros como el ID de AMI o la contraseña de RDS (usa valores por defecto seguros). Enoutputs.tf, expone la IP pública de EC2 y el endpoint de RDS. - Ejecuta y verifica: Corre
terraform init, luegoterraform planpara revisar. Si todo está bien, aplica conterraform apply. Verifica en la consola AWS que los recursos se crearon correctamente. - Limpieza: Al final, ejecuta
terraform destroypara eliminar todos los recursos y evitar cargos.
- Usa el bloque 'resource "aws_db_instance"' en el módulo RDS, y considera agregar un grupo de seguridad que permita tráfico desde EC2.
- Para el user_data en EC2, puedes incluir un comando para descargar un archivo de ejemplo desde el bucket S3 usando AWS CLI.
- Recuerda que en módulos, las variables se definen con 'variable' y se pasan al llamar el módulo; las salidas se definen con 'output' para exponer valores útiles.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.