NAT Gateway vs NAT Instance en AWS: ¿Cuál usar para tus instancias privadas?

Tienes instancias en subredes privadas que necesitan descargar actualizaciones del sistema operativo, paquetes de dependencias o conectarse a APIs externas — pero sin exponer esas instancias directamente a internet. La decisión entre NAT Gateway y NAT Instance parece simple al principio, hasta que te encuentras depurando un problema de conectividad a las 2 AM y descubres que elegiste la opción equivocada para tu caso de uso.

TL;DR: NAT Gateway vs NAT Instance

Criterio NAT Gateway NAT Instance
Gestión operativa Completamente gestionado por AWS Tú gestionas el EC2, parches, HA
Alta disponibilidad Redundancia dentro de la AZ incluida Requiere configuración manual (Auto Scaling, scripts)
Escalabilidad Escala automáticamente hasta límites documentados Limitada por el tipo de instancia EC2
Costo base Cargo por hora + por GB procesado Solo costo de instancia EC2 (más barato en escenarios de bajo tráfico)
Security Groups No aplica — no se asocian SGs al NAT Gateway Sí, puedes asociar Security Groups
Port forwarding / uso como bastion No soportado Soportado
Recomendación general ✅ Cargas productivas ⚠️ Casos muy específicos o entornos de bajo costo

Cómo funciona la traducción de direcciones de red (NAT) en AWS

Antes de elegir entre las dos opciones, es útil entender qué problema resuelven ambas. Las instancias en subredes privadas no tienen rutas directas hacia internet — no tienen IP pública y la tabla de rutas de su subred no apunta a un Internet Gateway. El NAT actúa como intermediario: recibe el paquete saliente de la instancia privada, reemplaza la IP de origen con su propia IP pública, reenvía el paquete a internet, y cuando llega la respuesta, invierte el proceso y entrega el paquete a la instancia original.

La diferencia fundamental entre NAT Gateway y NAT Instance no es el mecanismo de traducción — ambos hacen NAT — sino quién opera el componente que realiza esa traducción y qué capacidades adicionales ofrece cada uno.

graph LR PrivInst["Instancia Privada
sin IP pública"] -->|tráfico saliente| RouteTable["Tabla de Rutas
subred privada"] RouteTable -->|0.0.0.0/0| NAT["NAT Gateway / Instance
subred pública + EIP"] NAT -->|IP origen reemplazada| IGW["Internet Gateway"] IGW -->|paquete entregado| Internet["Internet"] Internet -->|respuesta| IGW IGW --> NAT NAT -->|IP destino restaurada| PrivInst
  1. Instancia privada genera tráfico saliente (ej. yum update).
  2. La tabla de rutas de la subred privada dirige el tráfico 0.0.0.0/0 hacia el NAT (Gateway o Instance) en la subred pública.
  3. El NAT reemplaza la IP de origen privada con su Elastic IP y reenvía el paquete al Internet Gateway.
  4. El Internet Gateway entrega el paquete a internet. La respuesta regresa por el mismo camino en orden inverso.
  5. Con NAT Gateway: AWS gestiona la disponibilidad y el escalado internamente. Con NAT Instance: el EC2 debe tener source/destination check deshabilitado para aceptar y reenviar tráfico que no le pertenece.

NAT Gateway: el camino gestionado

NAT Gateway es un servicio regional gestionado por AWS. Lo despliegas en una subred pública, le asignas una Elastic IP, y actualizas la tabla de rutas de tus subredes privadas para que apunten a él. AWS se encarga del resto: disponibilidad dentro de la zona de disponibilidad, escalado de ancho de banda, y mantenimiento del software subyacente.

Un detalle que sorprende a muchos: NAT Gateway es zonal, no regional. Si despliegas un solo NAT Gateway en us-east-1a y tus instancias privadas están en us-east-1b, el tráfico cruza zonas de disponibilidad — lo que introduce latencia adicional y cargos por transferencia de datos entre AZs. El patrón correcto para producción es un NAT Gateway por AZ donde tengas instancias privadas.

Piensa en NAT Gateway como el servicio de mensajería gestionado de tu edificio: tú depositas el paquete, ellos se encargan de entregarlo y traerte la respuesta. No tienes que contratar ni gestionar al mensajero.

Desplegar NAT Gateway con AWS CLI

El proceso requiere primero una Elastic IP, luego crear el gateway en la subred pública, y finalmente actualizar la tabla de rutas de las subredes privadas.

# Paso 1: Asignar una Elastic IP
aws ec2 allocate-address \
  --domain vpc \
  --region us-east-1

# La respuesta incluye AllocationId, ej: eipalloc-0a1b2c3d4e5f67890

# Paso 2: Crear el NAT Gateway en la subred pública
aws ec2 create-nat-gateway \
  --subnet-id subnet-0a1b2c3d4e5f67890 \
  --allocation-id eipalloc-0a1b2c3d4e5f67890 \
  --region us-east-1

# Esperar a que el estado sea 'available'
aws ec2 describe-nat-gateways \
  --nat-gateway-ids nat-0a1b2c3d4e5f67890 \
  --region us-east-1 \
  --query 'NatGateways[0].State'

# Paso 3: Agregar ruta en la tabla de rutas de la subred privada
aws ec2 create-route \
  --route-table-id rtb-0a1b2c3d4e5f67890 \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id nat-0a1b2c3d4e5f67890 \
  --region us-east-1

Política IAM mínima para gestionar NAT Gateway

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "NATGatewayManagement",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNatGateway",
                "ec2:DeleteNatGateway",
                "ec2:DescribeNatGateways",
                "ec2:AllocateAddress",
                "ec2:ReleaseAddress",
                "ec2:DescribeAddresses",
                "ec2:CreateRoute",
                "ec2:DeleteRoute",
                "ec2:DescribeRouteTables"
            ],
            "Resource": "*"
        }
    ]
}

