> ## Documentation Index
> Fetch the complete documentation index at: https://ai-kb.automationanywhere.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Guía de Recuperación ante Desastres y RTO/RPO

> DR strategy, RTO/RPO targets, backup systems, auto-recovery mechanisms, and recovery procedures for the EKB AWS/EKS infrastructure.

Este documento describe la estrategia de recuperación ante desastres (DR), el Objetivo de Tiempo de Recuperación (RTO) y el Objetivo de Punto de Recuperación (RPO) para la infraestructura EKB AWS/EKS. Cubre las capacidades HA integradas, los sistemas de respaldo activos, los procedimientos de recuperación y las brechas conocidas.

<Info>
  Para instrucciones de despliegue, consulte la [Guía de Despliegue con Terragrunt](/offerings/on-premise/kubernetes-deployment/terragrunt-deployment).
</Info>

***

## Resumen de Arquitectura y Alta Disponibilidad

### Componentes de Infraestructura

| Componente                  | Implementación                       | Modelo HA                                    |
| --------------------------- | ------------------------------------ | -------------------------------------------- |
| Cómputo                     | EKS (Kubernetes 1.33) + Karpenter    | Nodos multi-AZ, Spot + bajo demanda          |
| Autoescalado de pods        | KEDA                                 | Basado en CPU/Memoria, mínimo 2 réplicas     |
| Ingreso / SSL               | ALB + ACM                            | Multi-AZ, enrutamiento por health-check      |
| Caché                       | ElastiCache Redis (condicional)      | Multi-AZ con failover automático             |
| Cola de mensajes            | Amazon MQ / RabbitMQ (condicional)   | Instancia individual o activo/en espera      |
| Base de datos (autoalojado) | Clúster HA CloudNativePG + PgBouncer | Primario + réplicas, failover automático     |
| Base de datos (nube)        | Supabase Cloud                       | Administrado, multi-región por el proveedor  |
| Observabilidad              | SigNoz + k8s-infra (condicional)     | Dentro del clúster, sin punto único de falla |
| Estado IaC                  | S3 (versionado) + DynamoDB lock      | Cifrado, versionado                          |
| Volúmenes persistentes      | EBS (vía EBS CSI Driver)             | Snapshots vía AWS Data Lifecycle Manager     |

### Capacidades HA Actuales

| Capacidad                              | Tiempo de Recuperación | Pérdida de Datos     | Estado                          |
| -------------------------------------- | ---------------------- | -------------------- | ------------------------------- |
| Fallo de AZ (pods)                     | 0–5 min                | Ninguna              | Activo                          |
| Fallo / crash de pod                   | 0–2 min                | Ninguna              | Activo                          |
| Re-enrutamiento por health-check ALB   | 0–1 min                | Ninguna              | Activo                          |
| Failover Multi-AZ de Redis             | \< 1 min               | Ninguna              | Activo (cuando está habilitado) |
| Sustitución de nodos Karpenter         | 0–10 min               | Ninguna              | Activo                          |
| Restauración de snapshot EBS           | 15–30 min              | Hasta 24 h           | Activo                          |
| Restauración PITR de CloudNativePG     | 15–60 min              | Hasta el retraso WAL | Activo (cuando está habilitado) |
| Recreación completa de infraestructura | 30–60 min              | Ninguna (IaC)        | Vía Terragrunt                  |

***

## Objetivos RTO / RPO

| Escenario                      | Objetivo RTO | Objetivo RPO                         | Capacidad Actual                    |
| ------------------------------ | ------------ | ------------------------------------ | ----------------------------------- |
| Fallo de un solo pod           | \< 2 min     | 0                                    | Cumplido (réplicas mínimas KEDA)    |
| Fallo de un solo nodo          | \< 10 min    | 0                                    | Cumplido (sustitución Karpenter)    |
| Fallo de AZ                    | \< 5 min     | 0                                    | Cumplido (distribución multi-AZ)    |
| Fallo de Redis                 | \< 1 min     | 0                                    | Cumplido (failover multi-AZ)        |
| Fallo del primario de Postgres | \< 5 min     | 0–segundos de retraso WAL            | Cumplido (failover automático CNPG) |
| Pérdida de volumen EBS         | 15–30 min    | \< 24 h                              | Parcial — snapshots DLM diarios     |
| Fallo de región completa       | > 60 min     | Depende de la frecuencia de respaldo | No automatizado actualmente         |

