StackPractices
intermediate Por Mathias Paulenko

Guía de Despliegue Blue-Green

Guía práctica de despliegues blue-green: decisiones de arquitectura, mecanismos de conmutación de tráfico, migraciones de base de datos, planificación de rollback y operaciones de release sin interrupción.

Visión General

El despliegue blue-green mantiene vivos dos ambientes de nivel producción: blue sirve todo el tráfico mientras green espera inactivo. Despliegas la nueva versión en green, la validas en condiciones de producción, conmutas el tráfico y mantienes blue caliente como seguro de rollback. Si algo falla, conmutas de vuelta: segundos, no un nuevo despliegue.

El concepto es simple; las decisiones operativas no. ¿Qué mecanismo conmuta el tráfico? ¿Cómo migras la base de datos para que ambas versiones puedan correr? ¿Cuánto tiempo debe blue quedarse caliente? Esta guía cubre esas decisiones a nivel estratégico: arquitectura, mecanismos de conmutación, compatibilidad de base de datos y planificación de rollback. Para implementaciones listas para copiar — conmutación Nginx, selector de Service en Kubernetes, registros weighted de Route 53 — usa la receta de despliegue blue-green. Para el patrón abstracto, el patrón de despliegue blue-green.

Cuándo Usar

Blue-green justifica su infraestructura duplicada cuando:

  • La velocidad de rollback es el requisito principal: un cambio de selector o de DNS restaura la versión anterior en segundos — útil cuando una mala release cuesta dinero real por minuto.
  • Los despliegues son poco frecuentes y consecuentes: releases semanales o mensuales de un servicio núcleo, no decenas de pushes al día.
  • Puedes mantener los ambientes aislados pero compartir estado: misma base de datos, misma caché, mismo almacén de secretos; solo difiere la versión del código.
  • La validación necesita condiciones reales de producción: green solo sirve tráfico real tras la conmutación, pero los smoke tests corren contra la red real, las dependencias reales, los datos reales.

Cuándo NO Usar

Descarta blue-green cuando:

  • Despliegas muchas veces al día: mantener un ambiente paralelo completo inactivo el 95% del tiempo quema dinero por poco beneficio. Los despliegues rolling o canary encajan mejor en cadencias altas.
  • Los cambios de base de datos son frecuentes e incompatibles: las migraciones expand/contract añaden trabajo real; con cambios de esquema en cada release, el peaje de base de datos de blue-green supera a su victoria en rollback.
  • Dominan las conexiones de larga duración: WebSockets, streams SSE y trabajos por lotes en vuelo no sobreviven a una conmutación dura. Necesitas drenado de conexiones, que los cutovers graduales estilo canary manejan de forma más natural.
  • El tráfico es ínfimo o masivo: servicios diminutos no justifican la complejidad; servicios enormes hacen que duplicar infraestructura sea realmente caro.

Conceptos Clave

Cuatro propiedades definen un blue-green de verdad:

  1. Simetría de ambientes: blue y green corren infraestructura idéntica — mismos tipos de instancia, mismas reglas de escalado, misma zona de red. “Green es una copia más pequeña” se rompe en el momento en que green recibe todo el tráfico.
  2. Un único punto de conmutación: el tráfico se invierte en un límite bien definido — una regla de listener del load balancer, un registro DNS, un selector de Service de Kubernetes. Si la conmutación toca más de un sitio, no tienes un switch: tienes una secuencia de fallos parciales.
  3. Estado compartido, código versionado: ambos ambientes golpean la misma base de datos, caché y cola. Los ambientes difieren solo en versión de código — nunca en datos.
  4. Un objetivo de rollback caliente: blue sigue corriendo (quizá reducido) hasta que la siguiente release demuestra que green funciona. Desmantelar demasiado pronto borra tu botón de deshacer.

Arquitectura

flowchart diagram: Usuarios

El punto de conmutación es el corazón del diseño. Todo lo demás — el ambiente, las pruebas, el rollback — cuelga de esa única decisión.

Eligiendo tu Mecanismo de Conmutación

