- Gestión de Estado — Inicializa el bucket S3 usado para almacenar el estado de Terraform del entorno.
- Infraestructura EKS — Provisiona la VPC, subredes, NAT gateways, roles IAM y el cluster EKS con grupos de nodos administrados.
- Almacenamiento y Balanceo de Carga — Despliega el controlador EBS CSI para volúmenes persistentes y el AWS Load Balancer Controller para el ingreso ALB.
- Autoescalado con Karpenter — Configura el provisionamiento dinámico de nodos con soporte para instancias Spot y manejo de interrupciones via SQS y EventBridge.
- Autoescalado con KEDA — Despliega KEDA para el autoescalado a nivel de pod basado en umbrales de CPU y memoria.
- Servicios de Datos — Provisiona Supabase (autoalojado o Cloud), ElastiCache Redis y Amazon MQ RabbitMQ.
- Servicios Odin — Despliega el stack de aplicación EKB (Web, FastAPI, Celery, Automator) vía Helm.
- Observabilidad con SigNoz — Despliega la traza distribuida, métricas y agregación de logs a través de SigNoz y el agente k8s-infra.
- Despliegue Final — Ejecuta un
terragrunt applycompleto para reconciliar los recursos restantes.
<YOUR_*> en la plantilla del entorno estén completados. Algunos valores, incluyendo el ID de VPC, el endpoint del cluster EKS y los endpoints de Redis y RabbitMQ, solo están disponibles después de fases específicas, por lo que la guía indica exactamente cuándo capturarlos y aplicarlos.
Prerrequisitos
- AWS CLI configurada con los permisos apropiados
- Terraform (>= 1.0)
- Terragrunt (última versión)
kubectlpara la gestión de Kuberneteshelmpara la gestión de charts Helm
Guía de Instalación
Instalando Terragrunt
macOS (Homebrew)Instalando kubectl
macOS (Homebrew)Instalando Helm
macOS (Homebrew)Verificando la Instalación
Configuración de AWS CLI
Creando un Nuevo Entorno
Paso 1: Copie la Plantilla del Entorno
La carpetaenv-template-folder contiene archivos pre-estructurados con placeholders <YOUR_*> listos para ser completados. Cópiala completamente para crear su nueva carpeta de entorno.
Paso 2: Verifique que Todos los Placeholders Estén Presentes
<YOUR_*>. Los pasos a continuación describen cómo completarlos archivo por archivo.
Paso 3: Provisione Certificados SSL (AWS ACM)
Antes de establecer las variables de entorno necesita los ARNs de los certificados. Use la Consola de AWS para solicitar certificados SSL en AWS Certificate Manager (ACM) para todos los dominios que servirá su entorno. Opción A: Un solo certificado wildcard (recomendado) Un solo certificado wildcard cubre todos los subdominios con un solo ARN. Por ejemplo, si su dominio base esapp.example.com, un solo certificado *.app.example.com cubre:
Opción B: Certificados por servicio
Solicite un certificado por dominio si no puede usar un wildcard. Repita los pasos a continuación para cada dominio:
<YOUR_WEB_DOMAIN>, <YOUR_API_DOMAIN>, <YOUR_AUTOMATOR_DOMAIN>, <YOUR_SUPABASE_DOMAIN> (solo si ENABLE_SUPABASE=true), <YOUR_SIGNOZ_DOMAIN> (solo si ENABLE_SIGNOZ=true).
Solicitando un certificado en la Consola de AWS
- Abra la consola de AWS Certificate Manager
- Cambie a la región correcta (arriba a la derecha) — debe coincidir con
<YOUR_AWS_REGION> - Haga clic en Solicitar un certificado → Solicitar un certificado público → Siguiente
- Debajo de Nombre de dominio completo, ingrese el wildcard (ej.,
*.app.example.com) o un dominio específico - Establezca el Método de validación en Validación por DNS
- Haga clic en Solicitar — el certificado se crea en estado
Pending validation
Incluya el punto final (
.) al final de los valores CNAME si su proveedor de DNS lo requiere.- Inicie sesión en Cloudflare → seleccione su dominio → vaya a DNS → Records → Add record
- Establezca el Tipo en
CNAME - Pegue el nombre CNAME de ACM en Name y el valor CNAME de ACM en Target
- Establezca el Estado del proxy en DNS only (icono de nube gris) — el certificado no se validará a través del proxy de Cloudflare
- Haga clic en Save
- Abra la consola de Route 53 → Hosted zones → seleccione su zona → Create record
- Establezca el Tipo de registro en
CNAME - Pegue el nombre CNAME de ACM en Record name (solo la parte del subdominio) y el valor en Value
- Establezca TTL en
300y haga clic en Create records
arn:aws:acm:<region>:<account-id>:certificate/<uuid>.
Paso 4: Establezca las Variables de Entorno
Establezca estas variables de entorno del shell antes de ejecutar cualquier comando de Terragrunt. Son leídas directamente porterragrunt.hcl a través de get_env().
Instancias Spot y Cargas de Trabajo con Estado
Las instancias Spot se configuran por NodePool envalues/karpenter.yaml, no a través de variables de entorno. Cada NodePool declara su propia estrategia de capacidad:
El NodePool
application usa familias de instancias m/c (generación 5+) con solo bajo demanda. Los pods del servicio Supabase se fijan aquí mediante nodeSelector: workload-type: "application" para garantizar que nunca sean interrumpidos por un evento de recuperación Spot.
El NodePool database-dedicated nunca usa Spot. Usa consolidationPolicy: WhenEmpty para que Karpenter no evict un nodo que aún tiene un pod ejecutándose, lo que lo hace seguro para cargas de trabajo con estado como PostgreSQL y réplicas de CloudNativePG.
Pautas para aplicaciones con estado en Spot:
- No programe bases de datos, colas persistentes o cualquier pod con un
PersistentVolumeClaimen NodePools Spot. - Use un
nodeSelectordirigido anode-type: database-dedicatedcon la toleranciadatabase-workload: "true"correspondiente para pods de bases de datos. - Use
nodeSelector: workload-type: "application"para servicios de usuario sin estado que deben permanecer disponibles sin interrupciones. - Para cargas de trabajo de segundo plano (Web, API, Celery, Automator), el NodePool Spot
generales apropiado — el manejador de interrupciones SQS de Karpenter drena los nodos Spot graciosamente antes de que AWS los recupere, y el conteo mínimo de réplicas de KEDA (≥ 2) garantiza disponibilidad durante la sustitución de nodos. - Para deshabilitar Spot globalmente, elimine
"spot"de la lista de valores en cada NodePool dentro devalues/karpenter.yaml.
karpenter en terragrunt.hcl:
Paso 5: Actualice los Valores Específicos del Entorno
Realice una búsqueda y reemplazo en todos los archivos de su nueva carpeta de entorno para los siguientes placeholders:5.1 terragrunt.hcl — Configuración central del cluster
5.2 state/terragrunt.hcl — Bucket de estado S3
5.3 values/infrastructure.yaml — AWS Load Balancer Controller
5.4 values/karpenter-values.yaml — Controlador Karpenter
5.5 values/karpenter-nodeclasses.yaml — Clases de nodos Karpenter
5.6 values/aws-ebs-csi-driver.yaml — Controlador EBS CSI
5.7 values/karpenter.yaml — Karpenter NodePools
Los nombres de clases de nodo (
general, compute-intensive, memory-intensive, gpu, database) deben coincidir con las entradas en karpenter-nodeclasses.yaml.
5.8 values/keda.yaml — KEDA Autoscaler
No se requieren placeholders específicos del entorno. Los límites de recursos y los conteos de réplicas están preconfigurados con valores predeterminados razonables. Revise y ajuste si es necesario.
5.9 values/supabase.yaml — Aplicación Supabase (solo si ENABLE_SUPABASE=true)
5.10 values/ha-supabase-db.yaml — DB HA de Supabase (solo si ENABLE_HA_SUPABASE_DB=true)
La clase de almacenamiento (
ebs-csi-gp2), el conteo de instancias y los límites de recursos están preconfigurados. Ajuste postgres.storage.size y postgres.walStorage.size para su volumen de datos esperado.
5.11 values/cloudnative-pg.yaml — Operador CloudNativePG (solo si ENABLE_CNPG=true)
No se requieren placeholders específicos del entorno. Esto despliega solo el controlador del operador CNPG. Los valores predeterminados (3 réplicas, límites de recursos) son adecuados para la mayoría de los entornos.
5.12 values/odin-services.yaml — Servicios de aplicación Odin
Supabase (
dataServiceConfig) — autoalojado (ENABLE_SUPABASE=true):
Supabase (
dataServiceConfig) — Supabase Cloud (ENABLE_SUPABASE=false):
Redis:
ENABLE_SUPABASE=true):
Claves Supabase del frontend web — Supabase Cloud (
ENABLE_SUPABASE=false):
5.13 values/signoz.yaml — Observabilidad SigNoz (solo si ENABLE_SIGNOZ=true)
5.14 values/signoz-k8s-infra.yaml — Métricas K8s de SigNoz (solo si ENABLE_SIGNOZ=true)
El endpoint del colector OTel (
signoz-otel-collector.monitoring.svc.cluster.local:4317) está preconfigurado asumiendo que tanto SigNoz como k8s-infra se despliegan en el namespace monitoring. No se necesita cambio a menos que use un nombre de release personalizado.
Recordatorio del Orden de Despliegue
Algunos valores solo están disponibles después de que cierta infraestructura se haya desplegado. Siga este orden:- Antes de cualquier despliegue — Establecer:
<YOUR_ENV_NAME>,<YOUR_AWS_REGION>,<YOUR_AWS_ACCOUNT_ID>,<YOUR_ENVIRONMENT>,<YOUR_PROJECT>,<YOUR_VPC_CIDR>, todos los nombres de dominio, todos los ARNs de certificados, todos los valores de Supabase,<YOUR_TOOLKIT_ENCRYPTION_KEY>, usuario/contraseña de RabbitMQ - Después de crear el cluster EKS — Establecer:
<YOUR_VPC_ID>(infrastructure.yaml),<YOUR_EKS_CLUSTER_ENDPOINT>(karpenter-values.yaml) - Después de
terraform applypara servicios AWS — Establecer:<YOUR_REDIS_HOST>,<YOUR_RABBITMQ_HOST>(odin-services.yaml)
Paso 6: Verifique que No Queden Placeholders
Fase 1: Configuración de Gestión de Estado
Propósito: Creación del bucket S3 para el estado de Terraform. Cada módulo de gestión de estado del entorno crea un bucket S3 con el patrónodin-terraform-state-{environment-name}, configura cifrado, versionado y bloqueo de acceso público, y usa estado local para el módulo de estado en sí (patrón de bootstrap).
Fase 2: Despliegue de Infraestructura EKS
Propósito: Red central (VPC, subredes, NAT gateway), roles y políticas IAM, cluster EKS y grupos de nodos administrados.2.1 Ejecución de Prueba — Infraestructura EKS
Infraestructura CentralUsando un Registro Docker Personalizado / Privado
Por defecto, las imágenes de EKB se descargan de Docker Hub usando un secreto llamadoregcred. Si el cliente aloja imágenes en un registro diferente, siga estos pasos antes de desplegar odin-services.
Paso 1 — Crear el imagePullSecret en el namespace destino
values/odin-services.yaml
2.2 Desplegar Infraestructura EKS
Paso 1: Infraestructura CentralFase 3: Almacenamiento y Balanceo de Carga
Propósito: Controlador EBS CSI para volúmenes persistentes, AWS Load Balancer Controller ejecutándose en el grupo de nodos administrado.3.1 Ejecución de Prueba — Almacenamiento y Balanceo de Carga
Controlador EBS CSI3.2 Desplegar Almacenamiento y Balanceo de Carga
Paso 1: Controlador EBS CSIFase 4: Autoescalado con Karpenter
Propósito: Roles IAM para Karpenter, manejo de interrupciones Spot, controlador Karpenter y pools de nodos.4.1 Ejecución de Prueba — Karpenter
Recursos IAM de Karpenterterragrunt.hcl)
Puede aparecer un error esperado durante el plan:
API did not recognize GroupVersionKind from manifest (CRD may not be installed). Esto es seguro de ignorar — Kubernetes valida los recursos contra la API en vivo durante el plan, antes de que se instalen los CRDs.4.2 Desplegar Karpenter
Paso 1: Recursos IAM de Karpenterterragrunt.hcl)
Fase 5: Autoescalado con KEDA
Propósito: KEDA para autoescalado a nivel de aplicación.5.1 Ejecución de Prueba — KEDA
5.2 Desplegar KEDA
Fase 6: Servicios de Datos
Propósito: Supabase (base de datos), ElastiCache (Redis), RabbitMQ (cola de mensajes).Despliegue primero el operador CloudNativePG, luego el clúster HA de Supabase DB, y luego la aplicación Supabase. El clúster de DB debe estar listo antes de que Supabase inicie.
6.1 Ejecución de Prueba — Servicios de Datos
Paso 1: Operador CloudNativePG (si está habilitado)6.2 Desplegar Servicios de Datos
Paso 1: Operador CloudNativePG (si está habilitado)EXTERNAL-IP si es LoadBalancer) como el valor de SUPABASE_POSTGRES_HOST en values/odin-services.yaml y como secret.db.postgresHost en values/supabase.yaml.
Paso 3: Aplicación Supabase (si está habilitado)
Todos los pods del servicio Supabase se ejecutan exclusivamente en el NodePool application de Karpenter (solo bajo demanda) para prevenir interrupciones Spot.
Fase 7: Servicios Odin
Propósito: Despliegue de la aplicación vía Helm.Antes de desplegar, reduzca temporalmente las réplicas de
fastapiBackend a una sola para la ejecución inicial de migración de base de datos — establezca replicaCount: 1, workers: 1 y keda.minReplicas: 1. Una vez que la migración se complete exitosamente, revierta estos valores a sus valores de producción predeterminados antes de volver a desplegar.7.1 Ejecución de Prueba — Servicios Odin
7.2 Desplegar Servicios Odin
Fase 8: Observabilidad con SigNoz
Propósito: Monitoreo de logs y métricas.8.1 Ejecución de Prueba — Charts de SigNoz
8.2 Desplegar Charts de SigNoz
Fase 9: Despliegue Final
9.1 Despliegue Completo
9.2 Verificar Despliegue
Solución de Problemas
Problemas de bloqueo de estadoLimpieza
Monitoreo y Registro
Referencia Rápida — Todos los Comandos de Despliegue
Reemplace
your-env-name con el nombre real de su entorno en todo momento. Siempre ejecute ejecuciones de prueba (terragrunt plan) primero para validar su configuración antes de aplicar cambios.