"Tenemos backup"
Todos los productos tenían backup. Había CronJobs que generaban dumps de las bases y los enviaban a un bucket, y eso alcanzaba para responder "¿tienen backup?". Pero nadie sabía responder las preguntas que importan en un desastre: ¿el backup restaura? ¿Cuánto tarda en volver? ¿Cuántos datos podemos perder? Y si el backup deja de funcionar, ¿alguien se entera?
La única forma honesta de responder era restaurar.
Restaurar de verdad
Aprovisioné un entorno de restore aislado y, de entrada, encontré una falla en el Terraform: el disco de datos de 600 GB nunca se formateaba ni se montaba. La corregí, aislé el disco de otra prueba que corría en paralelo e hice el restore de la base de producción por streaming, directo desde el bucket, sin pasar por ninguna máquina local. Fueron 249 GB y 85 tablas en 2h41, con la integridad validada.
El ejercicio reveló lo que ningún panel mostraba. Los backups de producción estaban fallando desde hacía más de un día, en silencio. Había una inconsistencia de integridad referencial que ya existía en producción y habría pasado desapercibida. Y el bucket acumulaba unos 92 TB sin política de ciclo de vida, cerca de US$ 2,3 mil por mes.
Repetí el método en un producto con MongoDB. El dump salió de un nodo secundario, fuera del horario pico, con un retraso de replicación máximo de 15 segundos y sin impacto en producción. Fueron 425 millones de mensajes restaurados sin ninguna falla, con checksum idéntico. El tiempo de recuperación medido fue de unas 5h20, porque reconstruir los índices llevó más tiempo que cargar los datos.
Por qué fallaba el backup
La rutina de retención tenía un deadlock: los dumps antiguos solo se borraban después de un backup exitoso. Cuando el disco se llenaba, el backup fallaba antes de limpiar, y el ciclo nunca se recuperaba solo. El volumen llegó al 96%, lleno de dumps parciales. Liberé espacio borrando solo copias que ya había validado en el bucket y corregí la causa: el dump pasó a ir directo al bucket, sin guardar copia local.
En un tercer producto, encontré una falla silenciosa antes de que ocurriera. El job de backup no tenía tiempo máximo de ejecución, no permitía ejecuciones concurrentes y enviaba la notificación desde adentro de sí mismo. Un job trabado bloquearía todos los backups siguientes, y el aviso dependería justamente de lo que se había trabado. Propuse detectar la falla desde afuera, por la antigüedad del último éxito.
Hacer que el backup avise, y protegerlo
Creé alertas de falla y de backup detenido más tiempo de lo esperado, además de avisos de inicio, éxito y falla en el canal del equipo. Validé las reglas con promtool antes de aplicarlas.
El dump además se subía en texto legible: una filtración del bucket expondría la base entera, con datos personales. Evalué tres formas de custodiar las claves y elegí envelope encryption con el KMS de la nube, con una clave de datos nueva por archivo, la clave maestra que nunca sale del KMS y verificación de integridad por HMAC. El costo adicional fue cero. Separé los privilegios en dos identidades: una que solo cifra y escribe, otra que solo descifra y lee. La credencial del bucket pasó de un ConfigMap a un Secret, y los manifiestos que solo existían en el clúster fueron a Git, comparados campo por campo con producción.
Convertirlo en política
Con los tiempos medidos en la mano, escribí la política de recuperación ante desastres, con metas de RPO y RTO basadas en lo que de verdad pasó en las pruebas, registro de los ensayos, frecuencia y criterios de éxito, alineada con los controles de backup y continuidad de la ISO 27001. Para que la confianza no dependiera de que alguien se acordara de probar, creé un simulacro automático: un job que toma el backup cifrado más reciente, lo descifra, lo restaura en una base de prueba, lo valida y avisa al equipo.
En el camino, encontré y documenté una base de producción sin ningún backup, con el plan para implementarlo.
Qué cambió
Los backups de los productos principales dejaron de solo "existir" y pasaron a estar restaurados y medidos. El RTO y el RPO se convirtieron en números de una política, y no en estimaciones. Los backups que fallaban en silencio pasaron a avisar al equipo, y los dumps pasaron a estar cifrados, con claves fuera del alcance de quien solo tiene acceso al bucket.
Lo que me llevo
La única forma de saber si un backup funciona es restaurarlo. Cada prueba reveló algo que ningún dashboard mostraba. Y el tiempo real de recuperación (5h20, y no "unas dos horas") solo aparece cuando lo mides.