Terraform en AWS: reparto del estado, pipelines y la deriva que vas a encontrar

Casi todo el dolor de Terraform no es HCL. Es un fichero de estado enorme, applies desde portátiles y tres años de cambios manuales en la consola que nadie importó. Así lo desenredamos.

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:

  1. fmt, validate y una comprobación de políticas — tfsec o checkov para seguridad, más conftest para tus propias reglas del tipo "ningún grupo de seguridad con 0.0.0.0/0 en el puerto 22".
  2. plan en el pull request, publicado como comentario. El plan corre con un rol de solo lectura, así que un plan no puede cambiar nada.
  3. Aprobación manual para producción, automática para staging.
  4. apply con 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 list con 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.

ConsultorIA

¿Quieres esto en tu nube?

El diagnóstico de diez días en solo lectura es gratuito, y con Skyline puedes ver tu entorno en un mapa antes de escribirnos.

Artículos relacionados

Módulos que la gente reutiliza en vez de copiar

Los dos fracasos son un módulo que envuelve un recurso y no aporta nada, y un módulo que lo hace todo y que nadie se atreve a cambiar. Una interfaz mínima, valores por defecto seguros y un versionado honesto son lo que los separa.