Tres mecanismos dominan, y difieren en velocidad de propagación, radio de impacto y en lo que se rompe cuando fallan:

MecanismoVelocidad de cutoverRollbackLímites
Regla de load balancerInstantáneoInstantáneoUna región, necesita LB capa 7
Selector de Service en KubernetesInstantáneo (in-cluster)InstantáneoSolo K8s; el tráfico externo resuelve la misma IP del LB
Registros DNS weightedLigado al TTL (30s–5min)Ligado al TTLLos resolvers cachean; parte del tráfico queda fijado al ambiente viejo
Service mesh / ingressInstantáneo, con pesosInstantáneo, con pesosMáxima complejidad

Elige LB o selector de Service cuando la app vive detrás de infraestructura que controlas: conmutación instantánea, rollback instantáneo, sin sorpresas de caché. Elige DNS solo cuando los dos ambientes viven en regiones o proveedores distintos sin LB compartido — y acepta que algunos clientes seguirán en el ambiente viejo hasta que expiren los TTLs. Con DNS, el rollback “instantáneo” es en realidad “cuando el TTL diga”, una diferencia contractual real.

Un híbrido común: DNS externo para failover a nivel de región, selectores de Service internos para la conmutación dentro del cluster.

Un criterio más que la mayoría de equipos descubre tarde: prueba el modo de fallo, no solo el camino feliz. La conmutación por DNS falla “suave”: los clientes siguen golpeando el registro viejo hasta que expira la caché y no hay forma de forzarlos. La conmutación por LB falla “dura”: una regla mala puede tumbar todo el tráfico de golpe. Si tu entorno no sobrevive a un fallo duro durante la conmutación, constrúyela como una secuencia escalonada pequeña (5% → 50% → 100% sobre los targets weighted del LB) aunque parezca trabajo extra. Los puristas del blue-green llaman a eso canary; los pragmáticos lo llaman no recibir un aviso a las 3 de la mañana.

Despliegue Blue-Green Paso a Paso

1. Prepara el ambiente green

Aprovisiona green idéntico a blue: mismo perfil de instancia, mismos límites de autoscaling, mismos roles IAM. Despliega la nueva versión y ejecuta las puertas reales:

  • Los readiness probes devuelven 200 en /health en cada réplica
  • Las transacciones sintéticas recorren el camino crítico (login, checkout, lo que haga dinero)
  • Las comprobaciones de dependencias pasan: conectividad a la DB, calentamiento de caché, consumidores de cola arrancados

No tomes atajos con “los pods están Running”. Un green que no puede servir es una falsa sensación de seguridad.

2. Conmuta el tráfico

Invierte el punto de conmutación de forma atómica:

# Kubernetes: un patch, instantáneo
kubectl patch svc app-active -p '{"spec":{"selector":{"version":"green"}}}'

# AWS ALB: apunta la regla del listener al target group green
aws elbv2 modify-rule --rule-arn arn:aws:elasticloadbalancing:... \
  --actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:...green

Si tu procedimiento de conmutación tiene más de un paso, escríbelo como script y prueba el propio script: un cambio manual de dos pasos son dos oportunidades de dejar el tráfico partido.

3. Monitorea tras la conmutación

Vigila de 5 a 10 minutos como mínimo, con umbrales reales definidos antes de conmutar:

  • Tasa de HTTP 5xx: disparador de rollback si >1%
  • Latencia p95/p99: rollback si se degrada más de 1,5x la línea base de blue
  • Métricas de negocio: altas/minuto, pedidos/minuto, throughput de trabajos; un bug silencioso de datos aparece aquí antes que en los errores

Automatiza la observación: un bucle que golpee /health y /metrics cada 10 segundos basta para la mayoría de equipos; conéctalo a auto-rollback si confías en tus umbrales.

4. Rollback (si hace falta)

El rollback es la misma conmutación en sentido inverso — sin redespliegue, sin revertir migraciones:

kubectl patch svc app-active -p '{"spec":{"selector":{"version":"blue"}}}'

