Social Bot Scheduler

☁️ Migración a AWS — Social Bot Scheduler#

AWS IaC Containers Security: Hardened

Importante

Este documento es la guía maestra para migrar el laboratorio Social Bot Scheduler desde un entorno localhost (Docker Compose) hacia Amazon Web Services. Cubre arquitectura, servicios candidatos, paso a paso, costos estimados, seguridad y observabilidad.


📋 Tabla de Contenidos#


🎯 Objetivos de la Migración#

🎯 Objetivo📌 Descripción
DisponibilidadPasar de single-host a Multi-AZ con SLA ≥ 99.9%.
EscalabilidadAuto-scaling horizontal según métricas (CPU, RPS, cola).
SeguridadEliminar binding a 127.0.0.1 y aplicar VPC + IAM + Secrets Manager.
ObservabilidadCentralizar logs, métricas y trazas con CloudWatch + X-Ray.
CostoPay-per-use con Spot, Savings Plans y Graviton cuando aplique.
Reproducibilidad100% Infrastructure-as-Code (Terraform o AWS CDK).

🧭 Estado Actual vs. Estado Objetivo#

🖥️ Estado Actual (localhost)#

diagrama mermaid
graph TB
    subgraph "🖥️ Host Único (Docker Compose)"
        N[n8n :5678]
        D[Dashboards :8081-8100]
        DB1[(MySQL/MariaDB/PG/...)]
        OBS[Prometheus + Grafana]
        N --> DB1
        D --> DB1
        N -.-> OBS
    end

☁️ Estado Objetivo (AWS Multi-AZ)#

diagrama mermaid
graph TB
    U[👤 Usuarios] --> R53[Route 53]
    R53 --> CF[CloudFront + WAF]
    CF --> ALB[Application Load Balancer]

    subgraph "VPC Multi-AZ"
        subgraph "Public Subnets"
            ALB
            NAT[NAT Gateway]
        end
        subgraph "Private Subnets - Compute"
            ECS1[ECS Fargate: n8n]
            ECS2[ECS Fargate: Dashboards]
            ECS3[ECS Fargate: Receptores]
        end
        subgraph "Private Subnets - Data"
            RDS[(RDS/Aurora Multi-AZ<br/>PostgreSQL/MySQL<br/>+ pgvector/Timescale/RLS)]
            DDB[(DynamoDB<br/>Mnesia/Firestore)]
            REDIS[(ElastiCache Redis)]
            DOCDB[(DocumentDB)]
            KEYS[(Keyspaces - Cassandra)]
            NEP[(Neptune - Neo4j)]
            TS[(Timestream - InfluxDB)]
            MSK[[Amazon MSK - Kafka]]
            IOT[[IoT Core - MQTT]]
        end
        ALB --> ECS1
        ALB --> ECS2
        ALB --> ECS3
        ECS1 --> RDS
        ECS2 --> RDS
        ECS3 --> DDB
        ECS3 --> REDIS
        ECS3 --> NEP
        ECS3 --> TS
        IOT --> MSK --> ECS3
    end

    ECS1 -.-> SM[Secrets Manager]
    ECS1 -.-> CW[CloudWatch Logs/Metrics]
    ECS1 -.-> XR[X-Ray]

