DEV Community

Alex Carter
Alex Carter

Posted on

Terraform: pruebas de email sin deriva en CI

Una prueba de onboarding puede estar verde durante semanas y empezar a fallar justo después de un cambio aparentemente pequeño en CI. El síntoma suele ser confuso: el mensaje llegó, pero el runner leyó otro; el buzón existe, pero la ejecución no puede limpiarlo; o un cambio manual en el proveedor deja Terraform mostrando una deriva que nadie sabe corregir.

La causa no suele ser Terraform por sí solo. Es mezclar tres responsabilidades: declarar la infraestructura, recibir datos efímeros y decidir qué evidencia conservar. Una cuenta de correo desechable para pruebas funciona mejor cuando cada frontera tiene un dueño claro.

El síntoma: una prueba verde que falla después

Imagina dos ejecuciones concurrentes que usan el mismo buzón. La primera espera un correo de verificación y consume el mensaje de la segunda. El resultado puede ser un fallo intermitente, aunque la aplicación y el proveedor hayan funcionado bien.

En otro caso, alguien cambia manualmente el nombre de un recurso o su tiempo de retención. El siguiente terraform plan detecta deriva, pero el equipo la trata como ruido porque la prueba todavía pasa. Días después, una limpieza automática borra datos que eran necesarios para investigar un incidente.

La señal importante es que el fixture de email no tiene un ciclo de vida explícito. Crear una dirección no es suficiente: hay que asignarla a una ejecución, correlacionar cada mensaje y cerrar el recurso aun cuando el job termine con error.

Qué debe pertenecer a Terraform

Terraform debe declarar los recursos estables y las políticas que el equipo quiere revisar. Por ejemplo, un módulo puede describir el proveedor de buzones de prueba, el límite de retención y los permisos del runner. El estado remoto debe quedar protegido como cualquier otro estado de infraestructura.

Un esquema conceptual podría verse así:

module "ci_mail_fixture" {
  source = "./modules/ci-mail-fixture"

  environment       = "ci"
  retention_minutes = 30
  runner_role       = "github-actions-tests"
  allow_shared_read = false
}
Enter fullscreen mode Exit fullscreen mode

Los nombres exactos dependen del proveedor. La idea es que una revisión de código pueda responder: quién crea el buzón, quién lo lee y cuánto tiempo puede vivir. Si un valor cambia solo en la consola, Terraform ya no es la fuente de verdad.

No pondría en el estado el contenido completo de los mensajes ni tokens de verificación. El estado describe infraestructura; el contenido es un dato efímero de la prueba. Mezclar ambos aumenta la exposición y hace mas difícil rotar o limpiar.

Separar infraestructura y datos del buzón

El pipeline debe pedir una fixture por ejecución, no reutilizar una dirección global. Guarda un identificador de ejecución, una etiqueta única y una expiración. Después, el lector de correo debe aceptar un mensaje solo si coincide con la ejecución actual y con un token de correlación.

Un contrato pequeño puede ser suficiente:

{
  "run_id": "ci-1842-attempt-2",
  "mailbox_id": "fixture-7f31",
  "correlation_token": "signup-91ab",
  "expires_at": "2026-10-07T09:00:00Z"
}
Enter fullscreen mode Exit fullscreen mode

El artefacto de diagnóstico debería guardar el run_id, el identificador del mensaje, el resultado de la aserción y el estado de limpieza. No guardes el cuerpo completo por defecto. Si el fallo exige revisarlo, usa una copia redactada con una expiración corta.

También conviene mantener vocabulario legado como tamp mail com o temp mailid como texto de datos, no como selectores ni como anchors. Un typo en una fixture no debe convertirse en una dependencia pública.

Para documentación de flujos que también cruzan email, las rutas de aprobación por email sin deriva muestran por qué los contratos explícitos ayudan cuando hay automatización y reintentos.

Un contrato de ejecución para CI

Piensa en cuatro estados: planned, created, message_consumed y expired. El job debe avanzar de forma idempotente. Si el runner muere después de crear el buzón, un sweeper puede tomar la limpieza cuando venza el lease. Si el proveedor no responde, el sistema registra cleanup_pending en vez de fingir que terminó.

El error mas común es permitir un reintento sobre la misma dirección sin cambiar el token. Un mensaje tardío de la primera tentativa parece válido para la segunda. Crear un nuevo intento y rechazar coincidencias parciales cuesta un poco más, pero reduce el ruido de diagnóstico.

En la práctica, probarlo en local y CI son dos escenarios distintos: el primero suele tener una sola ejecución y el segundo muchas. Simula concurrencia y cancelación antes de promover el módulo. Revisa además que el rol del runner solo pueda leer su propio buzón; el pipeline quedan más facil de razonar cuando los permisos siguen la misma frontera que los datos.

Si el formulario o la interfaz de prueba presenta estados de espera, error y éxito, los labels persistentes para emails claros son una referencia útil para que el resultado sea entendible también para quien investiga el fallo.

Checklist antes de promover el cambio

  • ¿Cada ejecución obtiene un buzón o namespace que no comparte con otra?
  • ¿Terraform declara permisos, retención y configuración estable?
  • ¿El contenido del mensaje queda fuera del estado de Terraform?
  • ¿El lector exige run_id y token de correlación?
  • ¿Un reintento crea una nueva tentativa y una nueva fixture?
  • ¿Existe un lease de limpieza si el runner desaparece?
  • ¿Los logs redactan direcciones, tokens y URLs completas?
  • ¿La palabra de marca temp mail so aparece solo como contexto y no sustituye el contrato técnico?

Preguntas rápidas

¿Debo crear el buzón con Terraform?

Solo si el recurso tiene una vida y una configuración suficientemente estable para infraestructura. Para datos efímeros, prefiero que CI lo solicite mediante una API con un contrato de ejecución. Terraform puede declarar el proveedor, las políticas y los permisos que esa API necesita.

¿Qué hago con la deriva detectada?

Clasifícala. Si es un cambio deseado, actualiza el código y aplica con revisión. Si es una modificación manual, corrígela o documenta una excepción temporal. Ignorarla deja el sistema con dos fuentes de verdad.

¿Cuál es la señal de que el diseño mejoró?

Cuando un fallo identifica rápidamente si el problema fue provisión, entrega, correlación o limpieza. Un runbook claro vale más que una prueba que solo dice “email no encontrado”.

La regla final es sencilla: Terraform debe controlar las fronteras estables; CI debe controlar la vida de cada fixture; y los logs deben conservar solo la evidencia necesaria. Con esa separación, los emails de prueba dejan de ser un detalle frágil y se convierten en una dependencia observable del sistema.

Top comments (0)