La NAT Gateway de los $5,000
Cómo tres NAT Gateways sin VPC Endpoints triplicaron el costo de AWS en producción — y cómo lo resolvimos.
Impacto: Costo mensual $650 → $1,900 USD (+192%). ~$15,000 USD/año proyectados.
Línea de tiempo del incidente
- Día 1Despliegue de 15 nuevas Lambdas en subnets privadas▼
- Semana 3Factura AWS: $1,900 USD (+192% vs mes anterior)▼
- Día 22Abrimos Cost Explorer — NAT Gateway como top 3 de costos▼
- Día 22Diagnóstico: Lambdas llamando a S3 y DynamoDB por internet▼
- Día 23Crear VPC Endpoints para S3 y DynamoDB (Gateway Endpoints, sin costo adicional)▼
- Día 24Consolidar 3 NAT Gateways → 1 (con HA vía routing)▼
- Mes siguienteFactura AWS: $620 USD▼
Todo empezó con una factura de AWS.
Era el 1 de julio, revisando Cost Explorer como rutina mensual, cuando vi el número: $1,900 USD. El mes anterior había sido $650. Sin ningún lanzamiento de producto nuevo. Sin incremento de usuarios. Sin cambios de infraestructura "grandes".
Solo 15 funciones Lambda nuevas.
El contexto
A principios de junio migramos un conjunto de workers de background a AWS Lambda. El requisito de seguridad era claro: las funciones debían estar dentro de la VPC para acceder a recursos en subnets privadas.
El despliegue fue limpio. Tests pasaron. Staging funcionó bien. Pusheamos a producción.
Lo que no notamos fue una consecuencia silenciosa de esa decisión.
El diagnóstico
Al abrir Cost Explorer con el filtro de servicio, el culpable fue inmediato:
NAT Gateway: $890.47
El mes anterior había sido $28.
Filtramos por recurso y encontramos los tres NAT Gateways de la cuenta — uno por availability zone, como buena práctica de alta disponibilidad. Cada uno mostraba un incremento masivo en "DataProcessed".
La pregunta era: ¿qué tráfico estaba pasando por ahí?
El problema de raíz
AWS tiene dos tipos de acceso a sus servicios desde una VPC:
-
Por internet (a través de NAT Gateway): El tráfico sale a la internet pública, llega al endpoint público de S3/DynamoDB, y regresa. Se cobra por cada GB transferido.
-
Por VPC Endpoints: El tráfico se queda dentro de la red de AWS. Los Gateway Endpoints para S3 y DynamoDB son gratuitos.
Cada Lambda procesaba en promedio 2MB de datos de S3 por invocación. Con 15 funciones y ~500 invocaciones/día cada una:
15 funciones × 500 invocaciones × 2 MB = 15,000 MB/día = ~450 GB/mes
450 GB × $0.045/GB (NAT processing) = $20.25/día = ~$607/mes solo en datos
+ costo base de 3 NAT Gateways: $96/mes
= ~$703/mes de incrementoLos números cuadraban.
La solución
Paso 1: VPC Endpoints para S3 y DynamoDB
Los Gateway Endpoints son la corrección obvia. No tienen costo adicional y el tráfico nunca sale de la red de AWS:
# Gateway Endpoint para S3
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0abc123 \
--service-name com.amazonaws.us-east-1.s3 \
--route-table-ids rtb-0def456 rtb-0ghi789
# Gateway Endpoint para DynamoDB
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0abc123 \
--service-name com.amazonaws.us-east-1.dynamodb \
--route-table-ids rtb-0def456 rtb-0ghi789Terraform equivalente:
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.region}.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_route_table.private.id]
}
resource "aws_vpc_endpoint" "dynamodb" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.region}.dynamodb"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_route_table.private.id]
}No se requiere cambio en el código de las Lambdas. El SDK de AWS automáticamente usa el endpoint de la VPC cuando está disponible.
Paso 2: Consolidar NAT Gateways
Con los VPC Endpoints en lugar, el tráfico NAT restante era mínimo (acceso a APIs externas ocasional). Consolidamos de 3 a 1 NAT Gateway:
# Una sola NAT Gateway con IP elástica
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public_a.id # AZ primaria
}Documentamos el procedimiento de failover manual en caso de falla del AZ. Para el volumen de tráfico actual, el tradeoff valió la pena.
Resultado
| Concepto | Antes | Después | Ahorro |
|---|---|---|---|
| NAT Gateway (datos) | $862/mes | $8/mes | $854/mes |
| NAT Gateway (base, 3x) | $96/mes | $32/mes | $64/mes |
| Total | $1,900/mes | $620/mes | $1,280/mes |
Ahorro anual proyectado: $15,360 USD.
Lo que cambiaría
El problema no fue técnico — fue de proceso. Teníamos una arquitectura funcional en staging que no capturó el costo real porque:
- Staging no tiene el mismo volumen de datos que producción
- No revisamos el impacto de costos en el PR de infraestructura
- No teníamos alertas de costo configuradas con umbral relativo (% de cambio)
La tercera es la que más duele: AWS Budgets con alertas del 20% de cambio mes a mes habría disparado una alerta en la primera semana, no la tercera.
Este incidente llevó a crear nuestro Checklist de VPC Endpoints — una lista de todos los servicios de AWS que tienen endpoints disponibles y cuándo usarlos.