FinOps y arquitectura cloud

"En cloud no pagás por lo que provisionás — pagás por lo que dejás corriendo. La diferencia puede ser miles de dólares al mes."

Qué vas a aprender en este capítulo

Construir cosas en cloud es fácil; construirlas bien (rápidas, seguras, baratas, resilientes) requiere disciplina. Este capítulo cubre: gestión de costos (FinOps), el Well-Architected Framework, y cómo diseñar para resiliencia y portabilidad.


5.1 FinOps — gestión de costos cloud

💡 Intuición

Es trivial generar facturas de $50,000/mes en AWS por error: dejar instancias gigantes corriendo, no eliminar volúmenes huérfanos, mover terabytes entre regiones, o no usar reserved instances.

FinOps es la práctica de gestionar y optimizar costos cloud de forma colaborativa entre finanzas, ingeniería y producto.

📐 Fundamento

Principios FinOps:

  1. Visibilidad — todos pueden ver cuánto cuesta su servicio.
  2. Responsabilidad — los equipos son dueños de sus costos.
  3. Optimización continua — no es un proyecto único, es un proceso.
  4. Decisiones basadas en datos — antes de optimizar, medir.

Estrategias de optimización:

1. Right-sizing — usar el tamaño correcto:

Antes: instancia t3.xlarge (4 vCPU, 16 GB) usando solo 30% CPU y 4 GB RAM.
Después: t3.large (2 vCPU, 8 GB) → mitad de costo, mismo rendimiento.

Herramientas: AWS Compute Optimizer, GCP Recommender.

2. Modelos de pricing:

Modelo Descuento vs On-demand Cuándo usar
On-demand 0% Tráfico impredecible, dev/staging
Spot Instances Hasta 90% Batch, workloads tolerantes a interrupciones
Reserved Instances (1-3 años) 30-72% Workloads predecibles 24/7
Savings Plans Similar a RI, más flexible Compromiso de gasto $/h

3. Auto-scaling agresivo:

# En lugar de: instance_type = "t3.xlarge", count = 10 (siempre)
# Hacer: 
resource "aws_autoscaling_group" "api" {
  min_size     = 2    # noche
  max_size     = 20   # picos del mediodía
  
  # Escalar basado en CPU
  target_tracking_scaling_policy {
    target_value = 60.0  # mantener CPU promedio en 60%
  }
}

4. Apagar lo que no se usa:

  • Dev/staging fuera de horario laboral (apagar 12 horas/día = 50% menos costo).
  • Snapshots viejos (cuestan storage).
  • Volúmenes EBS no asociados a instancias.
  • Load balancers sin tráfico.
  • Elastic IPs no usadas.
# Lambda que apaga instancias dev a las 7 PM, las prende a las 7 AM
import boto3
ec2 = boto3.client('ec2')

def apagar_dev(event, context):
    instancias = ec2.describe_instances(
        Filters=[{'Name': 'tag:Environment', 'Values': ['dev', 'staging']}]
    )
    ids = [i['InstanceId'] for r in instancias['Reservations'] for i in r['Instances']]
    if ids:
        ec2.stop_instances(InstanceIds=ids)

5. Optimizar storage:

  • S3 Storage Classes: Standard → Infrequent Access (datos > 30 días) → Glacier (archivo > 90 días).
  • Lifecycle rules automáticas:
resource "aws_s3_bucket_lifecycle_configuration" "facturas" {
  bucket = "la-esquina-facturas"
  
  rule {
    id     = "archivar-viejas"
    status = "Enabled"
    
    transition {
      days          = 30
      storage_class = "STANDARD_IA"
    }
    transition {
      days          = 90
      storage_class = "GLACIER"
    }
    expiration {
      days = 2555  # eliminar después de 7 años (compliance)
    }
  }
}

6. Cuidado con el data transfer:

  • Tráfico SALIENDO de AWS a internet cuesta $0.09/GB.
  • Entre regiones también cuesta.
  • Mantener tráfico dentro de la misma región y AZ cuando sea posible.
  • Cloudfront cachea → reduce data transfer del origen.

Visibilidad:

  • AWS Cost Explorer — visualizar gastos por servicio, tag, etc.
  • AWS Budgets — alertas cuando se acerca al límite.
  • Tagging — cada recurso debe tener tags Environment, Team, Project. Permite agrupar costos.
# Política: todos los recursos deben tener tags
default_tags = {
  tags = {
    Environment = var.env
    Team        = "platform"
    Project     = "la-esquina"
    CostCenter  = "engineering"
    ManagedBy   = "terraform"
  }
}

5.2 AWS Well-Architected Framework

📐 Fundamento

AWS publica el Well-Architected Framework: 6 pilares para evaluar cualquier arquitectura cloud.

1. Operational Excellence:

  • IaC (Terraform, CloudFormation).
  • Procesos automatizados (CI/CD).
  • Monitoreo y observabilidad.
  • Postmortems sin culpa, mejora continua.

2. Security:

  • Identity (IAM, mínimo privilegio).
  • Detective controls (CloudTrail, GuardDuty).
  • Infrastructure protection (VPC, Security Groups, WAF).
  • Data protection (cifrado at-rest y in-transit).
  • Incident response.