🏛️ Estrategias de Migración (6 R's)#

Consejo

AWS define seis estrategias clásicas. Para este laboratorio recomendamos Replatform combinado con Refactor selectivo.

EstrategiaAplicación al RepositorioRecomendado
Rehost (Lift & Shift)EC2 + Docker Compose tal cual. Mínimo esfuerzo, máximo costo operativo.⚠️
Replatform (Lift & Reshape)Imágenes a ECR, contenedores a ECS Fargate, DBs a RDS/DocumentDB.
RefactorConvertir n8n + receptores a Lambda + EventBridge + Step Functions.🎯 (fase 2)
RepurchaseSustituir n8n por AWS Step Functions o Amazon AppFlow.
RetireApagar componentes redundantes (cAdvisor, dashboards duplicados).
RetainMantener localhost para desarrollo.

🧩 Servicios AWS Candidatos#

🚢 Cómputo de Contenedores#

ServicioCaso de UsoTrade-off
ECS FargateRecomendado para n8n + receptores. Serverless, sin gestión de nodos.💵 ~20% más caro que EC2, sin acceso al kernel.
EKS (Kubernetes)Si el equipo ya domina K8s o requiere CRDs/Operators.🧠 Curva de aprendizaje + costo control plane ($72/mes).
EC2 + ECSMayor control, GPU, instancias Spot.🛠️ Mantenimiento de AMIs y parches.
AWS LambdaEndpoints idempotentes y receptores ligeros (<15 min, <10 GB).❄️ Cold starts, no apto para n8n stateful.
App RunnerDespliegue rápido desde repo Git, ideal para dashboards.📉 Menos control de red.

🗄️ Bases de Datos Gestionadas#

Motor LocalEquivalente AWSNotas
🐬 MySQL / 🍃 MariaDBRDS for MySQL o Aurora MySQLAurora ofrece 5× rendimiento.
🐘 PostgreSQLRDS for PostgreSQL o Aurora PostgreSQLCompatible con n8n.
📂 SQLiteEFS (archivo) o migrar a RDSSQLite no es cloud-native; preferir RDS.
🍃 MongoDBAmazon DocumentDBAPI-compatible con MongoDB 5.0.
🏎️ RedisAmazon ElastiCache for RedisMulti-AZ + cluster mode.
👁️ CassandraAmazon KeyspacesServerless, API CQL.
🏢 SQL ServerRDS for SQL ServerLicencia BYOL o License Included.
🦆 DuckDBAthena + S3 (Parquet)Patrón data-lake serverless.

Nota

A partir de la v4.9.0 la matriz alcanza 18+ motores heterogéneos (casos 01–20). Los motores incorporados en los casos 10–20 mapean así:

Motor LocalEquivalente AWSNotas
🧬 Mnesia (embebida BEAM)DynamoDB o EFSEstado embebido de Erlang/Elixir.
🧠 pgvector (Postgres)RDS/Aurora PostgreSQL + pgvectorPersistencia vectorial para RAG/IA.
📊 ClickHouseEC2/EKS self-managed o AthenaOLAP columnar de alto volumen.
🔐 Supabase (Postgres + RLS)RDS PostgreSQL + PostgRESTBaaS con Row-Level Security.
🪳 CockroachDBCockroachDB Cloud o self-managed en EKSSQL distribuido compatible con Postgres.
⏱️ TimescaleDBRDS PostgreSQL + extensión o TimestreamSeries temporales sobre GraphQL.
📈 InfluxDBAmazon TimestreamMétricas IoT/MQTT.
🕸️ Neo4jAmazon NeptuneBase de datos de grafos (Cypher).
🔥 Firestore (emulador)DynamoDBDocumental para mobile-backend.
📨 Kafka (KRaft) (caso 13, bus de eventos)Amazon MSK o MSK ServerlessStreaming / event sourcing (patrón CQRS que alimenta a ClickHouse).
🦟 Mosquitto (MQTT) (caso 17, broker IoT)AWS IoT CoreIngesta de telemetría MQTT hacia el sink de series temporales.
🕰️ XTDB (caso 19, verificación pendiente)EC2/EKS self-managedBitemporal (funcional puro).

🌐 Red y Edge#

ServicioFunción
VPCAislamiento de red (subnets públicas/privadas en 2-3 AZs).
ALBBalanceo HTTP/HTTPS, path-based routing por caso.
Route 53DNS + health checks + failover.
CloudFrontCDN + caché para dashboards estáticos.
WAFProtección OWASP Top 10.
ACMCertificados TLS gratuitos.
API GatewaySi se exponen webhooks externos con throttling.

🔐 Seguridad e Identidad#

ServicioUso
IAMRoles por tarea ECS (Task Role + Execution Role).
Secrets ManagerReemplaza .env. Rotación automática.
Parameter StoreConfiguración no sensible.
KMSCifrado at-rest en RDS/S3/EBS.
GuardDutyDetección de amenazas.
InspectorEscaneo de imágenes en ECR (sustituye Trivy en CI).
Security HubConsolidación CIS / PCI-DSS.

📦 Almacenamiento#

ServicioUso
S3Backups de DB, artefactos, posts.json, logs archivados.
EFSVolumen compartido para n8n (workflows persistentes).
EBSSolo si se usa EC2.
ECRRegistro privado de imágenes Docker.

📊 Observabilidad#

ServicioReemplaza
CloudWatch Logsdocker logs
CloudWatch MetricsPrometheus
CloudWatch DashboardsGrafana (o usar Amazon Managed Grafana)
AWS X-RayTrazas distribuidas
Amazon Managed Prometheus (AMP)Compatible con scrape configs existentes

🏗️ Arquitecturas de Referencia#

🥇 Opción A — Replatform con ECS Fargate (Recomendada)#

diagrama mermaid
graph LR
    DEV[👨‍💻 Dev] -->|git push| GH[GitHub]
    GH -->|Actions| ECR[ECR Registry]
    ECR --> ECS[ECS Fargate Cluster]

    subgraph "VPC"
        ALB[ALB] --> ECS
        ECS --> RDS[(Aurora PostgreSQL)]
        ECS --> EC[(ElastiCache)]
        ECS --> EFS[(EFS - n8n data)]
    end

    ECS --> CW[CloudWatch]
    ECS -.-> SM[Secrets Manager]

Ventajas: sin gestión de nodos, escalado por servicio, costo predecible.


🥈 Opción B — EKS para entornos K8s-native#

diagrama mermaid
graph LR
    GH[GitHub Actions] --> ECR
    ECR --> EKS[EKS Cluster Multi-AZ]
    EKS --> NS1[Namespace: n8n]
    EKS --> NS2[Namespace: receivers]
    EKS --> NS3[Namespace: observability]
    NS1 --> RDS[(RDS)]
    NS2 --> DDB[(DynamoDB)]
    NS3 --> AMP[Amazon Managed Prometheus]
    NS3 --> AMG[Amazon Managed Grafana]

Ideal cuando: se requieren Helm charts, Operators, o políticas avanzadas (Istio, Argo CD).


🥉 Opción C — Serverless (Refactor agresivo)#

diagrama mermaid
graph LR
    SCH[EventBridge Scheduler] --> LAMBDA1[λ Emisor]
    LAMBDA1 --> SF[Step Functions Workflow]
    SF --> LAMBDA2[λ Idempotency Check]
    SF --> SQS[SQS DLQ]
    SF --> LAMBDA3[λ Social API Caller]
    SF --> DDB[(DynamoDB)]
    SF --> APIGW[API Gateway] --> DASH[CloudFront + S3 Dashboards]

Ideal para: cargas burst, costos cercanos a cero en idle. Requiere reescribir n8n.


🚦 Comparativa: ECS Fargate vs EKS vs EC2#

CriterioECS FargateEKSEC2 + Docker
⏱️ Time-to-prod🟢 Días🟡 Semanas🟡 Semanas
💰 Costo control plane🟢 $0🔴 $72/mes🟢 $0
🧠 Curva de aprendizaje🟢 Baja🔴 Alta🟡 Media
🔧 Flexibilidad🟡 Media🟢 Alta🟢 Alta
🛡️ Aislamiento🟢 Por tarea🟢 Por pod🟡 Compartido
📈 Auto-scaling🟢 Nativo🟢 HPA/Cluster Autoscaler🟡 ASG manual
🩹 Parches OS🟢 AWS los gestiona🟡 Worker nodes🔴 Tu responsabilidad

Nota

Recomendación oficial: comienza con ECS Fargate y migra a EKS solo si aparece una necesidad real (multi-cloud, CRDs, Service Mesh).


💾 Mapeo de Bases de Datos#

diagrama mermaid
graph LR
    subgraph "Local Docker — Núcleo (01-09)"
        L1[MySQL]
        L2[MariaDB]
        L3[PostgreSQL]
        L4[SQLite]
        L5[MongoDB]
        L6[Redis]
        L7[Cassandra]
        L8[SQL Server]
        L9[DuckDB]
    end

    subgraph "Local Docker — Matriz (10-20)"
        M1[Mnesia]
        M2[pgvector]
        M3[ClickHouse]
        M4[Postgres+RLS]
        M5[CockroachDB]
        M6[TimescaleDB]
        M7[InfluxDB]
        M8[Neo4j]
        M9[Firestore emu]
        M10[Kafka]
    end

    subgraph "AWS Managed"
        A1[RDS / Aurora MySQL]
        A2[RDS / Aurora PostgreSQL<br/>+pgvector/Timescale/RLS]
        A3[DocumentDB]
        A4[ElastiCache Redis]
        A5[Keyspaces]
        A6[RDS SQL Server]
        A7[Athena + S3 Parquet]
        A8[DynamoDB]
        A9[ClickHouse self-managed]
        A10[CockroachDB Cloud]
        A11[Timestream]
        A12[Neptune]
        A13[Amazon MSK]
    end

    L1 --> A1
    L2 --> A1
    L3 --> A2
    L4 --> A2
    L5 --> A3
    L6 --> A4
    L7 --> A5
    L8 --> A6
    L9 --> A7
    M1 --> A8
    M9 --> A8
    M2 --> A2
    M4 --> A2
    M6 --> A2
    M3 --> A9
    M5 --> A10
    M7 --> A11
    M8 --> A12
    M10 --> A13

🔄 Estrategias de Carga Inicial#

OrigenHerramienta AWSModo
MySQL/PostgreSQLAWS DMSFull + CDC continuo
MongoDB → DocumentDBmongodump / mongorestoreSnapshot offline
RedisElastiCache import RDBRestore desde S3
Cassandra → KeyspacesDSBulkBatch CSV
SQLiteScript PythonOne-shot ETL
PostgreSQL + pgvector / TimescaleDB / RLSAWS DMS o pg_dump/pg_restoreFull; recrear extensiones (vector, timescaledb) y políticas RLS en destino
CockroachDBcockroach dumpIMPORT (Cockroach Cloud)Batch; o CDC vía changefeeds
ClickHouseclickhouse-client INSERT ... FROM S3 (Parquet)Bulk columnar desde S3
Neo4j → NeptuneNeptune Bulk Loader (CSV en S3)Exportar nodos/aristas Cypher → CSV
InfluxDB → TimestreamBatch API / script de reescrituraMigrar por measurement
Kafka → Amazon MSKMirrorMaker 2Réplica de topics en vivo
Firestore (emu) → DynamoDBScript export → BatchWriteItemOne-shot por colección

🛠️ Paso a Paso (Hands-on)#

Importante

Esta guía asume AWS CLI v2, Terraform ≥ 1.6 y permisos de administrador en una cuenta sandbox.

🧱 Fase 0 — Preparación (Día 0)#

bash
# 1. Configurar credenciales
aws configure --profile sbs-prod

# 2. Crear bucket de estado de Terraform
aws s3 mb s3://sbs-terraform-state --region us-east-1
aws s3api put-bucket-versioning \
  --bucket sbs-terraform-state \
  --versioning-configuration Status=Enabled

# 3. Crear tabla DynamoDB para locking
aws dynamodb create-table \
  --table-name sbs-tf-lock \
  --attribute-definitions AttributeName=LockID,AttributeType=S \
  --key-schema AttributeName=LockID,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

🌐 Fase 1 — Red (VPC, Subnets, NAT)#

hcl
# infra/vpc.tf
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.5"

  name = "sbs-vpc"
  cidr = "10.20.0.0/16"

  azs             = ["us-east-1a", "us-east-1b", "us-east-1c"]
  public_subnets  = ["10.20.1.0/24", "10.20.2.0/24", "10.20.3.0/24"]
  private_subnets = ["10.20.10.0/24", "10.20.20.0/24", "10.20.30.0/24"]

  enable_nat_gateway     = true
  single_nat_gateway     = false   # Multi-AZ NAT
  enable_dns_hostnames   = true
  enable_flow_log        = true
}