Dos reglas: revierte dentro de la ventana en que la base de datos sigue siendo compatible con ambas versiones (ver abajo), y registra cada rollback con su disparador — rollbacks repetidos sobre la misma release significan que los smoke tests te están mintiendo.

5. Retira blue

Mantén blue caliente durante un ciclo de release: el tiempo entre este despliegue y el siguiente. Después escálalo hacia abajo (réplicas → 0 o una sola instancia caliente) y reutilízalo como green para la próxima release. Los ambientes intercambian roles en cada deploy; nunca destruyes ninguno de forma permanente.

Dimensionando el Ambiente Green

“Idéntico a blue” es la regla, pero hay margen para ser inteligente con el coste. Tres preguntas deciden el dimensionado:

¿Cuánto tiempo queda green a plena capacidad? Si tu ventana de deploy es de menos de una hora, green a tamaño completo cuesta casi nada: el gasto es el período caliente de standby tras la conmutación. La mayoría de equipos corren green a tamaño completo solo durante validación + conmutación y luego bajan blue a calidez mínima en esa hora.

¿Puedes tolerar el arranque en frío? Las apps Java/JVM y los pools de conexiones grandes tardan minutos en calentar. Si tu plan de rollback es “conmutar selector → usuarios esperan 90 segundos mientras green calienta”, eso es un rollback degradado. Mantén al menos una instancia caliente en el ambiente de standby en todo momento.

¿Cuánto cuesta caliente de verdad? Números aproximados: un t3.large en AWS son ~50 USD/mes; un nodo de K8s gestionado, ~70–150 USD/mes. Compáralo con tu coste de incidente: si una caída de 30 minutos cuesta más que un año de standby, la réplica caliente es el seguro más barato de tu stack.

Un reparto de presupuesto práctico: green a tamaño completo solo para la ventana de deploy, una réplica blue caliente hasta la siguiente release, y ambientes programados (escalado a cero fuera del horario laboral) para los niveles de preproducción.

Observabilidad y Disparadores de Rollback

Define los umbrales de rollback antes de desplegar, no mientras el incidente se desarrolla. Las señales que importan, en orden de fiabilidad:

SeñalUmbralPor qué atrapa lo que otras no ven
Tasa de HTTP 5xx>1% sostenido 60sImpacto directo al usuario
Latencia p99>1,5x línea base de blueProblemas de saturación que no dan error
Tasa de logs de error>2x línea baseBugs que devuelven 200 con datos erróneos
Caída de métrica de negocio>20% vs misma hora de referenciaFallos silenciosos (botón de checkout roto, webhook muerto)

Conéctalos en capas: las métricas de infraestructura alertan primero (segundos), los logs de error después (decenas de segundos), y las métricas de negocio al final (minutos) pero con la mejor relación señal-ruido para bugs de datos. El rollback automático en la capa de infraestructura es seguro; el rollback automático por métricas de negocio no — un email de marketing puede parecer una caída de conversión. Deja a un humano en la última capa.

Registra cada conmutación y cada rollback con timestamp, disparador y par de versiones: después de tres despliegues, ese registro te cuenta más sobre la calidad de tus releases que cualquier dashboard.

Consideraciones de Base de Datos

Aquí es donde los despliegues blue-green viven o mueren de verdad. Ambas versiones de la app comparten una base de datos, así que el esquema tiene que satisfacer a las dos a la vez. El patrón que funciona es expand/contract:

Expande primero: añade lo nuevo sin tocar lo existente:

-- Green puede leer/escribir email_v2; blue solo ve email.
ALTER TABLE users ADD COLUMN email_v2 VARCHAR(255);
UPDATE users SET email_v2 = email WHERE email_v2 IS NULL;

Despliega y conmuta: ambas versiones coexisten sobre el esquema compatible; blue sigue usando email, green usa email_v2, y un trigger o una doble escritura a nivel de aplicación los mantiene sincronizados durante la ventana de transición.

Contrae al final: retira la forma vieja solo después de desmantelar blue y cuando estés seguro de que ningún rollback la necesitará:

