Lección 3 de 312 min
Infraestructura como código
Describir servidores y redes en archivos versionados con Terraform, AWS CloudFormation y AWS CDK.
Montaste el entorno de producción a base de clics en la consola de AWS: una VPC, dos subredes, la base de datos, el bucket y los permisos. Funciona. Seis meses después necesitas un entorno de pruebas idéntico y nadie recuerda qué casillas se marcaron, ni por qué cierto security group tiene abierto el puerto 8080.
La infraestructura como código (IaC) resuelve esto describiendo servidores, redes y permisos en archivos de texto que se versionan en Git, se revisan en pull requests y se aplican con un comando. En esta lección verás las tres herramientas más habituales en AWS: Terraform, CloudFormation y CDK.
Qué es la infraestructura como código
Infraestructura como código
Describir la infraestructura en archivos versionados que una herramienta convierte en realidad.
- Estilo habitual:
- Declarativo
- Herramientas:
- Terraform, CloudFormation, CDK, Pulumi
Hay dos estilos. En el imperativo escribes los pasos («crea una VPC, luego una subred…»), como en un script de la CLI. En el declarativo describes el resultado («quiero una VPC con dos subredes») y la herramienta calcula qué crear, cambiar o borrar para llegar ahí. Casi todas las herramientas de IaC actuales son declarativas.
Lo declarativo da idempotencia: aplicar dos veces el mismo archivo deja el mismo resultado, sin duplicar nada. También permite detectar la deriva (drift): cuando alguien cambia algo a mano en la consola, la herramienta ve la diferencia entre el código y la realidad.
Y como es código, sigue el mismo flujo que tu aplicación: un pull request muestra qué recursos se van a crear o destruir, alguien lo revisa y el pipeline lo aplica. Lo verás en el módulo de CI/CD.
Úsalo cuando
En cuanto tengas más de un entorno, más de una persona tocando la infraestructura o necesites saber quién cambió qué y cuándo. Es decir, casi siempre.
Ten en cuenta
Mezclar código y clics es la receta del desastre: si alguien arregla algo a mano, el siguiente despliegue puede deshacerlo sin avisar. Acuerda con tu equipo que los cambios se hacen solo por código.
# Imperativo: ejecútalo dos veces y tendrás dos servidores
aws ec2 run-instances --image-id ami-0123456789abcdef0 --instance-type t3.micro
# Declarativo (Terraform): aplícalo dos veces y seguirá habiendo uno
resource "aws_instance" "web" {
ami = "ami-0123456789abcdef0"
instance_type = "t3.micro"
}Terraform
Terraform
IaC declarativa para casi cualquier proveedor, en HCL y con un plan antes de cada cambio.
- Lenguaje:
- HCL
- Creado por:
- HashiCorp
- Fork abierto:
- OpenTofu
Terraform, de HashiCorp, describe la infraestructura en HCL, un lenguaje de configuración legible. Cada servicio se gestiona a través de un provider, un plugin que traduce tus recursos a llamadas a su API. Hay providers para AWS, Google Cloud, Azure, Cloudflare, GitHub, Vercel y cientos más, así que un mismo proyecto puede crear un bucket en AWS y su registro DNS en Cloudflare.
El flujo es siempre el mismo: terraform init descarga los providers, terraform plan compara tu código con lo que existe y muestra qué va a crear (+), cambiar (~) o destruir (-), y terraform apply lo ejecuta tras tu confirmación.
En 2023, HashiCorp cambió la licencia de Terraform por una que ya no se considera de código abierto. En respuesta, parte de la comunidad creó OpenTofu, un fork abierto bajo el paraguas de la Linux Foundation que usa el mismo lenguaje y es compatible en gran medida, aunque con el tiempo cada proyecto va añadiendo funciones propias.
Úsalo cuando
Cuando gestionas recursos de varios proveedores, quieres una sola herramienta para varias nubes o tu equipo ya la conoce. Es una de las herramientas de IaC más extendidas.
Ten en cuenta
Lee el plan entero antes de aplicar: un cambio inocente, como renombrar un recurso, puede aparecer como «destruir y volver a crear», y en una base de datos eso significa perder datos (para renombrar sin destruir existe el bloque moved). Fija las versiones de Terraform y de los providers para que el plan no cambie de un día para otro.
terraform {
required_providers {
aws = { source = "hashicorp/aws" } # fija aquí también la versión
}
}
provider "aws" {
region = "eu-west-1"
}
resource "aws_s3_bucket" "fotos" {
bucket = "fotos-tienda-2026"
}
resource "aws_s3_bucket_versioning" "fotos" {
bucket = aws_s3_bucket.fotos.id
versioning_configuration { status = "Enabled" }
}El estado de Terraform
El archivo donde Terraform recuerda qué recurso real corresponde a cada bloque de tu código.
- Archivo:
- terraform.tfstate
- En equipo:
- Backend remoto con bloqueo
Terraform guarda en el estado (terraform.tfstate) la correspondencia entre tus recursos y los reales: «aws_s3_bucket.fotos es el bucket fotos-tienda-2026», con todos sus atributos. Sin él no sabría si algo ya existe ni podría calcular el plan.
En equipo, el estado no puede vivir en el portátil de nadie: se guarda en un backend remoto, como un bucket de S3 o HCP Terraform. El backend debe ofrecer bloqueo (locking): mientras alguien ejecuta apply, nadie más puede modificar el estado, porque dos ejecuciones simultáneas lo corromperían. Con S3, las versiones recientes de Terraform bloquean con un archivo en el propio bucket; antes hacía falta una tabla de DynamoDB.
Úsalo cuando
Desde el primer día de trabajo en equipo o en CI: configura el backend remoto antes de crear el primer recurso de producción.
Ten en cuenta
El estado contiene datos sensibles en texto plano, como contraseñas generadas: no lo subas a Git, cifra el bucket y limita quién puede leerlo. Nunca lo edites a mano; para casos especiales existen comandos como terraform state mv o terraform import.
terraform {
backend "s3" {
bucket = "estado-terraform-tienda"
key = "produccion/terraform.tfstate"
region = "eu-west-1"
encrypt = true
use_lockfile = true # bloqueo con un archivo en el propio bucket
}
}Las herramientas de AWS: CloudFormation y CDK
AWS CloudFormation
El servicio de IaC nativo de AWS: plantillas YAML o JSON que se despliegan como pilas.
- Unidad:
- Pila (stack)
- Vista previa:
- Change sets
En CloudFormation escribes una plantilla en YAML o JSON con los recursos (Resources), los parámetros de entrada (Parameters) y los valores de salida (Outputs). Al desplegarla creas una pila (stack): el conjunto de recursos que CloudFormation gestiona como una unidad. El estado lo guarda AWS, no tú.
Antes de modificar una pila puedes crear un conjunto de cambios (change set), el equivalente al plan de Terraform: muestra qué se añadirá, modificará o reemplazará. Si algo falla a mitad del despliegue, CloudFormation hace rollback automático y deja la pila como estaba.
Úsalo cuando
Cuando todo está en AWS y quieres una herramienta sin estado que gestionar, con soporte oficial y sin coste adicional: pagas solo los recursos.
Ten en cuenta
Está pensada para AWS, y las plantillas se vuelven largas y repetitivas: un servicio sencillo puede ocupar cientos de líneas. Un rollback que también falla puede dejar la pila en un estado del que cuesta salir. Para no escribir tanto YAML existe CDK.
Parameters:
Entorno:
Type: String
AllowedValues: [pruebas, produccion]
Resources:
BucketFotos:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "fotos-tienda-${Entorno}"
VersioningConfiguration:
Status: Enabled
Outputs:
NombreBucket:
Value: !Ref BucketFotos
# aws cloudformation deploy --template-file plantilla.yaml \
# --stack-name fotos-pruebas --parameter-overrides Entorno=pruebasAWS CDK
Infraestructura en TypeScript o Python que se convierte en plantillas de CloudFormation.
- Lenguajes:
- TypeScript, Python, Java, C#, Go
- Genera:
- Plantillas de CloudFormation
El CDK (Cloud Development Kit) te permite definir la infraestructura con un lenguaje de programación: TypeScript, Python, Java, C# o Go. Al ejecutar cdk synth, tu programa genera (sintetiza) una plantilla de CloudFormation, y cdk deploy la despliega. Por debajo sigue siendo CloudFormation, con sus pilas y sus rollbacks.
Las piezas se llaman constructs y tienen tres niveles. Los L1 son la traducción literal de cada recurso de CloudFormation (CfnBucket). Los L2 añaden valores por defecto sensatos y métodos útiles: bucket.grantRead(funcion) genera la política de IAM por ti. Los L3 son patrones completos, como «un servicio en Fargate con su balanceador».
Úsalo cuando
Si tu equipo prefiere programar a escribir YAML, quiere reutilizar componentes como librerías o aprovechar bucles, tipos y autocompletado. Y todo está en AWS.
Ten en cuenta
Un programa puede hacer cualquier cosa, incluida una infraestructura difícil de entender: mantén el código simple y revisa el resultado con cdk diff antes de desplegar. Cada cuenta y región necesita un cdk bootstrap previo, y heredas los límites de CloudFormation.
import { App, Stack, RemovalPolicy } from "aws-cdk-lib";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as lambda from "aws-cdk-lib/aws-lambda";
const app = new App();
const pila = new Stack(app, "FotosStack");
const bucket = new s3.Bucket(pila, "Fotos", {
versioned: true,
removalPolicy: RemovalPolicy.RETAIN, // no lo borres al destruir la pila
});
const miniaturas = new lambda.Function(pila, "Miniaturas", {
runtime: lambda.Runtime.NODEJS_22_X,
handler: "index.handler",
code: lambda.Code.fromAsset("lambda/miniaturas"),
});
bucket.grantRead(miniaturas); // L2: genera la política de IAM por tiNota
No son del todo excluyentes: hay equipos que gestionan la red y las cuentas con Terraform y los servicios de cada aplicación con CDK. Lo importante es que cada recurso tenga un único dueño: si dos herramientas gestionan el mismo bucket, acabarán pisándose.
Interactivo
Terraform, CloudFormation y CDK
Activa o desactiva opciones para compararlas cara a cara.
| Característica | Terraform | CloudFormation | AWS CDK |
|---|---|---|---|
| Lenguaje | HCL | YAML o JSON | TypeScript, Python, Java, C# o Go |
| Proveedores | AWS y cientos más | AWS | AWS |
| Dónde vive el estado | En un archivo de estado, en el backend que elijas | Lo gestiona AWS | Lo gestiona AWS, a través de CloudFormation |
| Ver los cambios antes | terraform plan | Change sets | cdk diff |
| Si falla a mitad | Se queda donde llegó: corriges y vuelves a aplicar | Rollback automático | Rollback automático, porque es CloudFormation |
| Encaja con | Varias nubes o proveedores | Equipos solo en AWS que prefieren plantillas | Equipos solo en AWS que prefieren programar |
Ponlo en práctica
Saber qué es cada cosa es la mitad del trabajo. La otra mitad es reconocer cuándo usarla.
Interactivo
¿Qué usarías?
Lee cada situación y elige la opción que mejor la resuelve. Fallar aquí no cuenta: es para practicar.
En el mismo proyecto necesitas crear un bucket en AWS, los registros DNS en Cloudflare y los equipos de tu organización en GitHub.
Para recordar
- Con IaC la infraestructura se describe en archivos versionados, se revisa en pull requests y se aplica con un comando, siempre igual.
- Declarativo e idempotente: describes el resultado, la herramienta calcula los cambios y aplicarlo dos veces no duplica nada.
- Terraform, y su fork abierto OpenTofu, sirven para casi cualquier proveedor; su estado va en un backend remoto, con bloqueo y fuera de Git.
- CloudFormation es la IaC nativa de AWS, con change sets y rollback automático; CDK te deja escribirla en TypeScript o Python.
- Lee siempre el plan antes de aplicar: un «reemplazar» en una base de datos puede significar perder datos.
Comprueba lo aprendido
Cuestionario
Responde las 5 preguntas para completar la lección.
1.¿Qué significa que una herramienta de IaC sea idempotente?
2.En la salida de
terraform planves queaws_db_instance.principal«must be replaced» (-/+). ¿Qué deberías pensar?3.¿Por qué no se debe subir
terraform.tfstatea Git?4.¿Qué relación hay entre AWS CDK y CloudFormation?
5.¿Qué es un change set de CloudFormation?