📦 Fase 2 — Registro de Imágenes (ECR)#

bash
# Crear un repo por servicio
for svc in n8n case01-emisor case01-receptor case02-emisor ...; do
  aws ecr create-repository --repository-name sbs/$svc \
    --image-scanning-configuration scanOnPush=true \
    --encryption-configuration encryptionType=KMS
done

# Login + build + push
aws ecr get-login-password | docker login --username AWS \
  --password-stdin <account>.dkr.ecr.us-east-1.amazonaws.com

docker build -t sbs/case01-emisor cases/case01/emisor/
docker tag  sbs/case01-emisor <account>.dkr.ecr.us-east-1.amazonaws.com/sbs/case01-emisor:v4.9.0
docker push <account>.dkr.ecr.us-east-1.amazonaws.com/sbs/case01-emisor:v4.9.0

🗄️ Fase 3 — Bases de Datos#

hcl
resource "aws_rds_cluster" "aurora_pg" {
  cluster_identifier      = "sbs-aurora-pg"
  engine                  = "aurora-postgresql"
  engine_version          = "15.5"
  database_name           = "n8n"
  master_username         = "sbs_admin"
  master_password         = random_password.db.result
  storage_encrypted       = true
  kms_key_id              = aws_kms_key.rds.arn
  backup_retention_period = 14
  deletion_protection     = true
  vpc_security_group_ids  = [aws_security_group.rds.id]
  db_subnet_group_name    = aws_db_subnet_group.private.name
}