ALTER TABLE users DROP COLUMN email;
ALTER TABLE users RENAME COLUMN email_v2 TO email;

El paso de contracción puede esperar semanas. El pecado capital es ordenarlo mal: una migración destructiva antes de la conmutación elimina tu ruta de rollback por completo — si green falla, blue ni siquiera arranca contra el nuevo esquema.

Cronograma del Día del Deploy

Una release que sale bien parece aburrida porque el trabajo ocurrió antes de la ventana. Un cronograma realista para un servicio que importa:

T-24h: Congela los merges de features a la rama de release. Ejecuta la migración expand y confirma que ambas versiones de la app arrancan contra ella. Ensaya el rollback en staging — conmuta el selector de vuelta de verdad, no solo “lee el comando”.

T-2h: Escala green a plena capacidad y despliega el candidato. Registra las líneas base de blue: tasa de 5xx, latencia p99, throughput de tus tres endpoints principales. Avisa a on-call.

T-15m: Ejecuta los smoke tests contra green por el endpoint interno — no la URL pública. Verifica transacciones sintéticas, comprobaciones de dependencias y consumidores de cola. Confirma que el comando de rollback funciona contra la infraestructura actual (deriva con el tiempo).

T+0: Conmuta el punto de conmutación. Este es el único paso manual que debería existir: todo lo anterior fue automatización, todo lo posterior es observación.

T+5m a T+15m: Vigila los umbrales de la sección de observabilidad. No navegues dashboards buscando “algo raro”: estás comprobando cuatro números predefinidos.

T+30m: Declara la release estable o revierte. Pasados 30 minutos, el rollback se vuelve más difícil de justificar (y los datos escritos desde la conmutación necesitan reconciliación).

T+24h hasta la siguiente release: Blue se queda caliente a capacidad mínima. Programa la migración de contracción y el retiro de blue como el mismo ticket: ambas son “terminar la release”.

Lo que funciona

  • Ensaya el rollback como parte del despliegue, no como un simulacro aparte. La primera vez que conmutas de vuelta nunca debería ser durante un incidente.
  • Mantén blue a temperatura mínima entre despliegues: una réplica conserva la opción de rollback por centavos; cero significa que el próximo deploy construye green desde cero de todos modos.
  • Todo con etiqueta de versión: tags de imagen, selectores de Service, target groups — si el selector no codifica la versión, la conmutación no puede encontrarla.
  • Un checklist de go/no-go escrito: smoke tests verdes, métricas con línea base, comando de rollback probado, on-call avisado del día de deploy. Dos minutos de checklist valen más que una hora de “¿por qué está caído checkout?”.
  • Consciencia de sesiones sticky: si las sesiones viven en memoria, la conmutación las deja huérfanas en vuelo. Externaliza las sesiones (Redis, JWT) antes de adoptar blue-green — no durante.
  • Documenta el procedimiento de conmutación donde on-call lo encontrará: el runbook pertenece junto a la alerta, no en un wiki que nadie abre durante un incidente. Un comentario fijado en el pipeline de deploy con el comando exacto de rollback ha salvado más releases que cualquier diagrama de arquitectura.

Errores Comunes

  1. Dividir el tráfico por accidente: una conmutación manual de dos pasos, o reglas DNS y LB que se contradicen, deja a unos usuarios en blue y a otros en green: dos versiones en producción, comportamiento indefinido.
  2. Contraer demasiado pronto: borrar columnas en cuanto green está sano significa que un rollback resucita código que lee un esquema que ya no existe.
  3. Desmantelar blue en conmutación+0: el incidente que importa suele llegar horas después. Mantén blue caliente hasta la siguiente release.
  4. Ambientes desiguales: green en instancias más pequeñas o AMIs viejas hace que “green va lento” no te diga nada sobre la release.
  5. Sorpresas de estado compartido: colas consumidas dos veces, cachés escritas por ambas versiones con serializadores distintos, cron jobs corriendo en los dos ambientes. Decide explícitamente qué ambiente posee el trabajo programado.
  6. Rollback como improvisación: si la ruta de rollback no se probó la semana pasada, asume que no funciona.
  7. Health checks que mienten: un endpoint /health que devuelve 200 mientras las dependencias están muertas hace que green pase todas las puertas y falle en cuanto llega tráfico. Haz que el readiness verifique dependencias reales — conexión a DB, acierto de caché, suscripción a la cola — no solo “el proceso está vivo”.