Las acciones Describe* requieren "Resource": "*" — no admiten restricción por ARN específico según la Service Authorization Reference de AWS.

NAT Instance: control total, responsabilidad total

Una NAT Instance es simplemente un EC2 en una subred pública configurado para reenviar tráfico IP. AWS publicaba AMIs preconfiguradas para este propósito (amzn-ami-vpc-nat), pero esas AMIs han llegado al fin de su soporte. Hoy, si optas por NAT Instance, debes configurar el reenvío IP manualmente en una AMI estándar de Amazon Linux.

El requisito más crítico y frecuentemente olvidado: deshabilitar el chequeo de origen/destino en la interfaz de red del EC2. Por defecto, AWS descarta cualquier paquete cuya IP de origen o destino no coincida con la instancia. Para que una NAT Instance funcione, debe aceptar y reenviar paquetes de otras instancias — lo que requiere desactivar esa verificación.

# Deshabilitar source/destination check en la instancia NAT
aws ec2 modify-instance-attribute \
  --instance-id i-0a1b2c3d4e5f67890 \
  --no-source-dest-check \
  --region us-east-1

# Verificar que quedó deshabilitado
aws ec2 describe-instance-attribute \
  --instance-id i-0a1b2c3d4e5f67890 \
  --attribute sourceDestCheck \
  --region us-east-1

Además, en el sistema operativo de la instancia (Amazon Linux 2) debes habilitar el reenvío IP a nivel de kernel y configurar iptables para el enmascaramiento NAT:

🔽 Configuración de iptables en Amazon Linux 2 (click para expandir)
# Habilitar IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf

# Configurar NAT con iptables (reemplaza eth0 con tu interfaz de red)
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -j ACCEPT
sudo iptables -A FORWARD -o eth0 -j ACCEPT

# Persistir reglas de iptables
sudo service iptables save

Actualizar la tabla de rutas para apuntar a la NAT Instance

# La ruta apunta al Instance ID, no a un gateway ID
aws ec2 create-route \
  --route-table-id rtb-0a1b2c3d4e5f67890 \
  --destination-cidr-block 0.0.0.0/0 \
  --instance-id i-0a1b2c3d4e5f67890 \
  --region us-east-1
