Los dos repositorios de Terraform que nos entregan parecen iguales por fuera y fallan de forma distinta. Uno es un único módulo raíz con cuatrocientos recursos de todos los entornos, donde terraform plan tarda once minutos y todo el mundo le tiene miedo. El otro son doscientos módulos diminutos sin propiedad clara, donde cambiar el CIDR de una subred toca nueve repositorios.
Los dos son problemas de reparto del estado. Acierta ahí y el resto de Terraform es ingeniería de software normal.
Reparte el estado por radio de explosión y ritmo de cambio
La regla que usamos: un estado por cuenta y por capa, donde una capa es un conjunto de recursos que cambian juntos y que se destruirían juntos sin que fuera una catástrofe.
- Cimientos — VPC, subredes, adjuntos de transit gateway, zonas de Route 53, claves KMS. Cambia al mes. Destruirlo es una caída.
- Plataforma — clúster de EKS, RDS, balanceadores compartidos, roles IAM de las cargas. Cambia a la semana.
- Carga de trabajo — un estado por servicio: definiciones de tarea, autoescalado, alarmas, el rol IAM propio del servicio. Cambia a diario.
Un cambio en una carga no debería planificar nunca contra la VPC. Cuando lo hace, el plan de once minutos es el menor de tus problemas — el riesgo real es un apply con prisas tocando algo que no debía.
Las referencias entre capas van por data sources o parámetros de SSM que publica la capa inferior, nunca por terraform_remote_state leyendo el fichero de otro equipo. Las lecturas de estado remoto crean un acoplamiento oculto que nada en el código hace visible, y se rompen el día que alguien mueve un recurso.
El backend
S3 con versionado y bloqueo en DynamoDB, el bucket en la cuenta a la que sirve, cifrado con una clave KMS cuya política permita solo el rol del pipeline y el de emergencia. Activa el versionado de S3 antes de necesitarlo; recuperar un estado que alguien truncó son cinco minutos con versionado y una semana muy mala sin él.
Pipelines, y humanos en solo lectura
El cambio que más mejora un entorno de Terraform: nadie hace apply desde un portátil en producción. El pipeline asume un rol por cuenta vía OIDC desde tu proveedor de CI —sin claves estáticas en ningún sitio— y es el único principal con permisos de escritura. Los humanos tienen ReadOnlyAccess más un rol de emergencia que avisa cuando se asume.
La forma de pipeline que desplegamos:
fmt,validatey una comprobación de políticas —tfsecocheckovpara seguridad, másconftestpara tus propias reglas del tipo "ningún grupo de seguridad con0.0.0.0/0en el puerto 22".planen el pull request, publicado como comentario. El plan corre con un rol de solo lectura, así que un plan no puede cambiar nada.- Aprobación manual para producción, automática para staging.
applycon el rol de escritura y el fichero de plan del paso 2 — aplicar un cambio replanificado es por donde entran las sorpresas.
La deriva que vas a encontrar
Todo entorno con más de un año tiene deriva, y el primer plan tras introducir el pipeline es el momento en que descubres cuánta. Tres categorías, tratadas de forma distinta:
- Recursos cambiados a mano en la consola. El plan quiere revertirlos. Antes de dejarle, pregunta por qué alguien los cambió — a menudo el cambio manual era correcto y el código está mal. Arregla el código.
- Recursos creados a mano que Terraform no conoce. Estos no aparecen en ningún plan, que es lo que los hace peligrosos. Encuéntralos comparando
terraform state listcon el inventario real; Skyline dibuja exactamente esa diferencia, y es la vista que acorta la conversación sobre recursos huérfanos. - Recursos que Terraform creó y alguien borró. El plan quiere recrearlos. Suele ser correcto y a veces es catastrófico — mira antes qué depende de ellos.
Importa los que merezca la pena conservar con bloques import en la configuración en lugar del comando de CLI, para que la importación se revise en un pull request como todo lo demás.
Módulos, con moderación
Escribe un módulo cuando el mismo patrón aparezca tres veces, no antes. Un módulo con catorce flags booleanos es señal de que se forzaron dos cosas distintas en una misma abstracción. Fija versiones de módulo, también los del registro, y actualiza a propósito — un módulo sin fijar es un cambio que llega sin pull request.
Este reparto es lo que ponemos en marcha al inicio de casi todos los proyectos cloud, normalmente junto al mapa de cuentas de nuestro artículo sobre landing zones.
Qué hacer esta semana
Ejecuta terraform plan contra producción y cuenta los recursos que quiere cambiar. Si la respuesta no es cero, tienes deriva, y la lista de lo que quiere revertir es el documento más honesto que existe sobre tu entorno.