Infrastructure as Code
Práctica de definir y gestionar infraestructura mediante archivos de configuración versionados en lugar de procesos manuales. Fundamento de la automatización moderna de operaciones.
Infrastructure as Code (IaC) es tratar la infraestructura exactamente como código: versionada en Git, revisada en PRs, testeada en CI, y aplicada de forma automatizada y reproducible.
¿Qué problema resuelve?
Sin IaC:
- Snowflake servers — cada servidor es único, configurado a mano, imposible de reproducir
- Configuration drift — los entornos divergen silenciosamente
- Documentación desactualizada — el wiki dice una cosa, la realidad es otra
- Auditoría imposible — ¿quién cambió qué, cuándo, por qué?
- Disaster recovery lento — reconstruir manualmente toma horas o días
Con IaC: terraform apply y la infraestructura completa se recrea en minutos.
Enfoques
Declarativo vs imperativo
| Enfoque | Descripción | Herramientas |
|---|---|---|
| Declarativo | Describes el estado deseado, la herramienta calcula cómo llegar | Terraform, CloudFormation, Kubernetes YAML |
| Imperativo | Describes los pasos a ejecutar en orden | Scripts bash, Ansible (parcialmente), Pulumi |
# Declarativo (Terraform) — "quiero esto"
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
}# Imperativo (Pulumi) — "haz esto"
server = aws.ec2.Instance("web",
ami="ami-0c55b159cbfafe1f0",
instance_type="t3.micro")Mutable vs inmutable
- Mutable — actualizar servidores existentes (Ansible, Chef, Puppet)
- Inmutable — destruir y recrear (Terraform + AMIs, contenedores)
La infraestructura inmutable elimina configuration drift por diseño.
Herramientas principales
| Herramienta | Tipo | Cloud | Lenguaje | Estado |
|---|---|---|---|---|
| Terraform | Provisioning | Multi-cloud | HCL | Remote state |
| OpenTofu | Provisioning | Multi-cloud | HCL | Remote state |
| Pulumi | Provisioning | Multi-cloud | TS, Python, Go | Managed/self-hosted |
| AWS CDK | Provisioning | AWS | TS, Python, Java | CloudFormation |
| CloudFormation | Provisioning | AWS | YAML/JSON | AWS-managed |
| Ansible | Config mgmt | Agnostic | YAML | Stateless |
| Crossplane | Provisioning | Multi-cloud | YAML (K8s CRDs) | Kubernetes |
Principios fundamentales
1. Todo en Git
infra/
├── modules/
│ ├── networking/
│ ├── compute/
│ └── database/
├── environments/
│ ├── dev/
│ ├── staging/
│ └── production/
├── .github/workflows/
│ └── terraform.yml
└── README.md
2. Idempotencia
Aplicar el mismo código N veces produce el mismo resultado:
terraform apply # Crea 3 instancias
terraform apply # No changes. Infrastructure is up-to-date.
terraform apply # No changes. Infrastructure is up-to-date.3. State management
El estado es la fuente de verdad sobre qué existe:
# Backend remoto (compartido entre equipo)
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}4. Módulos reutilizables
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "production"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
}5. Plan antes de apply
terraform plan # Ver qué va a cambiar
# + aws_instance.web (create)
# ~ aws_security_group.web (modify)
# - aws_instance.old (destroy)
terraform apply # Aplicar después de revisarPipeline de IaC
# .github/workflows/terraform.yml
name: Terraform
on:
pull_request:
paths: ['infra/**']
push:
branches: [main]
paths: ['infra/**']
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform validate
- run: terraform plan -out=plan.tfplan
- uses: actions/upload-artifact@v4
with:
name: plan
path: plan.tfplan
apply:
needs: plan
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- uses: actions/download-artifact@v4
with:
name: plan
- run: terraform apply plan.tfplanTesting de IaC
| Nivel | Herramienta | Qué valida |
|---|---|---|
| Lint | terraform validate, tflint | Sintaxis y convenciones |
| Static | Checkov, tfsec, Trivy | Seguridad y compliance |
| Unit | Terratest, terraform test | Lógica de módulos |
| Integration | Terratest | Infraestructura real temporal |
| Policy | OPA, Sentinel | Políticas organizacionales |
Anti-patrones
- ClickOps — crear recursos manualmente y luego «importarlos» como parche
- Mega-state — toda la infra en un solo state file. Dividir por dominio/entorno.
- Sin locks — dos personas aplicando simultáneamente corrompen el estado
- Hardcoded values — usar variables y tfvars para parametrizar
- Sin plan review — aplicar sin revisar el plan es como mergear sin code review
- Ignorar drift — no detectar cambios manuales que divergen del código
¿Por qué importa?
Sin IaC, la infraestructura es conocimiento tácito que vive en la cabeza de quien la configuró. Con IaC, cada cambio es rastreable, revisable y reproducible. Es el fundamento sobre el que se construyen prácticas como GitOps, disaster recovery automatizado y self-service infrastructure.
Referencias
- Infrastructure as Code, 2nd Edition — Kief Morris, 2020. El libro definitivo sobre IaC.
- Terraform: Up & Running, 3rd Edition — Yevgeniy Brikman, 2022. Guía práctica de Terraform con patrones reales.
- The Twelve-Factor App — Adam Wiggins, 2011. Principios de aplicaciones cloud-native que complementan IaC.
- Terraform Best Practices — Anton Babenko, 2024. Guía comunitaria de mejores prácticas.
- Pulumi Documentation — Pulumi, 2024. Documentación oficial de la alternativa imperativa.