***

## Sistemas de Respaldo

### 1. Estado de Terraform / Terragrunt — S3

**Qué se respalda:** Todo el estado de infraestructura (EKS, red, IAM, releases de Helm).

**Implementación:**

* Bucket S3 por entorno: `ekb-terraform-state-<env-name>` (inicializado vía `terragrunt/environments/<env-name>/state/`)
* Versionado habilitado — cualquier versión anterior del estado puede ser restaurada
* Cifrado del lado del servidor (AES-256)
* Tabla DynamoDB para bloqueo de estado

**Recuperación:** Revertir a cualquier versión anterior del estado en S3, luego volver a ejecutar `terragrunt apply`.

**RPO:** Cada commit de `terragrunt apply` — continuo.

***

### 2. Volúmenes Persistentes EBS — AWS Data Lifecycle Manager

**Qué se respalda:** Volúmenes EBS adjuntos a pods (PostgreSQL de Automator, MinIO de Supabase, cualquier carga de trabajo con estado).

**Implementación:** Política de AWS Data Lifecycle Manager (DLM) dirigida a etiquetas de entorno.

```bash theme={null}
# Etiquete los volúmenes EBS con el nombre de su entorno, luego cree una política DLM:
# - Recurso: Volúmenes EBS
# - Etiqueta objetivo: Environment=<your-env-name>
# - Horario: Diario a las 02:00 UTC
# - Retención: 7 snapshots
```

**Recuperación:**

```bash theme={null}
# 1. Identificar el snapshot a restaurar
aws ec2 describe-snapshots --filters "Name=tag:Environment,Values=<your-env-name>"
 
# 2. Crear un volumen a partir del snapshot
aws ec2 create-volume \
  --snapshot-id snap-xxxxxxxxxxxxxxxxx \
  --availability-zone <your-az> \
  --volume-type gp3
 
# 3. Actualizar el PersistentVolume en Kubernetes para referenciar el nuevo ID de volumen
kubectl patch pv <pv-name> -p '{"spec":{"awsElasticBlockStore":{"volumeID":"<new-vol-id>"}}}'
```

**RPO:** Hasta 24 horas (snapshots diarios). Reducir aumentando la frecuencia del horario DLM.

***

### 3. CloudNativePG (DB HA de Supabase) — Respaldos Barman Cloud

**Aplica a:** Entornos con `ENABLE_CNPG=true` y `ENABLE_HA_SUPABASE_DB=true`.

**Qué se respalda:** El clúster Postgres de CloudNativePG (`ha-supabase-db`), incluyendo streaming continuo de WAL (Write-Ahead Log) a S3 o MinIO, y respaldos base completos programados vía el CRD `ScheduledBackup` de CNPG.

**Implementación** (configurado en `values/ha-supabase-db.yaml`):

```yaml theme={null}
postgres:
  backup:
    enabled: true                    # activar respaldos barman-cloud
    # barmanObjectStore apunta al bucket S3 o endpoint MinIO
    # IRSA / service account debe tener s3:PutObject, s3:GetObject, s3:ListBucket
    retentionPolicy: "30d"           # mantener respaldos por 30 días
    compression: gzip
```

**Verificar estado del respaldo:**

```bash theme={null}
# Listar todos los respaldos del clúster
kubectl get backup -n ha-supabase-db
 
# Verificar un respaldo específico
kubectl describe backup <backup-name> -n ha-supabase-db
 
# Activar un respaldo bajo demanda
kubectl cnpg backup ha-supabase-db -n ha-supabase-db
```

**Recuperación a punto en el tiempo (PITR):**

```yaml theme={null}
# Crear un nuevo CNPG Cluster restaurando desde un respaldo
# (en un nuevo namespace o después de eliminar el original)
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: ha-supabase-db-restored
  namespace: ha-supabase-db-restore
spec:
  instances: 3
  bootstrap:
    recovery:
      source: ha-supabase-db
      recoveryTarget:
        targetTime: "2026-03-19T03:00:00.000000+00:00"  # punto en el tiempo objetivo
  externalClusters:
    - name: ha-supabase-db
      barmanObjectStore:
        # misma configuración S3/MinIO que el clúster fuente
        serverName: ha-supabase-db
```

