Saltar al contenido
Volver

Último llamado antes de producción

Cómo coordinamos varios ciclos de despliegue con previews, releases y aprobaciones, reservando la intervención humana para las decisiones que todavía necesitan contexto.

El último paso antes de producción no siempre puede decidirlo un workflow.

Al preparar un release de uno de los proyectos que operamos, podemos llegar a un punto donde todos los checks están en verde: los previews están listos, los artefactos tienen una versión, el diff de producción está disponible para revisión y la automatización sabe cómo ejecutar cada despliegue.

Pero todavía queda una pregunta:

¿Qué necesita desplegarse primero?

La respuesta no siempre es la misma.

En este proyecto, los cambios no llegan a producción mediante una sola herramienta de despliegue.

La capa de IaC administra la infraestructura base.
Lambda tiene su propio ciclo con lambroll.
Los servicios y jobs de ECS se despliegan con ecspresso.
Las state machines de Step Functions se empaquetan y despliegan con SAM.

Todas esas piezas pertenecen al mismo sistema, pero no siempre deben cambiar en el mismo orden.

En algunos releases, SAM tiene que desplegarse antes que Lambda. En otros, una nueva task definition de ECS debe registrarse antes que el cambio de IaC que la consumirá. También hay cambios donde la capa de IaC tiene que publicar primero un rol, un bucket o una referencia que otro despliegue necesita.

Al principio, esas relaciones parecen un grafo de dependencias que deberíamos poder expresar en código.

El problema es que el grafo cambia de un release al siguiente.

Una dependencia puede aparecer porque un recurso se crea por primera vez. Otra puede existir únicamente durante una migración o mientras la responsabilidad se mueve entre herramientas. Cuando ese trabajo termina, la dependencia puede desaparecer o apuntar en la dirección contraria.

Representar cada caso requiere más condiciones: ¿El recurso ya existe? ¿Los datos ya se movieron? ¿Qué herramienta lo administra ahora? ¿Es un release normal o un hotfix?

Codificar todo eso convierte el pipeline en otro sistema que el equipo debe probar y mantener. Su trabajo deja de ser únicamente desplegar cambios; también tiene que reproducir el contexto de cada release.

Automatizamos la parte repetible del release: detectar cambios, generar previews, asumir roles, construir artefactos, solicitar aprobaciones y ejecutar despliegues. Pero dejamos una decisión pequeña en manos de la persona que prepara el release:

¿Qué necesita desplegarse y en qué orden?

Ese es el último llamado antes de producción: una decisión explícita antes de ceder nuevamente el control al sistema.

El problema no era ejecutar comandos

Ejecutar los comandos de despliegue no es la parte difícil.

La dificultad está en todo lo que los rodea:

También está la orquestación.

Cada motor de despliegue entiende los recursos que administra. Sabe cómo renderizar, comparar y aplicar su parte del cambio, pero no entiende por sí solo la intención completa del release.

Ningún motor sabe necesariamente por qué, en este cambio particular, una pieza tiene que existir antes que otra.

Ese contexto no siempre vive en una dependencia estática que podamos programar una vez y olvidar.

Los contratos detrás del release

El sistema no se sostiene con una herramienta universal de despliegue. Depende de un conjunto pequeño de contratos que se mantienen entre herramientas, ambientes y equipos.

Un ciclo común entre herramientas

En lugar de obligar a todos los recursos a pasar por la misma herramienta, dimos a las distintas herramientas de despliegue un ciclo común. Cada tipo de recurso usa un workflow para decidir cuándo iniciar el proceso y otro reutilizable para realizar el despliegue:

pull request       -> preview en dev, staging y producción
merge a main       -> despliegue a dev y staging
draft release      -> previews de producción y definición del orden
published release  -> despliegue aprobado a producción
workflow_dispatch  -> despliegue al ambiente elegido bajo sus guardrails

El formato del preview depende de la herramienta —un changeset o un diff— y vuelve al pull request sin aplicarse. Después, la misma revisión avanza por desarrollo y staging. Un GitHub Release publicado funciona como la señal separada para producción, protegida por su compuerta de aprobación.

Fuera del flujo de pull requests, workflow_dispatch permite que un desarrollador despliegue una revisión seleccionada a desarrollo o staging para probarla. También ofrece un camino de hotfix a producción sin saltarse su compuerta de aprobación.

Un preview no puede desplegar

Los workflows se autentican en AWS mediante OIDC, sin access keys de larga duración en GitHub. Un rol de preview puede crear y consultar un changeset, renderizar configuración y generar un diff, pero no aplicar el cambio. Un rol de despliegue separado puede ejecutar, actualizar o registrar recursos.