3. Reliability:

  • Diseño multi-AZ (alta disponibilidad).
  • Multi-region para disaster recovery.
  • Monitoreo de health, auto-recovery.
  • Testing de recuperación.
  • Backups y restore probados.

4. Performance Efficiency:

  • Elegir el tipo de instancia correcto.
  • Usar caché (ElastiCache, CloudFront).
  • Bases de datos optimizadas.
  • Monitoreo de performance.
  • Load testing.

5. Cost Optimization:

  • (Toda la sección anterior).

6. Sustainability (agregado en 2021):

  • Elegir regiones con energía renovable.
  • Right-sizing reduce desperdicio energético.
  • Auto-shutdown de recursos no usados.
  • Architectures more efficient = menos huella de carbono.

Well-Architected Tool: AWS provee una herramienta gratuita que te hace preguntas y te da un reporte con áreas de mejora.


5.3 Alta disponibilidad y Disaster Recovery

Conceptos clave:

  • RTO (Recovery Time Objective): ¿en cuánto tiempo debe recuperarse el sistema después de un desastre?
  • RPO (Recovery Point Objective): ¿cuánta pérdida de datos es aceptable?
Estrategia RTO RPO Costo
Backup & Restore Horas-días Horas Bajo
Pilot Light Decenas de minutos Minutos Medio
Warm Standby Minutos Segundos Alto
Multi-site Active/Active ~0 ~0 Muy alto

Multi-AZ vs Multi-Region:

  • Multi-AZ: réplicas en múltiples AZs de la misma región. Sobrevive falla de datacenter. Latencia entre réplicas: < 5ms.
  • Multi-Region: réplicas en regiones distintas. Sobrevive falla de región completa. Más complejo, más caro.

Ejemplo: RDS Multi-AZ:

resource "aws_db_instance" "postgres" {
  multi_az = true   # AWS mantiene una réplica síncrona en otra AZ automáticamente
  # Failover automático en < 60 segundos si la primaria falla
}

Backup strategy 3-2-1:

  • 3 copias de los datos.
  • 2 medios diferentes.
  • 1 copia off-site (otra región o cuenta).
# AWS Backup: políticas centralizadas
resource "aws_backup_plan" "diario" {
  rule {
    rule_name         = "daily-backup"
    schedule          = "cron(0 5 ? * * *)"  # 5 AM UTC diario
    target_vault_name = aws_backup_vault.main.name
    
    lifecycle {
      delete_after = 30  # retener 30 días
    }
    
    copy_action {
      destination_vault_arn = aws_backup_vault.dr.arn  # copia a otra región
      lifecycle {
        delete_after = 365
      }
    }
  }
}

5.4 Multi-cloud y vendor lock-in

💡 Intuición

Vendor lock-in: depender tanto de un proveedor que migrar es prohibitivamente caro.

Si todo tu sistema usa Lambda, DynamoDB, Cognito, SQS... migrar a GCP requiere reescribir todo. Si usás K8s, PostgreSQL y código standard, podés moverte.

Pero: servicios managed propietarios suelen ser mucho mejores que sus alternativas portables. Hay un trade-off real entre portabilidad y productividad.

📐 Fundamento

Estrategias respecto al lock-in:

1. Single-cloud, abrazar el lock-in:

  • Usar todos los servicios managed (Lambda, DynamoDB, SNS, etc.).
  • Velocidad de desarrollo máxima.
  • Lock-in alto pero costo de migración aceptado.
  • Más común en startups y empresas medianas.

2. Multi-cloud por servicio:

  • Workloads en cloud A, BI en cloud B, ML en cloud C.
  • Aprovecha las fortalezas de cada uno.
  • Más complejo (gestión de múltiples cuentas, equipos especializados).

3. Multi-cloud verdadero (mismo workload en múltiples clouds):

  • Usar solo herramientas portables: Kubernetes, PostgreSQL, Redis.
  • Resiliencia ante caída de un cloud completo.
  • Mayor complejidad operacional.
  • Solo justificable para regulaciones o servicios críticos enormes.

Cuando tiene sentido multi-cloud:

  • Compliance que requiere redundancia (banking, healthcare).
  • Ya tenés presencia en múltiples clouds por adquisiciones.
  • Negociación de precios contra proveedores.

Cuando NO tiene sentido:

  • "Por si acaso" — agrega complejidad sin beneficio claro.
  • Para startups — la velocidad es más importante.

Herramientas multi-cloud:

  • Kubernetes — corre en cualquier cloud.
  • Terraform — mismo lenguaje para AWS/GCP/Azure.
  • Crossplane — Kubernetes-native multi-cloud control plane.
  • CockroachDB / Yugabyte — DBs distribuidas multi-cloud.

Patrón anti lock-in: hexagonal architecture:

# Interfaz portable
class FileStorage(Protocol):
    def upload(self, key: str, data: bytes) -> str: ...
    def download(self, key: str) -> bytes: ...