**RPO:** Casi cero para clústeres con WAL habilitado (segundos de retraso, limitados por el intervalo de carga WAL).

***

### 4. ElastiCache Redis — Replicación Multi-AZ

**Aplica a:** Entornos con `ENABLE_AWS_SERVICES=true`.

Redis no es un almacén de datos primario — almacena caché transitoria y datos de sesión. El enfoque DR está en un failover rápido en lugar de respaldo/restauración.

**Implementación:**

* Multi-AZ habilitado con failover automático
* Cifrado en reposo y en tránsito
* Un fallo del nodo primario promueve una réplica automáticamente (\< 1 min)

**RPO:** Los datos de Redis son efímeros por diseño. Las fallas de caché después del failover son esperadas; la aplicación repuebla desde la base de datos.

***

### 5. Amazon MQ (RabbitMQ — Cola de Mensajes

**Aplica a:** Entornos con `ENABLE_AWS_SERVICES=true`.

**Implementación:**

* Despliegue de instancia individual (predeterminado) o activo/en espera
* Los mensajes en tránsito pueden perderse durante un reinicio del broker; diseñar consumidores idempotentes
* UI de gestión disponible en el puerto 15671 (SSL)

**RPO:** Instancia individual — los mensajes en tránsito al momento del fallo pueden perderse. Usar el modo de despliegue activo/en espera para reducir este riesgo.

***

## Mecanismos de Auto-recuperación

### Karpenter — Provisionamiento y Recuperación de Nodos

* **Consolidación:** `WhenEmptyOrUnderutilized` — los nodos inactivos se terminan automáticamente
* **Manejo de interrupciones Spot:** Escucha eventos de interrupción SQS; drena y sustituye nodos Spot antes de la terminación
* **Deriva de nodos:** Los nodos que usan AMIs o configuraciones obsoletas se reemplazan automáticamente cuando `enable_drift = true`
* **Tiempo de recuperación:** Nuevo nodo provisionado en 0–10 minutos

### KEDA — Autoescalado de Pods

* **Réplicas mínimas:** 2 para todos los servicios (Web, API, Celery, Automator) — previene punto único de falla
* **Umbral de CPU:** 60–70% activa la escala ascendente
* **Umbral de memoria:** 80% activa la escala ascendente
* **Estabilización de escala descendente:** 30 segundos — evita fluctuaciones
* **Tiempo de recuperación:** Pods fallidos reprogramados dentro de 0–2 minutos

### Anti-afinidad de Pods de Kubernetes

Todos los servicios sin estado usan anti-afinidad `preferredDuringSchedulingIgnoredDuringExecution` en `kubernetes.io/hostname` para distribuir pods entre nodos y AZs.

```yaml theme={null}
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values: ["web", "fastapi-backend", "celery-worker", "automator"]
        topologyKey: kubernetes.io/hostname
```

***

## Procedimientos de Recuperación

### Escenario 1: Fallo de AZ

**Comportamiento esperado:** Karpenter provisiona nodos de reemplazo en las AZs restantes; KEDA reprograma pods; ALB deja de enrutar a objetivos no saludables.

**Verificación:**

```bash theme={null}
kubectl get nodes -o wide     # confirmar que los nodos están en AZs saludables
kubectl get pods -A -o wide   # confirmar que los pods se están ejecutando
kubectl get ingress            # confirmar que ALB está enrutando correctamente
```

<Info>
  No se requiere intervención manual bajo circunstancias normales.
</Info>

***

### Escenario 2: Fallo del Nodo Primario de Postgres (CloudNativePG)

CloudNativePG promueve automáticamente una réplica a primario.

```bash theme={null}
# Monitorear el failover
kubectl get cluster ha-supabase-db -n ha-supabase-db -w
 
# Confirmar el nuevo primario
kubectl cnpg status ha-supabase-db -n ha-supabase-db
 
# Verificar que el pooler PgBouncer apunta al nuevo primario
kubectl get svc -n ha-supabase-db | grep pooler
```

Las aplicaciones se reconectan vía PgBouncer — no se necesita cambiar la cadena de conexión.

***

### Escenario 3: Restaurar Volumen EBS desde Snapshot