El GitHub Environment se adjunta únicamente a los jobs que aplican cambios. Revisar un preview no necesita aprobación; desplegar a un ambiente protegido puede necesitarla. Una persona aprueba una ejecución con una ruta, un ambiente, un artefacto y un diff definidos, no un workflow con permisos generales para improvisar.

La persona aporta contexto. La plataforma mantiene el límite.

IaC publica dependencias compartidas; no controla todos los ciclos

La capa de IaC es la fuente de verdad para networking, roles, buckets, repositorios de imágenes y otros recursos compartidos. En este proyecto, CloudFormation publica esos valores como Exports.

La configuración de funciones y contenedores resuelve los Exports desde Jsonnet, mientras las definiciones de state machines los consumen con ImportValue. IaC puede crear el rol de una función sin administrar su código, o un repositorio de imágenes sin decidir cuándo publicar una imagen nueva.

Las herramientas siguen dependiendo unas de otras, pero las dependencias son visibles sin obligar a todos los recursos a compartir el mismo ciclo de vida.

Los artefactos conservan su identidad

Las imágenes de ECS se etiquetan con el SHA del commit y ECR no permite sobrescribir tags. Producción nunca depende de latest ni de una imagen reconstruida después con el mismo nombre.

Los demás recursos vuelven a una versión anterior desplegando otra vez desde un commit o tag conocido. El mecanismo cambia según el recurso, pero el contrato se mantiene: un release deja suficiente identidad para reconstruir qué llegó a producción y recuperarse si falla.

Todo lo integrado a main está listo para desplegarse

Los releases no dependen de un operador o equipo. Cualquier persona que necesite un cambio puede prepararlo, venga de aplicación o de infraestructura. El contrato es simple: todo lo integrado a main está listo para desplegarse.

Eso no elimina el error humano, pero la revisión evita que la confianza recaiga en una sola persona. DevOps construye el camino y los guardrails para que el equipo despliegue con seguridad. No necesita observar cada despliegue.

El contexto operacional permanece con el proyecto

Cada proyecto mantiene su infraestructura y sus workflows cerca del código que despliega. Los principios se mantienen, pero cada repositorio puede expresar sus propios recursos, ambientes y excepciones.

Un repositorio central de módulos también puede funcionar. Pero cuando intenta cubrir todas las cuentas y ambientes, los flags, variables y count pueden terminar describiendo cada excepción. Aceptamos cierta duplicación para que un desarrollador pueda entender desde un solo lugar cómo se construye un proyecto y cómo llega a producción.

No es una regla universal. La duplicación se vuelve cara cuando todas las copias necesitan el mismo cambio o empiezan a desviarse sin intención. Aquí es un trade-off a favor de la claridad local.

El último llamado antes de producción

La persona que prepara el release elige el tipo de incremento de SemVer. El workflow calcula la siguiente versión, compara el tag del último release publicado con el commit que queremos promover y reúne en un draft release los previews de todos los ciclos de despliegue.

El draft es el segundo punto de revisión. Antes de publicar nada, el equipo puede inspeccionar el cambio combinado y definir los pasos de producción y su orden.

Publicar el release activa los workflows de producción. Cada uno utiliza su artefacto y sus permisos correspondientes, detrás de la compuerta de aprobación del GitHub Environment. El orden se mantiene como coordinación explícita del equipo, no como una dependencia escondida dentro de un script.

Eso no convierte el despliegue en manual. La persona no entra a una cuenta de AWS, elige credenciales, cambia parámetros durante la ejecución ni adivina qué versión de una imagen es correcta. Responde la pregunta que el sistema no puede contestar de forma confiable sin entender la intención del cambio.

El objetivo no es alcanzar “100% de automatización”. Es saber qué se puede previsualizar, qué puede aplicar un cambio, quién lo aprueba, qué artefacto se promueve, dónde permanece trabajo manual y cómo recuperarse si algo falla.

Es fácil describir este sistema por su toolchain. Pero lo importante es que un desarrollador puede ver el impacto de un cambio sin tener permisos para aplicarlo, mover la misma revisión por ambientes conocidos y tomar la única decisión que todavía necesita contexto en un lugar pequeño y auditable.

Producción no necesita una persona que ejecute cada paso.

Necesita que alguien pueda explicar por qué esos pasos deben ocurrir en ese orden.

El sistema hace que ese último llamado sea visible y seguro.


Newsletter

Recibe los próximos posts en tu correo.

Notas ocasionales sobre DevOps, plataformas, confiabilidad y el trabajo real detrás de producción. Sin ruido, solo cuando haya algo útil que compartir.

Puedes darte de baja cuando quieras. No compartiré tu correo.



Post anterior
Cuando cada 'write' empieza leyendo la colección completa