🚢 Fase 4 — Cluster ECS Fargate#

hcl
resource "aws_ecs_cluster" "main" {
  name = "sbs-cluster"
  setting {
    name  = "containerInsights"
    value = "enabled"
  }
}

resource "aws_ecs_task_definition" "n8n" {
  family                   = "sbs-n8n"
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = 1024
  memory                   = 2048
  execution_role_arn       = aws_iam_role.ecs_exec.arn
  task_role_arn            = aws_iam_role.n8n_task.arn

  container_definitions = jsonencode([{
    name  = "n8n"
    image = "${aws_ecr_repository.n8n.repository_url}:v4.9.0"
    portMappings = [{ containerPort = 5678 }]
    secrets = [
      { name = "DB_POSTGRESDB_PASSWORD",
        valueFrom = aws_secretsmanager_secret.n8n_db.arn }
    ]
    logConfiguration = {
      logDriver = "awslogs"
      options = {
        "awslogs-group"         = "/ecs/sbs-n8n"
        "awslogs-region"        = "us-east-1"
        "awslogs-stream-prefix" = "n8n"
      }
    }
  }])
}

🔐 Fase 5 — Secretos y Configuración#

bash
aws secretsmanager create-secret \
  --name sbs/n8n/db \
  --secret-string '{"username":"sbs_admin","password":"***"}' \
  --kms-key-id alias/sbs-secrets