```bash theme={null}
# 1. Buscar snapshots del entorno
aws ec2 describe-snapshots \
  --filters "Name=tag:Environment,Values=<your-env-name>" \
  --query 'Snapshots[*].[SnapshotId,StartTime,VolumeSize]' \
  --output table
 
# 2. Crear un nuevo volumen a partir del snapshot elegido
aws ec2 create-volume \
  --snapshot-id snap-xxxxxxxxxxxxxxxxx \
  --availability-zone <target-az> \
  --volume-type gp3 \
  --tag-specifications 'ResourceType=volume,Tags=[{Key=Environment,Value=<your-env-name>}]'
 
# 3. Reducir las réplicas de la carga de trabajo afectada
kubectl scale deployment <workload> --replicas=0
 
# 4. Actualizar el PV para referenciar el nuevo volumen EBS, luego restaurar las réplicas
kubectl patch pv <pv-name> -p '{"spec":{"csi":{"volumeHandle":"<new-volume-id>"}}}'
kubectl scale deployment <workload> --replicas=2
```

***

### Escenario 4: Recreación Completa de Infraestructura

Usado después de un fallo catastrófico o al reconstruir una región.

```bash theme={null}
# 1. Inicializar el bucket de estado (si no existe)
cd terragrunt/environments/<your-env-name>/state
terragrunt apply
 
# 2. Recrear el cluster EKS y la infraestructura central
cd terragrunt/environments/<your-env-name>
terragrunt apply
 
# 3. Desplegar servicios en orden (ver Guía de Despliegue con Terragrunt § Fase 6)
ENABLE_CNPG=true terragrunt apply --target='helm_release.local["cloudnative-pg"]'
ENABLE_HA_SUPABASE_DB=true terragrunt apply --target='helm_release.local["ha-supabase-db"]'
ENABLE_SUPABASE=true terragrunt apply --target='helm_release.local["supabase"]'
```

**RTO estimado:** 30–60 minutos para el clúster completo; 60–120 minutos si se deben restaurar datos de EBS/CNPG.

***

### Escenario 5: Reversión de Estado de Terragrunt

```bash theme={null}
# Listar versiones de estado en S3
aws s3api list-object-versions \
  --bucket ekb-terraform-state-<your-env-name> \
  --prefix <state-key>
 
# Restaurar una versión específica
aws s3api get-object \
  --bucket ekb-terraform-state-<your-env-name> \
  --key <state-key> \
  --version-id <version-id> \
  terraform.tfstate
 
# Re-importar o aplicar con el estado restaurado
```

***

## Observabilidad y Alertas (SigNoz)

Cuando `ENABLE_SIGNOZ=true`, SigNoz se despliega en el namespace `monitoring` y proporciona:

* Traza distribuida para todos los servicios de EKB
* Métricas del clúster vía el agente DaemonSet k8s-infra (CPU, memoria, estado de pods)
* Agregación de logs de todos los pods
* Alertas — configure reglas de alerta en SigNoz para notificar sobre bucles de crash de pods, altas tasas de error o presión de nodos

Para fines de DR, los paneles de SigNoz son la herramienta principal para diagnosticar y confirmar la recuperación después de un incidente. Los datos de SigNoz se almacenan en volúmenes EBS PV y están cubiertos por la política de snapshots EBS.

***

## Brechas y Recomendaciones

| Brecha                                            | Riesgo                                                           | Recomendación                                                                                    |
| ------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Sin replicación multi-región                      | Fallo de región completa = RTO extendido                         | Considerar réplica de lectura multi-región RDS o replicación multi-región S3 para respaldos CNPG |
| Snapshots EBS son diarios                         | Hasta 24 h de pérdida de datos para cargas de trabajo con EBS    | Aumentar la frecuencia DLM a horaria para volúmenes críticos                                     |
| RabbitMQ de instancia individual (predeterminado) | Mensajes en tránsito perdidos en fallo del broker                | Cambiar a modo de despliegue `ACTIVE_STANDBY_MULTI_AZ` para producción                           |
| Sin simulacro DR automatizado                     | Procedimientos de recuperación sin probar hasta que se necesiten | Programar simulacros trimestrales; probar restauración PITR de CNPG en un entorno de staging     |
| SigNoz en el mismo clúster                        | Observabilidad perdida durante fallo del clúster                 | Considerar un endpoint de monitoreo ligero separado o alertas de respaldo de CloudWatch          |
