ConTodo
DevOps & AWS

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

  1. 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.
  2. 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).
  3. IaC como única fuente de verdad. Cero cambios manuales en consola fuera de incidentes. Todo en Terraform versionado, con plan revisado en cada PR.
  4. 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.
  5. 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

SupuestoValorJustificación
Usuarios activos por cliente (promedio)8PYME textil/comercial típica
Ratio usuarios concurrentes25%Pico horario laboral Perú (GMT-5)
RPS por usuario concurrente0,3ERP transaccional, no streaming
Tamaño DB por cliente (año 1)0,8–1,5 GBDocumentos, kardex, asientos, adjuntos en S3
Jobs Sidekiq por cliente/día200–600Facturación electrónica, PLE/SIRE, BI, correos
Región primariaus-east-1Menor precio AWS; latencia Perú ~90 ms aceptable
Región DRus-west-2Replicación cross-region para RPO/RTO
CDN/edgeCloudFrontPunto 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-1 por 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

ComponenteServicio AWSFunción en ConTodo
DNSRoute53app.contodo.pe, api.contodo.pe, failover DR
CDN/EdgeCloudFront + ACMCache de SPA React, TLS, compresión, geo
Firewall L7AWS WAFOWASP Top 10, rate limiting, geo-block, bot control
BalanceoALBDistribución a tasks ECS, health checks, sticky por JWT no
Compute webECS Fargate (Rails/Puma)API REST/GraphQL, render server-side mínimo
Compute asyncECS Fargate (Sidekiq)Facturación electrónica, PLE/SIRE, correos, BI
Base de datosRDS PostgreSQL 16 Multi-AZOLTP multi-tenant, RLS por company_id
Réplica lecturaRDS Read ReplicaReportes BI y Estados Financieros pesados
Cache/ColaElastiCache RedisCache, sesiones, broker Sidekiq, rate limit
ObjetosS3SPA estática, adjuntos, XML/CDR de SUNAT, backups lógicos
SecretosSecrets ManagerCredenciales DB, tokens OSE, claves API, rotación
ObservabilidadCloudWatch + X-RayLogs, métricas, trazas, alarmas, dashboards
Backup/DRAWS BackupSnapshots cifrados, copia cross-region
CifradoKMSCMK por dominio (DB, S3, Redis)

3. Red y seguridad

3.1 Topología VPC

  • VPC 10.0.0.0/16 en us-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

CapaControl
BordeWAF managed rules (Core, SQLi, Linux), rate limit 2.000 req/5min/IP, geo-allow LATAM+EEUU
TransporteTLS 1.2+ en CloudFront/ALB, HSTS, certificados ACM auto-renovados
IdentidadCognito o JWT propio; MFA para admins de tenant; IAM roles por servicio (sin llaves estáticas)
DatosKMS CMK, RLS PostgreSQL por company_id, cifrado de columnas sensibles (DNI, cuentas)
SecretosSecrets Manager con rotación automática de credenciales RDS cada 30 días
RedSecurity Groups mínimos (ALB→web:3000, web→RDS:5432, web→Redis:6379)
AuditoríaCloudTrail org-wide, GuardDuty, Security Hub, Config rules

4. Estrategia CI/CD

4.1 Pipeline

  1. PR a main dispara: linters (RuboCop, ESLint), tests (RSpec, Jest, cobertura ≥80%), SAST (Brakeman), escaneo de imagen (Trivy), npm/bundle audit.
  2. 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.
  3. 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).
  4. Staging: despliegue automático tras merge + smoke tests.
  5. 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.
  6. Versionado de infra: cada PR a Terraform corre plan comentado en el PR; apply solo tras aprobación en main ví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 tfvars cifrados (SOPS/KMS), terraform fmt/validate/tflint en CI, módulos versionados, prevent_destroy en RDS/S3 de estado, y checkov para policy-as-code.


6. Backups y Disaster Recovery

6.1 Objetivos

MétricaMVP/PymeEnterprise
RPO (pérdida máx. de datos)1 hora5 minutos
RTO (tiempo máx. de recuperación)4 horas1 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-2 ví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.4xlarge segú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

ServicioMVP (~5 clientes)100 clientes500 clientes1.000 clientes5.000 clientes
ECS Fargate web601805209503.800
ECS Fargate Sidekiq (Spot)25702204201.700
RDS PostgreSQL Multi-AZ1302906201.1504.200
RDS Read Replica(s)0702204802.100
ElastiCache Redis50902304301.500
S3 (storage + req)52590180750
CloudFront (transfer)10351302501.100
ALB2025354590
NAT Gateway35457095220
Route53 + ACM345610
WAF12183045120
Secrets Manager48152560
CloudWatch + X-Ray1540110200700
AWS Backup + CRR103090170650
KMS346820
Data transfer out830110210900
Subtotal infra3909642.4984.66417.920
Buffer/contingencia 15%591453757002.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)

CohorteRDSRead ReplicasRedisECS web (tasks)ECS Sidekiq (tasks)
MVPdb.t4g.medium (Single-AZ dev / Multi-AZ prod)0t4g.small21
100db.r6g.large1r7g.large42
500db.r6g.xlarge1r7g.large85
1.000db.r6g.2xlarge2r7g.xlarge149
5.000db.r6g.4xlarge (o Aurora)3 + shardingr7g.xlarge cluster3628

10. Riesgos, alternativas y recomendaciones

10.1 Riesgos

RiesgoImpactoMitigación
Vendor lock-in AWSAlto a largo plazoIaC portable, contenedores estándar; evitar servicios propietarios donde haya alternativa
Costo RDS dispara margen a escalaMedioReserved Instances, Graviton, evaluar Aurora Serverless v2, sharding por cohorte
Conexiones DB saturadas (Rails)AltoRDS Proxy / PgBouncer obligatorio desde 100 clientes
"Noisy neighbor" entre tenantsMedioRate limiting por tenant, colas Sidekiq segmentadas, silo dedicado para Enterprise
Latencia desde Perú (~90 ms)Bajo-MedioCloudFront edge en Lima; evaluar Local Zone si Enterprise lo exige
Picos de facturación electrónica (fin de mes)MedioAutoscaling Sidekiq por latencia de cola + Spot; pre-warm programado
Caída de SUNAT/OSEMedioReintentos 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

  1. Día 1: VPC multi-AZ, RDS Multi-AZ, IaC en Terraform, CI/CD con OIDC, WAF y Secrets Manager. No diferir seguridad.
  2. Desde 100 clientes: RDS Proxy, read replica, Savings Plans, alarmas de costo (AWS Budgets) y SLO formal.
  3. Desde 500: cross-region DR (warm standby), FinOps mensual, Reserved Instances.
  4. 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.