Testing en produccion: canary deployments, feature flags y chaos engineering
Staging miente
Staging es un entorno que se parece a produccion pero no es produccion. Los datos son diferentes (menos volumen, menos variedad, menos usuarios concurrentes). Las integraciones de terceros estan en modo sandbox. El trafico es sintetico. Y por tanto, los problemas que staging detecta son un subconjunto de los que produccion revelara.
No es un argumento contra staging. Staging es necesario. Es un argumento a favor de complementar staging con testing en produccion: tecnicas diseñadas para validar codigo con trafico real, usuarios reales, y la complejidad real del sistema en funcionamiento.
Testing en produccion no significa “desplegar y rezar”. Significa desplegar de forma controlada, observar metricas en tiempo real, y tener la capacidad de revertir en segundos si algo va mal. Es ingenieria, no temeridad.
Canary deployments: el termometro antes de la inmersion
Un canary deployment despliega la nueva version a un subconjunto pequeño de usuarios (tipicamente 1-5%) mientras el resto sigue con la version anterior. Si las metricas del canary son buenas, se incrementa progresivamente. Si son malas, se revierte.
Implementacion practica
En Kubernetes: la forma mas comun es con dos Deployments (estable y canary) y un Ingress que distribuye trafico por peso. Istio y Linkerd soportan traffic splitting nativo. Argo Rollouts automatiza el proceso completo: despliega el canary, monitoriza metricas, avanza o revierte automaticamente.
# Argo Rollouts - canary strategy
spec:
strategy:
canary:
steps:
- setWeight: 5
- pause: {duration: 10m}
- setWeight: 20
- pause: {duration: 10m}
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100
analysis:
templates:
- templateName: error-rate
args:
- name: service-name
value: api-server
En serverless (AWS Lambda): Lambda aliases con traffic shifting. Configuras una alias que distribuye trafico entre dos versiones. CodeDeploy automatiza el progreso del canary basandose en alarmas de CloudWatch.
En servidores tradicionales: un load balancer que redirige un porcentaje del trafico al servidor con la nueva version. Nginx con split_clients, HAProxy con weight, o el balanceador de tu cloud (ALB weighted target groups).
Las metricas que determinan el exito del canary
El canary pasa si las metricas de la nueva version son equivalentes (o mejores) que las de la version estable. Las metricas criticas:
- Error rate: comparar el porcentaje de errores 5xx entre canary y estable. Si el canary tiene un error rate 2x superior, algo esta mal.
- Latencia p95/p99: la latencia media es engañosa. Un 5% de peticiones extremadamente lentas puede esconderse detras de una media aceptable. El p99 no miente.
- Metricas de negocio: tasa de conversion, pedidos completados, pagos procesados. Un canary que no genera errores tecnicos pero reduce las conversiones un 20% es un canary fallido.
El intervalo de observacion importa. 10 minutos al 5% con 1.000 peticiones/hora son solo 8 peticiones. Estadisticamente insignificante. Para tener confianza, necesitas un volumen minimo por paso del canary. La regla practica: al menos 100 peticiones en el canary antes de avanzar al siguiente paso.
Cuando no usar canary
Canary no funciona bien para cambios de base de datos. Si la nueva version requiere un schema migration, el canary y la version estable leen la misma base de datos. El nuevo schema tiene que ser compatible con ambas versiones (expand and contract pattern), lo que limita el tipo de cambios que puedes hacer incrementalmente.
Tampoco funciona cuando los cambios afectan a estado compartido (caches, colas) de formas incompatibles. Si la version canary produce mensajes en un formato que la version estable no puede consumir, el 5% de trafico canary puede corromper datos para el otro 95%.
Feature flags: el interruptor granular
Los feature flags desacoplan el despliegue del lanzamiento. Despliegas codigo nuevo en produccion pero desactivado. Lo activas para usuarios especificos, para un porcentaje de trafico, o para nadie (dark launch). Esto permite desplegar continuamente sin riesgo y lanzar cuando el negocio lo decide.
Tipos de feature flags
Release flags: activan funcionalidades nuevas. El caso mas comun. “Mostrar el nuevo checkout a los usuarios del segmento beta.” Vida corta: se activan, se validan, y se eliminan (junto con el codigo del path antiguo).
Experiment flags: para A/B testing. “El 50% de los usuarios ve el boton azul, el 50% el verde.” Se mantienen hasta que hay resultados estadisticamente significativos.
Operational flags: circuit breakers manuales. “Si el servicio de pagos tiene problemas, mostrar el mensaje de mantenimiento.” Sin fecha de eliminacion. Son infraestructura permanente.
Permission flags: habilitan funcionalidades por usuario o segmento. “Los usuarios premium ven el dashboard avanzado.” Cercanos a la gestion de permisos, pero implementados como flags para mayor flexibilidad.
Herramientas
LaunchDarkly es el lider del mercado (valorado en 3.000 millones $). SDKs para todos los lenguajes, targeting avanzado, evaluacion del lado del servidor con streaming. Desde 8.33 $/mes por seat (plan Starter). Para equipos de 10+, el coste escala rapidamente.
Unleash es la alternativa open-source mas madura. Self-hosted o cloud. Soporta targeting, gradual rollouts y variantes. Para equipos que no quieren dependencia de un SaaS para algo tan critico como los feature flags.
Flagsmith, OpenFeature, y el propio AWS AppConfig con feature flags son opciones intermedias.
Nuestra recomendacion: para equipos de hasta 20 desarrolladores, Unleash self-hosted. Coste cero de licencia, control total, y suficiente funcionalidad para el 90% de los casos. LaunchDarkly para organizaciones grandes donde el soporte y la integracion con herramientas enterprise justifiquen el coste.
La deuda tecnica de los feature flags
Un feature flag que se queda en el codigo 6 meses despues de su lanzamiento es deuda tecnica. Cada flag añade un path condicional que hay que mantener y testear. Con 50 flags activos, las combinaciones posibles son astronomicas.
Regla estricta: todo feature flag de release tiene una fecha de eliminacion asignada en el momento de crearlo. En nuestros proyectos, usamos un bot que alerta cuando un flag supera los 30 dias de antigüedad sin ser removido. Sin esta disciplina, hemos visto codebases con mas de 200 flags, donde nadie sabia cuales estaban activos y cuales eran vestigios de features lanzadas hace dos años.
Progressive rollouts: el modelo completo
Canary y feature flags se combinan en progressive rollouts: un modelo de despliegue donde el codigo se expone a usuarios reales de forma gradual y controlada.
El flujo tipico:
- Deploy con feature flag desactivado (dark launch)
- Activar para el equipo interno (dogfooding)
- Ampliar al 1% de usuarios reales
- Observar metricas durante 24 horas
- Ampliar al 10%, observar 24 horas
- Ampliar al 50%, observar 24 horas
- Full rollout (100%)
- Limpieza: eliminar el feature flag y el codigo del path antiguo
Cada paso tiene criterios de avance (metricas dentro de umbrales) y criterios de reversion (metricas fuera de umbrales). La automatizacion completa es posible con herramientas como Argo Rollouts + Prometheus + feature flag service, pero incluso manual el modelo reduce drasticamente el riesgo.
¿Suena lento? Lo es. Un feature que antes se desplegaba en un dia ahora tarda una semana en llegar al 100%. Pero el numero de incidentes en produccion se reduce proporcionalmente. En un cliente con despliegues diarios, pasar de “deploy and pray” a progressive rollouts redujo los incidentes post-deploy un 85%.
Chaos engineering: romper para fortalecer
Chaos engineering es la practica de introducir fallos deliberados en produccion para verificar que el sistema los tolera. No es testing destructivo aleatorio. Es experimentacion controlada con hipotesis claras.
El modelo cientifico
Un experimento de chaos engineering sigue el metodo cientifico:
- Hipotesis: “Si una instancia del servicio de pagos falla, el load balancer redirige el trafico a las instancias sanas y los usuarios no experimentan errores.”
- Variables: ¿que fallo? (kill del proceso, latencia inyectada, particion de red). ¿Que medimos? (error rate, latencia, disponibilidad).
- Blast radius: ¿cuantos usuarios pueden verse afectados? Empezar con blast radius minimo.
- Ejecutar: introducir el fallo.
- Observar: ¿la hipotesis se cumple?
- Aprender: si no se cumple, ¿por que? ¿Que hay que mejorar?
Herramientas
Chaos Monkey de Netflix es la herramienta original: mata instancias de VM aleatoriamente en produccion. Simple pero efectivo para validar que los servicios toleran la perdida de instancias.
Litmus Chaos es el proyecto CNCF para chaos engineering en Kubernetes. Soporta experimentos como pod kill, network delay, disk fill, y CPU stress. Se define como recursos de Kubernetes (ChaosEngine, ChaosExperiment), lo que facilita la integracion con CI/CD.
Gremlin es la opcion SaaS mas completa: interfaz web, targeting preciso, halt button para detener el experimento inmediatamente. Desde 2.000 $/año para equipos pequeños.
AWS Fault Injection Simulator (FIS) permite inyectar fallos en servicios AWS (parar instancias EC2, throttlear DynamoDB, desconectar subnets). Nativo, sin agentes, facil de configurar para equipos que ya estan en AWS.
Por donde empezar
No empieces matando instancias en produccion el primer dia. El camino incremental:
Nivel 1 - Game days: simulacros manuales en un entorno no productivo. “¿Que pasa si el servicio X deja de responder?” El equipo investiga y documenta el impacto. Cero automatizacion, maximo aprendizaje.
Nivel 2 - Chaos automatizado en staging: ejecutar experimentos de Litmus o FIS en staging de forma automatica. Validar que los runbooks de respuesta funcionan.
Nivel 3 - Chaos en produccion con blast radius minimo: matar un pod de un servicio no critico en produccion durante horario laboral, con el equipo observando. Verificar que el auto-scaling y el health check funcionan.
Nivel 4 - Chaos continuo en produccion: ejecutar experimentos automaticos periodicamente (semanalmente, por ejemplo) contra servicios criticos. El sistema deberia tolerar estos fallos sin intervencion humana.
La mayoria de los equipos nunca pasan del nivel 2. Y esta bien. Los game days manuales ya generan un valor enorme al exponer suposiciones incorrectas sobre la resiliencia del sistema.
La cultura detras de las herramientas
Testing en produccion requiere una cultura organizacional especifica. Los equipos que lo hacen bien comparten tres caracteristicas:
Confianza en la observabilidad: si no puedes ver el impacto de un cambio en tiempo real, no puedes testear en produccion de forma segura. Los dashboards, las alertas y las trazas son prerequisitos, no extras.
Reversion rapida como prioridad: el tiempo para revertir un deploy debe ser inferior a 5 minutos. Si revertir requiere un proceso manual de 30 minutos, el riesgo del testing en produccion es inaceptable. Automatiza la reversion antes de automatizar el despliegue.
Blameless culture: cuando un canary falla y hay que revertir, eso no es un error. Es el sistema funcionando como se diseño. Si el equipo teme desplegar porque un rollback se percibe como fracaso, nadie desplegara incrementalmente.
Testing en produccion no reemplaza el testing previo. Complementa un pipeline de CI/CD robusto con unit tests, integration tests y testing en staging. Es la ultima capa de validacion, la que verifica que el sistema funciona con la unica variable que no puedes simular: la realidad.
Nuestro equipo de cloud y DevOps implementa pipelines de despliegue con canary, feature flags y progressive rollouts. Si tu organizacion quiere reducir los incidentes post-deploy, podemos diseñar la estrategia de testing en produccion adecuada a tu stack y equipo. Consulta tambien nuestro articulo sobre observabilidad en microservicios para los prerequisitos de monitoring necesarios.
Etiquetas
Sobre el autor
abemon engineering
Equipo de ingenieria
Equipo multidisciplinar de ingenieria, datos e IA con sede en Canarias. Construimos, desplegamos y operamos soluciones de software a medida para empresas de cualquier escala.