aws secretsmanager create-secret \
  --name sbs/social/twitter-api \
  --secret-string '{"bearer_token":"***"}'

🌍 Fase 6 — Exposición Pública#

  1. Crear ACM cert en us-east-1 para *.sbs.example.com.
  2. Aprovisionar ALB con listeners 80→443 redirect y 443 con cert.
  3. Configurar Target Groups por servicio (n8n/5678, dashboards/8081-8100).
  4. Crear Route 53 A-Alias apuntando al ALB.
  5. (Opcional) CloudFront + WAF delante del ALB para los dashboards estáticos.

🔄 Fase 7 — Migración de Datos#

bash
# Ejemplo: PostgreSQL local → Aurora
pg_dump -h localhost -U sbs sbs_db | \
  psql -h sbs-aurora-pg.cluster-xxx.us-east-1.rds.amazonaws.com -U sbs_admin sbs_db

# Validación
python verify_n8n.py --remote https://n8n.sbs.example.com

🚀 Fase 8 — Cutover#

  1. Activar modo lectura en el entorno local.
  2. DMS: pasar a CDC final + apply pending.
  3. Cambiar Route 53 a los endpoints AWS.
  4. Monitorear CloudWatch durante 24h.
  5. Apagar Docker Compose local.

💰 Estimación de Costos#

