---
name: cloud-aws
description: Mejores prácticas de AWS. EC2, S3, RDS, Lambda, ECS/EKS, CloudFront, IAM, VPC, SQS/SNS, DynamoDB. Well-Architected Framework, optimización de costos, patrones serverless vs containers.
version: "1.0.0"
herramientasPermitidas: [Read, Grep]
evolvable: true  # default para skill estandar
exclusiones:
  - "No cargar para despliegues en Azure o GCP — para Azure cargar `azure-cloud`, para GCP cargar `gcp-cloud`."
  - "No cargar para configurar servicios AWS de machine learning (SageMaker, Bedrock, Rekognition) sin relación con arquitectura de aplicación — para ML en AWS usar la documentación del servicio directamente."
  - "No cargar para auditoría de costos detallada o reservas de instancias Reserved/Savings Plans — para optimización de costos avanzada usar AWS Cost Explorer y Trusted Advisor directamente."
  - "No cargar para configuración de AWS Organizations, Control Tower o multi-account strategy — para governance multi-cuenta consultar la documentación de AWS Organizations directamente."
---
# AWS — Mejores Prácticas de Nube

## Cuándo NO cargar

- La tarea es desplegar en Azure: cargar `azure-cloud`.
- La tarea es desplegar en GCP: cargar `gcp-cloud`.
- La tarea es configurar SageMaker, Bedrock o servicios de ML de AWS: usar la documentación del servicio directamente.
- La tarea es auditoría de costos avanzada o multi-account strategy: usar AWS Cost Explorer y Organizations directamente.


Este skill cubre decisiones de arquitectura, seguridad y costos en AWS para sistemas
de producción. Los ejemplos usan Python (boto3) y configuración de infraestructura.

---

## 1. Well-Architected Framework — 6 Pilares

| Pilar | Pregunta clave |
|-------|---------------|
| **Excelencia operativa** | Puedes operar y mejorar continuamente? |
| **Seguridad** | Proteges la información y los sistemas? |
| **Confiabilidad** | Recuperas de fallos automáticamente? |
| **Eficiencia de desempeño** | Usas recursos eficientemente? |
| **Optimización de costos** | Pagas solo por lo que usas? |
| **Sostenibilidad** | Minimizas impacto ambiental? |

---

## 2. IAM — Mínimo Privilegio Siempre

```json
// BIEN: solo lo que necesita la función
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "LeerBucketNomina",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::empresa-nomina-prod",
        "arn:aws:s3:::empresa-nomina-prod/*"
      ]
    }
  ]
}
```

NUNCA usar `"Action": "*"` ni `"Resource": "*"` en políticas IAM de producción.

```python
# NUNCA hardcodear credenciales AWS
# BIEN: usar IAM roles (en EC2/ECS/Lambda automático)
cliente_s3 = boto3.client('s3', region_name='us-east-1')
```

---

## 3. VPC — Red Segura

```
VPC: 10.0.0.0/16
├── Public Subnets (2 AZs)          — ALB, NAT Gateway, Bastion
│   ├── 10.0.1.0/24 (us-east-1a)
│   └── 10.0.2.0/24 (us-east-1b)
├── Private App Subnets (2 AZs)     — ECS Tasks, EC2 App servers
│   ├── 10.0.11.0/24 (us-east-1a)
│   └── 10.0.12.0/24 (us-east-1b)
└── Private Data Subnets (2 AZs)    — RDS, ElastiCache
    ├── 10.0.21.0/24 (us-east-1a)
    └── 10.0.22.0/24 (us-east-1b)

Reglas:
- Internet → ALB (80, 443) OK
- ALB → App Servers (8000) OK
- App Servers → RDS (5432) OK
- RDS → Internet NUNCA
```

---

## Servicios Detallados

Para implementaciones completas de S3 (cifrado, lifecycle), RDS (configuración producción),
Lambda (handlers, partial batch), ECS Fargate (task definitions), SQS/SNS (mensajería),
CloudFront (CDN) y optimización de costos, ver
[recursos/servicios-aws-referencia.md](recursos/servicios-aws-referencia.md).

---

## Checklist de Arquitectura AWS

### Seguridad
- [ ] Sin credenciales hardcodeadas — IAM roles siempre
- [ ] MFA activado en cuenta root y usuarios IAM admin
- [ ] CloudTrail habilitado en todas las regiones
- [ ] Config Rules para compliance
- [ ] GuardDuty habilitado para detección de amenazas