Variantes

EscenarioForma recomendada
App única detrás de un LBSwap de target group en ALB/NLB o anotación de ingress
Cluster KubernetesPatch del selector de Service (ver la receta) + puertas de readiness
Multi-región o multi-nubeRegistros DNS weighted + conmutación de LB por región
ServerlessAlias de Lambda / etapas de API Gateway: blue-green sin instancias
Release intensiva en base de datosExpand/contract + feature flags ocultando lecturas/escrituras nuevas

Lectura Adicional

Ver También

Preguntas frecuentes

¿Cuánto cuesta realmente correr dos ambientes?

Aproximadamente el doble mientras ambos están totalmente aprovisionados: durante la ventana de deploy y el período caliente posterior. La mayoría de equipos escala blue a una sola réplica caliente entre releases, lo que reduce el sobrecoste a porcentajes de un dígito del coste del ambiente. La cuenta honesta incluye tu tiempo: una release fallida sin blue-green puede costar horas de respuesta a incidentes; la infraestructura duplicada suele pagarse sola la primera vez que el rollback es un cambio de selector y no un rebuild.

¿Load balancer o DNS: qué mecanismo de conmutación elijo?

LB o selector de Service siempre que la app viva detrás de infraestructura propia: conmutación instantánea, rollback instantáneo, sin caché en medio. Registros DNS weighted solo cuando los ambientes no pueden compartir un punto de conmutación (regiones o proveedores distintos), y siempre con TTLs cortos más la conciencia de que algunos clientes seguirán en blue hasta que la caché expire.

¿Cómo manejo sesiones y conexiones WebSocket durante la conmutación?

Externaliza primero el estado de sesión — Redis, JWTs, una base de datos — para que cualquier ambiente pueda servir a cualquier usuario. Las conexiones largas (WebSockets, SSE) necesitan un período de drenado: deja de aceptar conexiones nuevas en blue, deja que las existentes cierren de forma natural dentro de un timeout, y luego conmuta. Las conexiones que superan el timeout reciben una señal de reconexión para que el cliente se reestablezca en green.

¿Puedo hacer blue-green con una base de datos compartida?

Puedes, y la mayoría de despliegues reales lo hacen: para eso está expand/contract. Cambios de esquema aditivos primero (columnas nuevas, tablas nuevas), conmuta el tráfico, retira el esquema viejo solo cuando cierre la ventana de rollback. Si tu release exige un cambio destructivo de esquema el primer día, blue-green es la herramienta equivocada para esa release; combínala con feature flags o haz un cutover en ventana de mantenimiento.

¿Cuándo es canary mejor opción que blue-green?

Elige canary cuando quieres que el propio tráfico de producción valide la release gradualmente: una mala release toca al 5% de usuarios, no al 100%. Elige blue-green cuando la velocidad de rollback importa más que controlar el radio de impacto, y cuando tu patrón de tráfico es tan irregular que una muestra canary del 5% no detectaría el bug de todos modos.

¿Cómo gestiono secretos y configuración entre blue y green?

Ambos ambientes leen del mismo almacén de secretos (Vault, AWS Secrets Manager, GCP Secret Manager) con valores idénticos. La única diferencia intencionada entre ambientes es la versión del código: la deriva de configuración entre blue y green es un bug que produce incidentes de "funciona en green, falla en blue".

¿Qué debería incluir el checklist de go/no-go antes de conmutar?

Cinco puntos: smoke tests en verde en todas las réplicas; líneas base de errores y latencia registradas desde blue; comando de rollback probado (ejecutado de verdad, en staging, esta semana); on-call enterado de la ventana de deploy; base de datos en estado expand — sin migraciones de contracción pendientes que rompan la versión vieja.