Advertencia

Cifras orientativas en USD, región us-east-1, basadas en tarifas públicas a la fecha del documento. Usa siempre la AWS Pricing Calculator para tu caso real.

🧪 Escenario A — Lab/Dev (bajo tráfico, single-AZ)#

ComponenteConfiguraciónCosto Mensual
ECS Fargate4 tasks × 0.25 vCPU × 0.5 GB × 730 h~$15
Aurora Serverless v2 (PG)0.5 ACU promedio~$45
ElastiCache Rediscache.t4g.micro × 1~$12
ALB1 unidad + bajo tráfico~$18
NAT Gateway1 unidad~$33
CloudWatch Logs5 GB ingest~$3
ECR10 GB storage~$1
Secrets Manager5 secretos~$2
Route 531 zona~$0.5
Data Transfer10 GB out~$1
TOTAL≈ $130/mes

🏭 Escenario B — Producción Multi-AZ (carga media)#

ComponenteConfiguraciónCosto Mensual
ECS Fargate12 tasks × 0.5 vCPU × 1 GB × 730 h~$90
Aurora PostgreSQLdb.r6g.large × 2 nodos~$420
DocumentDBdb.t4g.medium × 2~$200
ElastiCache Rediscache.r7g.large × 2 (cluster)~$240
ALB+ 50M requests~$45
NAT Gateway3 AZs~$100
CloudFront + WAF200 GB + 50M req~$50
CloudWatch50 GB logs + métricas~$45
Backups + S3100 GB~$10
Data Transfer200 GB out~$18
TOTAL≈ $1,200/mes

Nota

Esta estimación cubre el núcleo (RDS/DocumentDB/ElastiCache). Desplegar la matriz completa de 19 casos añade servicios gestionados adicionales — orientativo: Neptune db.r6g.large (~$400), Timestream (~$50 según ingesta), Amazon MSK 2 brokers kafka.m7g.large (~$300), Keyspaces (serverless, por uso), y CockroachDB/ClickHouse self-managed en EC2/EKS (~$150-300). Presupuesta +$900-1,100/mes extra para la matriz completa en producción.

💸 Optimizaciones Recomendadas#

TécnicaAhorro Estimado
Compute Savings Plans (1 año)hasta 30%
Graviton (ARM) en Fargate/RDShasta 20%
Aurora Serverless v2 en devhasta 70% vs provisionado
S3 Intelligent-Tieringhasta 40% en backups
VPC Endpoints (S3, ECR, SecretsMgr)reduce tráfico NAT
Single NAT Gateway en dev~$66/mes menos

🛡️ Seguridad Cloud-Native#

Importante

La política "🛡️ Security: Hardened" del repositorio se preserva y se amplía en AWS con controles adicionales.

🔒 Controles Mínimos Obligatorios#

CapaControl
IdentidadIAM roles por tarea + MFA + SCP a nivel Organization.
RedSGs least-privilege, NACLs por subnet, VPC Flow Logs a S3.
CifradoKMS CMK propias en RDS, S3, EBS, EFS, Secrets.
SecretosSecrets Manager con rotación de 30 días.
ImágenesECR scan-on-push + Inspector v2.
WAFReglas AWS Managed: Core, Bad Inputs, Anonymous IP.
DDoSShield Standard (gratis) + Shield Advanced en producción crítica.
AuditoríaCloudTrail org-wide + Config + GuardDuty.
ComplianceSecurity Hub con CIS AWS 1.5 + PCI-DSS si aplica.

🚫 Anti-patrones a Evitar#

  • Credenciales hardcoded en task definitions (usar Secrets Manager).
  • Security Group abierto 0.0.0.0/0 excepto ALB:443.
  • RDS público: siempre en subnets privadas.
  • Bucket S3 público sin Block Public Access.
  • Tareas Fargate con --privileged o sin read-only root fs.

📊 Observabilidad en AWS#