### Confiabilidad
- [ ] Multi-AZ en RDS, ElastiCache, ALB
- [ ] Auto Scaling Groups con mínimo 2 instancias
- [ ] Health checks en ALB y ECS
- [ ] Backups automatizados con retención mínima 7 días
- [ ] Runbooks documentados para fallos comunes

### Costos
- [ ] Budget alerts configuradas ($X USD/mes)
- [ ] Lifecycle policies en S3
- [ ] Snapshots de RDS/EBS con retención limitada
- [ ] Recursos de dev/staging apagados fuera de horario laboral
- [ ] Reserved instances para carga base predecible

### Desempeño
- [ ] CloudFront para assets estáticos
- [ ] ElastiCache para queries frecuentes
- [ ] Connection pooling en aplicación
- [ ] Read replicas para reportes pesados

---

## Gotchas / Errores comunes no obvios

**Una política IAM con `"Effect": "Allow"` en todas las acciones S3 sobre el bucket pero sin el ARN del bucket con `/*` al final no permite operar sobre los objetos del bucket — solo sobre el bucket mismo**: la política `"Resource": "arn:aws:s3:::mi-bucket"` permite `ListBucket` pero no `GetObject`, `PutObject` ni `DeleteObject` porque estas operaciones actúan sobre objetos (`mi-bucket/*`), no sobre el bucket. Causa: en IAM, el recurso bucket y el recurso objeto son ARNs distintos; `s3:GetObject` requiere `arn:aws:s3:::mi-bucket/*`. Fix: para permisos completos sobre un bucket, siempre incluir ambos ARNs en el array `Resource`: `["arn:aws:s3:::mi-bucket", "arn:aws:s3:::mi-bucket/*"]`. `ListBucket` va al ARN del bucket; `GetObject`/`PutObject`/`DeleteObject` van al ARN de objetos.

**ECS Fargate con `awsvpc` network mode asigna una IP privada al task que cambia en cada deployment, y el Security Group que permite tráfico del task al RDS por IP no funciona después de un redeploy porque la IP cambió**: el Security Group del RDS tiene una inbound rule de `10.0.11.45/32` (la IP anterior del task) pero el task nuevo tiene `10.0.11.67/32`. La aplicación no puede conectarse a RDS hasta que alguien actualiza la regla manualmente. Causa: con `awsvpc`, cada task tiene su propia Elastic Network Interface con IP dinámica; confiar en IPs fijas para Security Groups es un anti-patrón. Fix: en el Security Group del RDS, usar el Security Group del ECS task como source en lugar de una IP: `aws ec2 authorize-security-group-ingress --group-id sg-rds --protocol tcp --port 5432 --source-group sg-ecs-tasks`. Los Security Groups como source se actualizan automáticamente cuando cambian las IPs.

**`boto3.client('s3').upload_file()` en Lambda con un archivo de más de 5GB falla con `EntityTooLarge` porque S3 requiere multipart upload para objetos mayores a 5GB pero `upload_file()` usa multipart automático solo para objetos mayores al `multipart_threshold` del `TransferConfig` (por defecto 8MB)**: la Lambda que procesa exportaciones grandes funciona para archivos de 500MB pero falla esporádicamente para archivos de 7GB. Causa: `upload_file()` usa multipart cuando el archivo supera `multipart_threshold`, pero hay un límite absoluto de S3 de 5GB para single-part PUT. Para archivos entre 8MB y 5GB, el comportamiento es correcto; para mayores de 5GB, `upload_file()` intenta single-part y S3 rechaza. Fix: siempre usar `config=TransferConfig(multipart_threshold=1024*25, multipart_chunksize=1024*25)` (25MB) para uploads desde Lambda con archivos de tamaño variable. El multipart threshold bajo garantiza multipart independientemente del tamaño.

**CloudWatch Logs Insights cobra por el volumen de datos escaneado en cada query, y las queries sin filtro de tiempo ejecutadas por el equipo en modo debug durante un incidente pueden generar costos de $50-200 USD en una sola sesión**: una query `fields @message | filter @message like 'ERROR'` sin `| limit 100` sobre un log group de 50GB de los últimos 90 días escanea los 50GB y puede costar $12.50 (a $0.005/GB escaneado en us-east-1). Varios ingenieros ejecutando queries similares durante un incidente de 2 horas puede acumular $100+. Causa: CloudWatch Insights cobra por GB escaneado, no por número de queries ni por resultado. Fix: siempre incluir filtro de tiempo en las queries de Insights: `filter @timestamp > datefloor(@timestamp, 1h)` o seleccionar el rango de tiempo en la UI antes de ejecutar. Para debugging frecuente, exportar logs a S3 + Athena que cobra $5/TB escaneado (40x más barato que Insights).
