Cerramos el capítulo de testing con una idea más avanzada: el contract testing (pruebas de contrato) entre módulos. Cuando construyes infraestructura componiendo módulos que se conectan entre sí (recuerda el Capítulo 18), necesitas asegurarte de que esas conexiones siguen encajando aunque los módulos evolucionen. El contract testing protege esos «puntos de unión». Es un concepto más sutil, pero entenderlo te hará diseñar mejores módulos.

Recordatorio: los módulos se conectan por sus interfaces

En el Capítulo 18 vimos que los módulos tienen un contrato: unas entradas (variables) y unas salidas (outputs). Y vimos que se componen conectando la salida de un módulo con la entrada de otro (subcapítulo 18.2):

   Módulo "red"                    Módulo "servidores"
   output: id_subred  ──────────►  entrada: id_subred

Esa conexión es un contrato entre los dos módulos: el módulo de servidores confía en que el módulo de red le dará un id_subred válido. Mientras ese contrato se respete, todo encaja.

El problema: los contratos se pueden romper

Aquí está el riesgo. Imagina que alguien modifica el módulo de red y, sin darse cuenta del impacto, cambia el nombre o el formato de su salida id_subred (por ejemplo, lo renombra a subnet_id, o cambia lo que devuelve). El módulo de red, por sí solo, sigue «funcionando»... pero el módulo de servidores que dependía de esa salida se rompe, porque ya no encuentra lo que esperaba.

Antes:  módulo red  →  output "id_subred"  →  módulo servidores ✓ encaja
Cambio: módulo red  →  output "subnet_id"  →  módulo servidores ✗ ¡roto!
        (el contrato cambió sin avisar)

Este tipo de fallo es traicionero: el módulo modificado parece correcto en aislamiento, pero ha roto a otros módulos que dependían de él. Y en una organización grande, puede haber muchos módulos dependiendo de uno solo (recuerda los módulos compartidos del subcapítulo 18.4).

Qué es el contract testing

El contract testing (prueba de contrato) verifica que la interfaz entre dos módulos —el «contrato» de entradas y salidas— se mantiene estable y compatible. En lugar de probar toda la infraestructura, se centra en los puntos de conexión: comprueba que un módulo sigue ofreciendo las salidas que otros esperan, con el nombre y el formato correctos.

Contract test: "¿el módulo 'red' sigue ofreciendo un output 'id_subred'
                con el formato que el módulo 'servidores' espera?"
   → SÍ → el contrato se respeta ✓
   → NO → el contrato se rompió, hay que avisar antes de fusionar ✗

Analogía: un contrato entre módulos es como el enchufe y la clavija. El enchufe (la salida de un módulo) tiene una forma estándar, y la clavija (la entrada de otro) encaja en ella. El contract testing comprueba que nadie ha cambiado la forma del enchufe: si alguien lo modifica, los aparatos que dependían de él ya no encajarían. Verificas el «enchufe», no todo el aparato.

Cómo se hace en la práctica

El contract testing entre módulos no es una herramienta única con un botón mágico; es más bien un enfoque que combina varias prácticas que ya conoces:

  1. Tests centrados en las interfaces

Escribes pruebas (por ejemplo, con Terratest del subcapítulo 21.3) que verifican específicamente que los outputs de un módulo existen y tienen el formato esperado. No pruebas toda la infraestructura, solo el «contrato».

  1. Versionado estricto de módulos

Aquí brilla el versionado del subcapítulo 18.4. Si cambias la interfaz de un módulo (sus entradas o salidas) de forma incompatible, eso es un cambio mayor (sube la versión MAYOR, ej. de v1.x a v2.0). Así, los módulos que dependían de él no se actualizan automáticamente y siguen usando la versión compatible hasta que se adapten conscientemente.

Cambio compatible (añadir un output nuevo)  → versión MENOR (v1.2 → v1.3)
Cambio incompatible (quitar/renombrar output) → versión MAYOR (v1.x → v2.0)

  1. Tests de integración entre módulos en CI

En el CI (subcapítulo 21.1), cuando alguien cambia un módulo compartido, se pueden ejecutar tests que combinan ese módulo con los que lo usan, para confirmar que siguen encajando antes de fusionar el cambio.

Por qué importa, especialmente a gran escala