diagrama mermaid
graph LR
    APP[ECS Tasks] -->|logs| CWL[CloudWatch Logs]
    APP -->|metrics| CWM[CloudWatch Metrics]
    APP -->|traces| XR[X-Ray]
    APP -->|prom scrape| AMP[Amazon Managed Prometheus]
    AMP --> AMG[Amazon Managed Grafana]
    CWL --> SUB[Subscription Filter]
    SUB --> OS[OpenSearch Service]
    CWM --> ALARM[CloudWatch Alarms]
    ALARM --> SNS[SNS] --> PD[PagerDuty/Email]

🎯 Métricas Clave (SLI)#

SLIUmbralServicio
n8n latency P95< 500 msCloudWatch
Webhook error rate< 0.5%CloudWatch
DB CPU< 70%RDS Performance Insights
DLQ depth= 0SQS Metric
Container OOM= 0Container Insights

🔁 CI/CD en AWS#

🔧 Pipeline GitHub Actions → ECS#

yaml
# .github/workflows/deploy-aws.yml
name: Deploy to AWS
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write   # OIDC
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::<acct>:role/gha-deploy
          aws-region: us-east-1
      - uses: aws-actions/amazon-ecr-login@v2
      - name: Build & Push
        run: |
          docker build -t $ECR/sbs/n8n:${{ github.sha }} .
          docker push   $ECR/sbs/n8n:${{ github.sha }}
      - uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: infra/ecs/n8n.json
          container-name: n8n
          image: $ECR/sbs/n8n:${{ github.sha }}
      - uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          service: sbs-n8n
          cluster: sbs-cluster
          wait-for-service-stability: true

🌀 Alternativa Nativa#

CodePipeline + CodeBuild + CodeDeploy (Blue/Green) elimina dependencia de GitHub Actions y reduce permisos cruzados.


🚨 Riesgos y Mitigaciones#

🔥 Riesgo🛡️ Mitigación
Sobrecosto inicialBudget Alerts + Cost Anomaly Detection + tag policies.
Lock-in con servicios propietariosMantener compatibilidad PostgreSQL/Redis estándar; contenedores portables.
Latencia n8n por cold-start de FargateMantener desiredCount ≥ 1 y usar minimumHealthyPercent=100.
Pérdida de datos en migraciónDMS con CDC + dump previo en S3 + ventana de read-only.
Fugas de secretosRotación automática + IAM secretsmanager:GetSecretValue por tarea.
DDoSShield + WAF + CloudFront.
Deriva de IaCterraform plan en CI + drift detection con AWS Config.

✅ Checklist Final de Cutover#

  • VPC, subnets y NAT desplegados en 3 AZs.
  • ECR poblado con todas las imágenes versionadas.
  • RDS Aurora Multi-AZ con backups automáticos verificados.
  • Secretos en Secrets Manager con rotación activa.
  • ECS services con auto-scaling y health checks.
  • ALB + ACM + Route 53 funcionando.
  • WAF y GuardDuty activos.
  • CloudWatch dashboards y alarmas críticas configuradas.
  • Pipeline CI/CD con OIDC desplegando exitosamente.
  • Runbook de Disaster Recovery probado (RTO < 1h, RPO < 15min).
  • Smoke tests verify_n8n.py y verify_all_cases.py en verde contra entorno cloud.
  • Apagado controlado del entorno localhost.

📚 Referencias#

RecursoURL
AWS Well-Architected Frameworkhttps://aws.amazon.com/architecture/well-architected/
AWS Pricing Calculatorhttps://calculator.aws
ECS Best Practices Guidehttps://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/
Terraform AWS Moduleshttps://registry.terraform.io/namespaces/terraform-aws-modules
AWS Prescriptive Guidance — Migrationshttps://aws.amazon.com/prescriptive-guidance/
n8n on AWS — Referencehttps://docs.n8n.io/hosting/installation/server-setups/aws/

🔗 Documentos Relacionados#

TipoDocumento
🏗️ Arquitectura localdocs/ARCHITECTURE.md
🛡️ SeguridadSECURITY.md | docs/RUNTIME_SECURITY.md
🎓 Instalación localdocs/INSTALL.md
🛣️ RoadmapROADMAP.md

Coded with ❤️ by Vladimir Acuña — Cloud Edition