# Implementación AWS
class S3Storage:
    def upload(self, key: str, data: bytes) -> str:
        s3.put_object(Bucket=bucket, Key=key, Body=data)
        return f"s3://{bucket}/{key}"

# Implementación GCP
class GCSStorage:
    def upload(self, key: str, data: bytes) -> str:
        storage_client.bucket(bucket).blob(key).upload_from_string(data)
        return f"gs://{bucket}/{key}"

# El código de negocio solo conoce la interfaz
def crear_factura(storage: FileStorage, datos: dict):
    pdf = generar_pdf(datos)
    return storage.upload(f"facturas/{datos['id']}.pdf", pdf)

Migrar de AWS a GCP: cambiar la implementación, no el código de negocio.

🛠️ En la práctica

La Esquina Cloud — checklist final de Well-Architected

Operational Excellence:

  • [x] Toda la infraestructura en Terraform.
  • [x] CI/CD con GitHub Actions.
  • [x] Logs centralizados en CloudWatch.
  • [x] Runbooks documentados.
  • [x] Postmortems de cada incidente.

Security:

  • [x] MFA obligatoria para humanos.
  • [x] IAM roles, sin credenciales hardcoded.
  • [x] WAF para OWASP Top 10.
  • [x] Cifrado at-rest y in-transit.
  • [x] Secrets en AWS Secrets Manager.
  • [x] Network segmentation con VPC + Security Groups.

Reliability:

  • [x] Multi-AZ deployment.
  • [x] Auto-scaling configurado.
  • [x] Health checks en load balancers.
  • [x] RDS Multi-AZ con backups diarios.
  • [x] DR plan probado trimestralmente (RTO 1h, RPO 15min).

Performance:

  • [x] CloudFront CDN.
  • [x] ElastiCache para queries frecuentes.
  • [x] Read replicas en RDS.
  • [x] Monitoreo P95/P99 de latencia.

Cost:

  • [x] Reserved Instances para cargas constantes.
  • [x] Spot para workers no críticos.
  • [x] Lifecycle policies en S3.
  • [x] Tags por equipo/proyecto.
  • [x] Budget alerts en >80% del límite.
  • [x] Dev/staging apagado fuera de horario.

Sustainability:

  • [x] Region en zona con energía renovable (us-west-2).
  • [x] Right-sizing trimestral.

5.5 Cierre del libro

Este libro recorrió el panorama completo de la computación en la nube:

  1. Fundamentos cloud — modelos de servicio, regiones, IAM, servicios fundamentales.
  2. Infrastructure as Code — Terraform para infraestructura versionada y reproducible.
  3. Contenedores y Kubernetes — empaquetado y orquestación moderna.
  4. Serverless — funciones sin servidores, escala infinita por evento.
  5. FinOps y arquitectura — costos, Well-Architected, multi-cloud.

La nube cambió la economía y el tiempo de construcción del software. Ahora una persona puede desplegar una app a producción global desde su laptop. La habilidad de hacer esto bien — rápido, seguro, barato y resiliente — es de las más valoradas en la industria.


5.6 Ejercicios

✏️ Ejercicio 5.1 — Optimización de costos

Un cliente tiene esta factura mensual de AWS:

  • 10 instancias t3.xlarge corriendo 24/7: $1,500
  • RDS db.r5.2xlarge Single-AZ: $700
  • 5 TB en S3 Standard (logs viejos que nunca se acceden): $115
  • Data transfer: $400 (entre regiones)
  • 3 ALBs (load balancers), uno sin tráfico: $66

Total: $2,781/mes.

Identificá oportunidades de optimización con ahorro estimado.


5.7 Para profundizar

5.X Mini-proyecto integrador

🏗️ Proyecto final — Deploy real en Free Tier

Alcance: poné una app web en producción en AWS / GCP / Cloudflare usando Free Tier, con todo lo del libro: IaC, contenedores, observabilidad y monitoreo de costos.

Entregables:

  1. App — un servicio simple (un acortador de URLs, un health-check público, una API que devuelva el clima de El Salvador).
  2. IaCterraform apply levanta la infraestructura entera (cap. 2). El repo no debe tener nada manual.
  3. Contenedor — Dockerfile multi-stage, imagen < 100 MB, en un registry privado (cap. 3).
  4. Compute — desplegado en Kubernetes (kind/EKS) o Lambda/Cloud Run (serverless, cap. 4). Justificá la elección.
  5. Observabilidad — métricas con CloudWatch o Grafana Cloud Free Tier; un dashboard con CPU, latencia y errores.
  6. CostoAWS Cost Explorer o equivalente: capturar el costo del proyecto durante 1 semana. Documentá cuánto se gastaría escalando a 1000 req/s (cap. 5).

Criterio de éxito: podés destruir todo (terraform destroy) y rearmarlo en 10 minutos. La cuenta a fin de mes es < $5.

Tiempo estimado: 2-3 semanas.


Definiciones nuevas: FinOps, right-sizing, Reserved Instance, Spot Instance, Savings Plan, S3 Storage Class, Lifecycle policy, Well-Architected Framework, RTO, RPO, multi-AZ, multi-region, vendor lock-in, hexagonal architecture, Crossplane, AWS Cost Explorer.