En un proyecto pequeño con pocos módulos, los contratos se rompen poco y es fácil detectarlo. Pero en una organización grande (que veremos en la Parte VII, con plataformas internas y módulos compartidos por muchos equipos), un solo módulo base puede ser usado por decenas de proyectos. Romper su contrato sin avisar causaría fallos en cascada por toda la empresa.

Ejemplo del mundo real: el equipo de plataforma mantiene un módulo red-corporativa que usan 30 equipos. Una desarrolladora quiere mejorarlo y, de paso, renombrar una salida para que sea «más clara». Sin contract testing, ese cambio rompería los 30 proyectos. Con contract testing y versionado estricto, el CI detecta que está cambiando la interfaz de forma incompatible y le obliga a publicarlo como versión mayor (v2.0). Los 30 equipos siguen en v1.x tranquilos, y migran a v2.0 cuando puedan, adaptando su código. El cambio mejora el módulo sin romper a nadie.

La idea de fondo: cuidar las interfaces

El mensaje clave de este subcapítulo, más allá de las herramientas, es una mentalidad: cuando diseñas módulos reutilizables, sus interfaces (entradas y salidas) son un contrato sagrado. Otros confían en ellas. Cambiarlas a la ligera rompe a quienes dependen de ti. El contract testing y el versionado son las herramientas que protegen esos contratos, permitiendo que los módulos evolucionen sin causar caos.

Lo que debes recordar

  • Los módulos se conectan por sus interfaces (salidas de uno → entradas de otro); esa conexión es un contrato en el que unos módulos confían.
  • Si alguien cambia la interfaz de un módulo (renombra o altera una salida), puede romper otros módulos que dependían de ella, aunque el módulo modificado «funcione» en aislamiento. Es un fallo traicionero, sobre todo a gran escala.
  • El contract testing verifica que la interfaz entre módulos se mantiene estable y compatible, centrándose en los puntos de conexión (como comprobar que «el enchufe no ha cambiado de forma»).
  • Se logra combinando: tests centrados en las interfaces (Terratest), versionado estricto (un cambio incompatible es versión MAYOR, subcap. 18.4) y tests de integración entre módulos en CI.
  • Importa especialmente a gran escala, donde un módulo base lo usan muchos equipos. La mentalidad clave: las interfaces de tus módulos son un contrato que debes cuidar.

¡Has terminado el Capítulo 21! Ya sabes asegurar la calidad y seguridad de tu infraestructura en todos los niveles. En el Capítulo 22 uniremos todo esto en un flujo automático completo: Terraform en CI/CD, desde el lint hasta el despliegue automatizado.

Cloud, AWS & Terraform — De cero a experto

Capítulo 1 · Qué es el cloud computing

Capítulo 2 · El mercado cloud y los grandes proveedores

Capítulo 3 · Regiones, zonas de disponibilidad y edge

Capítulo 4 · Cómputo: EC2

Capítulo 5 · Almacenamiento: S3

Capítulo 6 · Redes: VPC

Capítulo 7 · Identidad y acceso: IAM

Capítulo 8 · Bases de datos gestionadas

Capítulo 9 · Por qué Infraestructura como Código

Capítulo 10 · HCL: el lenguaje de Terraform

Capítulo 11 · Providers y estado

Capítulo 12 · Tu primera infraestructura real en Terraform

Capítulo 13 · Balanceo de carga y autoescalado

Capítulo 14 · Serverless con Lambda

Capítulo 15 · Mensajería y eventos

Capítulo 16 · Entrega de contenido y DNS

Capítulo 17 · Contenedores en AWS

Capítulo 18 · Módulos: reutilización y composición

Capítulo 19 · Workspaces y gestión de entornos

Capítulo 20 · Backends remotos y locking

Capítulo 21 · Testing de infraestructura

Capítulo 22 · Terraform en CI/CD

Capítulo 23 · Seguridad en profundidad

Capítulo 24 · Observabilidad: logs, métricas y trazas

Capítulo 25 · Optimización de costes

Capítulo 26 · Alta disponibilidad y disaster recovery

Capítulo 27 · Well-Architected Framework de AWS

Capítulo 28 · Arquitecturas serverless a escala

Capítulo 29 · Plataformas de datos en AWS

Capítulo 30 · Multi-cuenta y landing zones

Capítulo 31 · Platform Engineering e Internal Developer Platform

Capítulo 32 · Certificaciones AWS relevantes

Capítulo 33 · Proyectos para consolidar lo aprendido

Capítulo 34 · Recursos y comunidad

© Copyright 2024. Todos los derechos reservados