graph TD EIP["Elastic IP"] --> NATGW["NAT Gateway
gestionado por AWS"] EIP --> NATI["NAT Instance EC2
gestionado por ti"] NATGW -->|sin SG aplicable| PubSubnetA["Subred Pública"] NATI -->|SG + iptables + src/dst check off| PubSubnetB["Subred Pública"] PubSubnetA --> IGW["Internet Gateway"] PubSubnetB --> IGW PrivSubnet["Subred Privada"] -->|ruta 0.0.0.0/0| NATGW PrivSubnet -->|ruta 0.0.0.0/0| NATI
  1. NAT Gateway path: AWS gestiona disponibilidad, escalado y mantenimiento. Sin Security Groups aplicables al gateway.
  2. NAT Instance path: Tú gestionas el EC2, iptables, source/dest check, parches de seguridad, y alta disponibilidad.
  3. Ambas opciones requieren una Elastic IP y residir en una subred pública con ruta al Internet Gateway.
  4. La tabla de rutas de la subred privada es el punto de decisión: apunta a nat-xxxxxxxx (gateway) o a i-xxxxxxxx (instancia).

El escenario donde la NAT Instance sigue teniendo sentido

Aquí es donde la experiencia de campo difiere de la documentación oficial. En un entorno de desarrollo o laboratorio con tráfico mínimo y presupuesto muy ajustado, una NAT Instance t3.nano o t3.micro puede costar significativamente menos que un NAT Gateway con sus cargos por hora más por GB procesado. Si el tráfico de salida es esporádico y el entorno no es productivo, la ecuación económica puede favorecer a la instancia.

El otro caso legítimo: necesitas hacer port forwarding o usar el mismo host como bastion SSH hacia instancias privadas. NAT Gateway no soporta estas funciones — es estrictamente un componente de NAT de salida. Una NAT Instance puede servir ambos propósitos simultáneamente, aunque mezclar roles en un solo EC2 tiene sus propios riesgos operativos.

Diagnóstico: cuando las instancias privadas no tienen conectividad de salida

Este es el patrón de falla más común, y la causa raíz casi nunca está donde uno busca primero.

Síntoma: curl https://example.com desde una instancia privada cuelga indefinidamente o retorna inmediatamente con error de conexión. Los logs de la aplicación muestran timeouts hacia endpoints externos.

El diagnóstico incorrecto más frecuente: revisar el Security Group de la instancia privada. El SG de la instancia privada controla el tráfico entrante hacia ella — no el tráfico saliente que pasa por el NAT. Puedes pasar 30 minutos revisando reglas de SG sin encontrar nada, porque el problema está en la tabla de rutas o en el estado del NAT.

La causa real: la tabla de rutas de la subred privada no tiene una ruta 0.0.0.0/0 apuntando al NAT, o el NAT Gateway está en estado failed o deleted.

# Paso 1: Verificar la tabla de rutas asociada a la subred privada
aws ec2 describe-route-tables \
  --filters Name=association.subnet-id,Values=subnet-0a1b2c3d4e5f67890 \
  --region us-east-1 \
  --query 'RouteTables[0].Routes'

# Busca una entrada con DestinationCidrBlock: 0.0.0.0/0
# y NatGatewayId o InstanceId apuntando a tu NAT
# Paso 2: Verificar el estado del NAT Gateway
aws ec2 describe-nat-gateways \
  --filter Name=state,Values=available \
  --region us-east-1 \
  --query 'NatGateways[*].{ID:NatGatewayId,State:State,SubnetId:SubnetId}'
# Paso 3: Confirmar que el NAT Gateway está en una subred pública
# (la subred pública debe tener ruta 0.0.0.0/0 hacia un Internet Gateway)
aws ec2 describe-route-tables \
  --filters Name=association.subnet-id,Values=subnet-PUBLIC_SUBNET_ID \
  --region us-east-1 \
  --query 'RouteTables[0].Routes'

Si usas NAT Instance, agrega este paso adicional — es el que más frecuentemente se omite:

# Paso 4 (solo NAT Instance): Verificar source/destination check
aws ec2 describe-instance-attribute \
  --instance-id i-0a1b2c3d4e5f67890 \
  --attribute sourceDestCheck \
  --region us-east-1 \
  --query 'SourceDestCheck'

Si SourceDestCheck.Value es true, el tráfico de otras instancias está siendo descartado silenciosamente por AWS antes de llegar al proceso de iptables. No hay error visible en la instancia NAT — simplemente los paquetes desaparecen.

Ese comportamiento silencioso es exactamente por qué NAT Instance tiene una curva de depuración más pronunciada que NAT Gateway.

Verificar métricas de NAT Gateway en CloudWatch

NAT Gateway publica métricas en CloudWatch automáticamente. Las más útiles para diagnosticar problemas de conectividad o saturación:

# Verificar bytes procesados en los últimos 60 minutos
aws cloudwatch get-metric-statistics \
  --namespace AWS/NATGateway \
  --metric-name BytesOutToDestination \
  --dimensions Name=NatGatewayId,Value=nat-0a1b2c3d4e5f67890 \
  --start-time $(date -u -d '60 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Sum \
  --region us-east-1
# Verificar conexiones activas
aws cloudwatch get-metric-statistics \
  --namespace AWS/NATGateway \
  --metric-name ActiveConnectionCount \
  --dimensions Name=NatGatewayId,Value=nat-0a1b2c3d4e5f67890 \
  --start-time $(date -u -d '60 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Maximum \
  --region us-east-1

Guía de decisión: NAT Gateway vs NAT Instance

graph TD Start(["¿Necesito salida a internet
desde subred privada?"]) Start --> Prod{"¿Entorno productivo?"} Prod -->|Sí| NATGW["✅ NAT Gateway
por AZ"] Prod -->|No| PortFwd{"¿Necesito port forwarding
o bastion SSH?"} PortFwd -->|Sí| NATI["NAT Instance EC2"] PortFwd -->|No| Budget{"¿Presupuesto muy limitado
y tráfico mínimo?"} Budget -->|Sí| NATI Budget -->|No| NATGW
  1. Si el entorno es productivo, la respuesta es casi siempre NAT Gateway — la carga operativa de mantener una NAT Instance en producción raramente justifica el ahorro de costo.
  2. Si necesitas port forwarding o funcionalidad de bastion, NAT Instance es la única opción nativa sin agregar servicios adicionales.
  3. Para entornos de desarrollo con presupuesto muy limitado y tráfico mínimo, NAT Instance puede ser económicamente razonable si el equipo tiene la capacidad de operarla.
  4. Si el tráfico de salida es predecible y alto en volumen, evalúa el costo de NAT Gateway (cargo por GB) versus el costo fijo de una instancia EC2 de mayor tamaño.

Conclusión y próximos pasos con NAT Gateway vs NAT Instance

Para la mayoría de los equipos operando cargas en AWS, NAT Gateway es la elección correcta: elimina una categoría entera de problemas operativos a cambio de un costo predecible. NAT Instance tiene su lugar en escenarios muy específicos — presupuesto extremadamente ajustado en entornos no productivos, o cuando necesitas funcionalidad que NAT Gateway no ofrece por diseño.

Si decides usar NAT Gateway en producción, el siguiente paso es asegurarte de tener uno por zona de disponibilidad donde operes instancias privadas, y configurar alertas en CloudWatch sobre la métrica ErrorPortAllocation para detectar agotamiento de puertos antes de que impacte a tus aplicaciones. Consulta la documentación oficial de NAT Gateway y la documentación de NAT Instance para detalles actualizados sobre límites de servicio y configuración.

Glosario de términos clave

Término Definición
NAT (Network Address Translation) Mecanismo que reemplaza la IP privada de origen con una IP pública al reenviar tráfico hacia internet, permitiendo que instancias sin IP pública accedan a recursos externos.
Elastic IP (EIP) Dirección IPv4 pública estática asignada a tu cuenta AWS. Requerida tanto por NAT Gateway como por NAT Instance para mantener una IP pública consistente.
Source/Destination Check Verificación que AWS realiza en cada interfaz de red EC2 para descartar tráfico cuya IP de origen o destino no corresponde a la instancia. Debe deshabilitarse en NAT Instances.
Tabla de rutas (Route Table) Conjunto de reglas que determina hacia dónde se dirige el tráfico de una subred. El componente de configuración más crítico para que el NAT funcione correctamente.
Internet Gateway (IGW) Componente VPC que permite la comunicación entre recursos de la VPC e internet. El NAT (Gateway o Instance) lo usa como siguiente salto para el tráfico de salida.

Related Posts

Comentarios

Entradas populares de este blog

EC2 sin acceso a Internet en VPC personalizada: Internet Gateway y Route Table

Actualizar Contenido en CloudFront: Cómo Crear una Invalidación para Limpiar el Caché del Edge

Aumentar el Timeout de Lambda: Configuración, Límites y Diagnóstico en Producción