ConTodo ERP — Infraestructura AWS, CI/CD, IaC, DR y Costeo Cloud (DevOps & AWS)
ConTodo ERP — Plataforma Cloud-Native en AWS
Documento del Agente DevOps & AWS. Define la arquitectura de infraestructura para ConTodo, un ERP SaaS multi-tenant (Rails + PostgreSQL + Redis/Sidekiq + React) desplegado sobre AWS. Cubre el diagrama de arquitectura, la estrategia CI/CD, la Infraestructura como Código (Terraform), backups y Disaster Recovery, observabilidad, seguridad, y un modelo de costos mensual para MVP, 100, 500, 1.000 y 5.000 clientes. Las cifras son supuestos de planeación basados en precios públicos de AWS región
us-east-1(~junio 2026); deben revalidarse trimestralmente y contra una factura real.
1. Principios de diseño y supuestos
1.1 Principios rectores
- Multi-tenant por esquema lógico, no por infra física. Todos los tenants comparten el mismo clúster Rails y la misma instancia RDS; el aislamiento es a nivel de aplicación (columna
company_id+ Row-Level Security en PostgreSQL). Esto maximiza la densidad y reduce el costo por tenant. Para clientes Enterprise con requisitos de aislamiento estricto se ofrece un silo dedicado (RDS + ECS service propios) como SKU premium. - Stateless compute, stateful gestionado. Los contenedores Rails y Sidekiq son efímeros (Fargate); todo el estado vive en servicios gestionados (RDS, ElastiCache, S3). Esto permite escalado horizontal sin sesiones pegajosas (sesiones en Redis/JWT).
- IaC como única fuente de verdad. Cero cambios manuales en consola fuera de incidentes. Todo en Terraform versionado, con
planrevisado en cada PR. - Seguridad por defecto. Cifrado en reposo (KMS) y tránsito (TLS 1.2+), secretos en Secrets Manager, WAF al borde, principio de mínimo privilegio en IAM.
- Costo consciente del SaaS. Uso intensivo de Fargate Spot para workers, Savings Plans para baseline, S3 Intelligent-Tiering, y autoscaling agresivo.
1.2 Supuestos de capacidad
| Supuesto | Valor | Justificación |
|---|---|---|
| Usuarios activos por cliente (promedio) | 8 | PYME textil/comercial típica |
| Ratio usuarios concurrentes | 25% | Pico horario laboral Perú (GMT-5) |
| RPS por usuario concurrente | 0,3 | ERP transaccional, no streaming |
| Tamaño DB por cliente (año 1) | 0,8–1,5 GB | Documentos, kardex, asientos, adjuntos en S3 |
| Jobs Sidekiq por cliente/día | 200–600 | Facturación electrónica, PLE/SIRE, BI, correos |
| Región primaria | us-east-1 | Menor precio AWS; latencia Perú ~90 ms aceptable |
| Región DR | us-west-2 | Replicación cross-region para RPO/RTO |
| CDN/edge | CloudFront | Punto de presencia en Lima reduce latencia frontend |
Nota de soberanía de datos. Perú aún no exige residencia local de datos para ERP comercial, pero la Ley de Protección de Datos Personales (Ley 29733) y SUNAT obligan a confidencialidad y trazabilidad. Mantenemos
us-east-1por costo; si un cliente Enterprise exige residencia, AWS tiene zona local en Lima (Local Zone) y São Paulo (sa-east-1) como alternativa más cara.
2. Diagrama de arquitectura AWS
2.1 Componentes y su rol
| Componente | Servicio AWS | Función en ConTodo |
|---|---|---|
| DNS | Route53 | app.contodo.pe, api.contodo.pe, failover DR |
| CDN/Edge | CloudFront + ACM | Cache de SPA React, TLS, compresión, geo |
| Firewall L7 | AWS WAF | OWASP Top 10, rate limiting, geo-block, bot control |
| Balanceo | ALB | Distribución a tasks ECS, health checks, sticky por JWT no |
| Compute web | ECS Fargate (Rails/Puma) | API REST/GraphQL, render server-side mínimo |
| Compute async | ECS Fargate (Sidekiq) | Facturación electrónica, PLE/SIRE, correos, BI |
| Base de datos | RDS PostgreSQL 16 Multi-AZ | OLTP multi-tenant, RLS por company_id |
| Réplica lectura | RDS Read Replica | Reportes BI y Estados Financieros pesados |
| Cache/Cola | ElastiCache Redis | Cache, sesiones, broker Sidekiq, rate limit |
| Objetos | S3 | SPA estática, adjuntos, XML/CDR de SUNAT, backups lógicos |
| Secretos | Secrets Manager | Credenciales DB, tokens OSE, claves API, rotación |
| Observabilidad | CloudWatch + X-Ray | Logs, métricas, trazas, alarmas, dashboards |
| Backup/DR | AWS Backup | Snapshots cifrados, copia cross-region |
| Cifrado | KMS | CMK por dominio (DB, S3, Redis) |
3. Red y seguridad
3.1 Topología VPC
- VPC
10.0.0.0/16enus-east-1, distribuida en 2 AZ (us-east-1a,us-east-1b); se amplía a 3 AZ a partir de 1.000 clientes. - Subnets públicas (
/24): ALB y NAT Gateway. Sin instancias con IP pública. - Subnets privadas app (
/22): tasks Fargate (web + worker). Salida a internet solo vía NAT. - Subnets privadas datos (
/24): RDS y ElastiCache, sin ruta a internet. - VPC Endpoints (Gateway/Interface) para S3, ECR, Secrets Manager y CloudWatch Logs: evita tráfico por NAT y reduce costo de egreso.
3.2 Controles de seguridad
| Capa | Control |
|---|---|
| Borde | WAF managed rules (Core, SQLi, Linux), rate limit 2.000 req/5min/IP, geo-allow LATAM+EEUU |
| Transporte | TLS 1.2+ en CloudFront/ALB, HSTS, certificados ACM auto-renovados |
| Identidad | Cognito o JWT propio; MFA para admins de tenant; IAM roles por servicio (sin llaves estáticas) |
| Datos | KMS CMK, RLS PostgreSQL por company_id, cifrado de columnas sensibles (DNI, cuentas) |
| Secretos | Secrets Manager con rotación automática de credenciales RDS cada 30 días |
| Red | Security Groups mínimos (ALB→web:3000, web→RDS:5432, web→Redis:6379) |
| Auditoría | CloudTrail org-wide, GuardDuty, Security Hub, Config rules |
4. Estrategia CI/CD
4.1 Pipeline
- PR a
maindispara: linters (RuboCop, ESLint), tests (RSpec, Jest, cobertura ≥80%), SAST (Brakeman), escaneo de imagen (Trivy),npm/bundle audit. - Build de imagen Docker multi-stage (Ruby 3.3-slim, assets React precompilados), tag con SHA y versión semántica, push a ECR con escaneo de vulnerabilidades on-push.
- Migraciones ejecutadas como ECS one-off task antes del despliegue (con lock advisory para evitar doble ejecución en multi-task). Migraciones siempre backward-compatible (expand/contract).
- Staging: despliegue automático tras merge + smoke tests.
- Producción: despliegue gated (aprobación manual). Estrategia blue-green con CodeDeploy o rolling con
minimumHealthyPercent=100/maximumPercent=200. Canary 10% → validación de métricas (errores 5xx, latencia p95) → 100% con auto-rollback ante alarma CloudWatch. - Versionado de infra: cada PR a Terraform corre
plancomentado en el PR;applysolo tras aprobación enmainvía OIDC (sin credenciales largas en GitHub).
5. Infraestructura como Código (Terraform)
Estructura modular con backend remoto en S3 + bloqueo en DynamoDB, separando ambientes por workspace/carpeta (dev, staging, prod).
# environments/prod/main.tf — extracto representativo
terraform {
required_version = ">= 1.7"
backend "s3" {
bucket = "contodo-tfstate-prod"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "contodo-tflock"
encrypt = true
}
}
module "network" {
source = "../../modules/network"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
enable_nat_gateway = true
}
module "rds" {
source = "../../modules/rds"
engine_version = "16.3"
instance_class = "db.r6g.large" # escala segun cohorte
allocated_storage = 200
max_allocated_storage = 2000 # autoscaling de disco
multi_az = true
read_replica_count = 1
backup_retention_days = 14
kms_key_arn = module.kms.rds_key_arn
deletion_protection = true
performance_insights = true
}
module "ecs_web" {
source = "../../modules/ecs-service"
cluster_arn = module.ecs.cluster_arn
family = "contodo-web"
cpu = 1024 # 1 vCPU
memory = 2048 # 2 GB
desired_count = 4
autoscaling_min = 4
autoscaling_max = 40
target_cpu_pct = 60
image = "${module.ecr.repo_url}:${var.app_version}"
capacity_provider = "FARGATE" # web en On-Demand/Savings Plan
}
module "ecs_worker" {
source = "../../modules/ecs-service"
family = "contodo-sidekiq"
cpu = 1024
memory = 2048
desired_count = 2
autoscaling_max = 30
capacity_provider = "FARGATE_SPOT" # workers tolerantes a interrupcion
scale_metric = "sidekiq_queue_latency"
}
module "redis" {
source = "../../modules/elasticache"
node_type = "cache.r7g.large"
num_node_groups = 1
replicas_per_ng = 1
multi_az = true
transit_enabled = true
at_rest_enabled = true
}
Buenas prácticas IaC. Variables por ambiente en
tfvarscifrados (SOPS/KMS),terraform fmt/validate/tflinten CI, módulos versionados,prevent_destroyen RDS/S3 de estado, ycheckovpara policy-as-code.
6. Backups y Disaster Recovery
6.1 Objetivos
| Métrica | MVP/Pyme | Enterprise |
|---|---|---|
| RPO (pérdida máx. de datos) | 1 hora | 5 minutos |
| RTO (tiempo máx. de recuperación) | 4 horas | 1 hora |
6.2 Estrategia de respaldo
- RDS: snapshots automáticos diarios + PITR (Point-in-Time Recovery) con retención de 14 días; logs de transacción permiten RPO de minutos. Snapshots copiados a
us-west-2vía AWS Backup (cross-region, cifrados con KMS multi-región). - S3: versionado activado + Cross-Region Replication (CRR) a
us-west-2; ciclo de vida → Glacier para XML/CDR > 1 año (SUNAT exige conservar 5 años). - Redis: snapshots diarios (cache reconstruible; no crítico para RPO).
- IaC: el estado y los módulos permiten reconstruir la infra completa en región DR en < 1 hora.
6.3 Patrón DR
- Estrategia primaria: Warm Standby para Enterprise — RDS read replica cross-region promovible + ECS service mínimo (1 task) en
us-west-2, Route53 con failover health-check. - Pilot Light para tiers Pyme — solo datos replicados; compute se provisiona on-demand vía Terraform ante desastre (RTO ~2–4 h).
- Game days trimestrales: simulacro de promoción de réplica y failover de Route53, documentado en runbook.
7. Escalado
7.1 Horizontal (preferente)
- ECS web: Target Tracking sobre CPU 60% y RequestCountPerTarget del ALB. Min 4, max 40 tasks. Escala de 4→40 cubre el salto de MVP a 5.000 clientes.
- ECS Sidekiq: escalado por latencia de cola (métrica custom a CloudWatch); colas críticas (facturación) tienen prioridad. Fargate Spot con fallback a On-Demand.
- RDS Read Replicas: 1 → 3 réplicas para descargar reportes BI/Estados Financieros conforme crece la cohorte.
7.2 Vertical (cuando aplica)
- RDS: escalonado
db.r6g.large → r6g.xlarge → r6g.2xlarge → r6g.4xlargesegún conexiones e IOPS. Usar PgBouncer/RDS Proxy para multiplexar conexiones (Rails abre muchas). - Redis:
r7g.large → r7g.xlarge; activar cluster mode (sharding) a partir de ~1.000 clientes.
7.3 Particionado de datos (a futuro)
A 5.000+ clientes se evalúa sharding por cohorte de tenants (varios clústeres RDS, cada uno con N tenants) y/o Aurora PostgreSQL para mayor throughput y autoscaling de cómputo (Serverless v2). El diseño multi-tenant con company_id facilita migrar tenants entre shards.
8. Observabilidad
- CloudWatch Logs centralizados (Fargate
awslogs), retención 30 días + export a S3/Athena para análisis histórico barato. - Métricas custom: latencia de colas Sidekiq, tiempo de facturación electrónica por tenant, errores SUNAT, p95 por endpoint.
- Trazas: AWS X-Ray para requests cross-service.
- Alarmas: 5xx > 1%, latencia p95 > 800 ms, CPU RDS > 80%, cola Sidekiq > 5 min, free storage RDS < 15%. Notificación a SNS → Slack/PagerDuty.
- Dashboards por dominio (App, DB, Colas, Costos) y SLO: 99,9% disponibilidad mensual.
9. Tabla de costos mensual estimada (USD)
Precios públicos AWS
us-east-1, ~junio 2026. Incluye Savings Plans estimados para baseline de cómputo. Excluye soporte AWS, impuestos (IGV 18% en factura Perú) y descuentos por compromiso plurianual. Cifras redondeadas; rango ±20%.
9.1 Resumen por cohorte
| Servicio | MVP (~5 clientes) | 100 clientes | 500 clientes | 1.000 clientes | 5.000 clientes |
|---|---|---|---|---|---|
| ECS Fargate web | 60 | 180 | 520 | 950 | 3.800 |
| ECS Fargate Sidekiq (Spot) | 25 | 70 | 220 | 420 | 1.700 |
| RDS PostgreSQL Multi-AZ | 130 | 290 | 620 | 1.150 | 4.200 |
| RDS Read Replica(s) | 0 | 70 | 220 | 480 | 2.100 |
| ElastiCache Redis | 50 | 90 | 230 | 430 | 1.500 |
| S3 (storage + req) | 5 | 25 | 90 | 180 | 750 |
| CloudFront (transfer) | 10 | 35 | 130 | 250 | 1.100 |
| ALB | 20 | 25 | 35 | 45 | 90 |
| NAT Gateway | 35 | 45 | 70 | 95 | 220 |
| Route53 + ACM | 3 | 4 | 5 | 6 | 10 |
| WAF | 12 | 18 | 30 | 45 | 120 |
| Secrets Manager | 4 | 8 | 15 | 25 | 60 |
| CloudWatch + X-Ray | 15 | 40 | 110 | 200 | 700 |
| AWS Backup + CRR | 10 | 30 | 90 | 170 | 650 |
| KMS | 3 | 4 | 6 | 8 | 20 |
| Data transfer out | 8 | 30 | 110 | 210 | 900 |
| Subtotal infra | 390 | 964 | 2.498 | 4.664 | 17.920 |
| Buffer/contingencia 15% | 59 | 145 | 375 | 700 | 2.688 |
| TOTAL mensual estimado | ~449 | ~1.109 | ~2.873 | ~5.364 | ~20.608 |
| Costo por cliente/mes | ~90 | ~11,1 | ~5,7 | ~5,4 | ~4,1 |
9.2 Lectura del modelo
- Economías de escala claras: el costo por cliente cae de ~$90 (MVP, infra subutilizada) a ~$4 a 5.000 clientes. La densidad multi-tenant es el principal driver de margen.
- RDS es el mayor centro de costo (~25–30% del total) en todas las cohortes. Optimizaciones: Aurora Serverless v2, Graviton (r6g/r7g ~20% más barato que Intel), Reserved Instances a escala (hasta 40% off con compromiso 1 año).
- Fargate web + Spot workers: Savings Plans de cómputo (1 año, no-upfront) ahorran ~30% del baseline. Workers en Spot ahorran ~60% adicional en async.
- Data transfer y CloudFront crecen con tráfico; VPC Endpoints reducen el egreso interno por NAT.
- Margen de software: si ConTodo cobra
$25–40/cliente/mes (según pricing del agente CEO), el costo de infra a escala ($4–6) deja un margen de infraestructura > 80%, sano para SaaS B2B.
9.3 Configuración de cómputo por cohorte (referencia)
| Cohorte | RDS | Read Replicas | Redis | ECS web (tasks) | ECS Sidekiq (tasks) |
|---|---|---|---|---|---|
| MVP | db.t4g.medium (Single-AZ dev / Multi-AZ prod) | 0 | t4g.small | 2 | 1 |
| 100 | db.r6g.large | 1 | r7g.large | 4 | 2 |
| 500 | db.r6g.xlarge | 1 | r7g.large | 8 | 5 |
| 1.000 | db.r6g.2xlarge | 2 | r7g.xlarge | 14 | 9 |
| 5.000 | db.r6g.4xlarge (o Aurora) | 3 + sharding | r7g.xlarge cluster | 36 | 28 |
10. Riesgos, alternativas y recomendaciones
10.1 Riesgos
| Riesgo | Impacto | Mitigación |
|---|---|---|
| Vendor lock-in AWS | Alto a largo plazo | IaC portable, contenedores estándar; evitar servicios propietarios donde haya alternativa |
| Costo RDS dispara margen a escala | Medio | Reserved Instances, Graviton, evaluar Aurora Serverless v2, sharding por cohorte |
| Conexiones DB saturadas (Rails) | Alto | RDS Proxy / PgBouncer obligatorio desde 100 clientes |
| "Noisy neighbor" entre tenants | Medio | Rate limiting por tenant, colas Sidekiq segmentadas, silo dedicado para Enterprise |
| Latencia desde Perú (~90 ms) | Bajo-Medio | CloudFront edge en Lima; evaluar Local Zone si Enterprise lo exige |
| Picos de facturación electrónica (fin de mes) | Medio | Autoscaling Sidekiq por latencia de cola + Spot; pre-warm programado |
| Caída de SUNAT/OSE | Medio | Reintentos con backoff, colas de reproceso, alertas |
10.2 Alternativas evaluadas
- ECS Fargate vs EKS (Kubernetes): se elige Fargate por menor overhead operativo en etapa temprana (sin gestionar nodos/control plane). EKS se reconsidera a > 2.000 clientes si se requiere flexibilidad de scheduling avanzada o multi-cloud.
- RDS vs Aurora: se inicia con RDS PostgreSQL (más barato y simple); se migra a Aurora a escala por su mejor throughput, réplicas más rápidas y Serverless v2 para cargas variables.
- AWS Copilot/App Runner: descartados frente a Terraform por necesidad de control fino multi-ambiente y policy-as-code.
- Multi-cloud: no recomendado en fase 1 (complejidad). Mantener portabilidad como seguro, no como objetivo inmediato.
10.3 Recomendaciones priorizadas
- Día 1: VPC multi-AZ, RDS Multi-AZ, IaC en Terraform, CI/CD con OIDC, WAF y Secrets Manager. No diferir seguridad.
- Desde 100 clientes: RDS Proxy, read replica, Savings Plans, alarmas de costo (AWS Budgets) y SLO formal.
- Desde 500: cross-region DR (warm standby), FinOps mensual, Reserved Instances.
- Desde 1.000: evaluar Aurora, 3 AZ, sharding plan, EKS spike.
11. Conclusión
La arquitectura propuesta es cloud-native, multi-AZ, segura por defecto y económicamente escalable: parte de ~$450/mes en MVP y soporta 5.000 clientes por $20.600/mes ($4/cliente), habilitando márgenes de infraestructura superiores al 80% para el negocio SaaS. El uso de Fargate, RDS gestionado, Spot para async, Graviton y Savings Plans optimiza costo sin sacrificar resiliencia (RPO 5 min / RTO 1 h en Enterprise). La disciplina de IaC, CI/CD gated y observabilidad con SLO 99,9% sostiene operación confiable a escala LATAM. Las cifras son supuestos de planeación y deben validarse contra factura real y revisarse cada trimestre con prácticas FinOps.