Cerrábamos el módulo 2 con una constatación incómoda: MercadoFresco tiene ya en eu-west-1 un grupo
de Auto Scaling, discos con copias automáticas, el catálogo en S3, la base de datos en RDS y dos
funciones Lambda… y todo eso vive en la VPC por defecto. Es decir, en una red que AWS creó sola
el día que se abrió la cuenta, con todas las subredes públicas, con la base de datos compartiendo
espacio de red con la tienda y con la instancia mercadofresco-tienda-01 accesible desde internet
sin que nadie lo haya decidido conscientemente.
Una VPC (Virtual Private Cloud) es tu propio centro de datos virtual dentro de AWS: un espacio de red aislado, con el rango de direcciones IP que tú elijas, dividido en subredes que tú colocas en las zonas de disponibilidad que quieras, con las rutas que tú definas. Es la capa sobre la que se apoya absolutamente todo lo demás. Un balanceador se coloca en subredes. Una base de datos vive en un grupo de subredes. Un grupo de seguridad pertenece a una VPC. Si la red está mal diseñada, todo lo que se construya encima arrastra el problema.
En esta lección Marta diseña y construye desde cero la red definitiva de MercadoFresco:
vpc-mercadofresco, con seis subredes repartidas en dos zonas de disponibilidad, tres niveles de
aislamiento, salida controlada a internet y una base de datos que deja de ser alcanzable desde fuera.
Contenido
- Qué es una VPC y por qué la VPC por defecto no sirve para producción
- Direccionamiento: CIDR, máscaras y cómo elegir el rango
- Las cinco IP que AWS reserva en cada subred
- Por qué no solaparse con la red de la oficina
- El diseño de red de MercadoFresco: seis subredes en dos AZ
- Internet Gateway y qué hace realmente que una subred sea «pública»
- Tablas de rutas: principal, personalizadas, asociaciones y la ruta local
- NAT Gateway y NAT instance: para qué sirven y cuánto cuestan de verdad
- Direcciones IP privadas, públicas, elásticas e interfaces de red
- Endpoints de VPC: de puerta de enlace y de interfaz
- DNS dentro de la VPC
- Conectar con la oficina: peering, Transit Gateway, VPN y Direct Connect
- Construcción completa de
vpc-mercadofrescopor CLI - Mover la base de datos
mercadofresco-pedidosa las subredes privadas de datos - VPC Flow Logs: el registro de lo que pasa por la red
- Limpieza y control de coste
Qué es una VPC y por qué la VPC por defecto no sirve para producción
Una VPC es una red virtual aislada lógicamente del resto de clientes de AWS. Vive en una región
(la nuestra, eu-west-1) y se extiende automáticamente por todas sus zonas de disponibilidad. Dentro
de ella creas subredes, y cada subred vive en una sola zona de disponibilidad. Esa es la
regla que gobierna todo el diseño: la VPC es regional, la subred es zonal.
Cuando AWS crea una cuenta nueva, genera en cada región una VPC por defecto con un diseño pensado para que cualquier cosa funcione al primer intento. Ese es exactamente su problema.
| Aspecto | VPC por defecto | VPC diseñada (vpc-mercadofresco) |
|---|---|---|
| Rango | 172.31.0.0/16, idéntico en todas las cuentas |
10.0.0.0/16, elegido por nosotros |
| Subredes | Una por AZ, todas públicas | Seis: pública, privada de aplicación y privada de datos, en dos AZ |
| Ruta a internet | 0.0.0.0/0 → IGW en todas las subredes |
Solo en las públicas |
| IP pública automática | Sí, activada por defecto | No, desactivada salvo en las públicas |
| Aislamiento por capas | Ninguno | Tres niveles con rutas distintas |
| Base de datos | Alcanzable desde internet si el SG falla | Sin ruta a internet en absoluto |
| Solapamiento con la oficina | Impredecible | Controlado y documentado |
| Reproducible en otra cuenta | No | Sí, es infraestructura declarada |
El punto crítico es el penúltimo. En la VPC por defecto, la única cosa que impide que cualquiera en
internet abra una conexión a la base de datos de pedidos es el grupo de seguridad. Un grupo de
seguridad es una regla, y las reglas se editan por error un viernes a las siete de la tarde. En una
subred privada no hay ninguna ruta hacia internet: aunque alguien abriera el puerto 5432 a
0.0.0.0/0, no habría camino de vuelta. Eso no es una regla, es física de la red. A eso se le llama
defensa en profundidad, y es la razón por la que este diseño merece el trabajo.
Direccionamiento: CIDR, máscaras y cómo elegir el rango
CIDR (Classless Inter-Domain Routing) es la notación dirección/máscara con la que se
describe un rango de direcciones IP. En 10.0.0.0/16, el /16 significa que los primeros 16 bits
son fijos (el 10.0.) y los 16 restantes son variables: eso da 2^16 = 65.536 direcciones, desde
10.0.0.0 hasta 10.0.255.255.
La regla mental: cuanto mayor es el número tras la barra, más pequeña es la red. Cada bit que añades divide el rango por dos.
| Máscara | Direcciones totales | IP utilizables en AWS | Uso típico |
|---|---|---|---|
/16 |
65.536 | 65.531 | Máximo permitido para una VPC |
/18 |
16.384 | 16.379 | Subred enorme, rara vez necesaria |
/20 |
4.096 | 4.091 | Subred de aplicación cómoda (nuestra elección) |
/22 |
1.024 | 1.019 | Subred mediana |
/24 |
256 | 251 | Subred pequeña, la más habitual en ejemplos |
/26 |
64 | 59 | Subred de base de datos |
/28 |
16 | 11 | Mínimo permitido para una subred en AWS |
Los rangos privados que puedes usar (definidos en el RFC 1918) son:
10.0.0.0/8— de10.0.0.0a10.255.255.255. Casi 17 millones de direcciones.172.16.0.0/12— de172.16.0.0a172.31.255.255. Aquí vive la VPC por defecto.192.168.0.0/16— de192.168.0.0a192.168.255.255. El clásico de los routers domésticos.
Marta elige 10.0.0.0/16 por tres razones concretas:
- Es el máximo que AWS permite para una VPC (
/16). El CIDR principal de una VPC no se puede reducir ni cambiar una vez creada; solo se pueden añadir bloques secundarios. Empezar pequeño «porque no necesitamos tantas IP» es el error que más migraciones ha costado. - No es
172.31.x.x, así que nunca chocará con la VPC por defecto si algún día hay que hacer peering entre ambas. - No es
192.168.x.x, que es exactamente lo que usa el router de la oficina de MercadoFresco.
Sobre el punto 1, una cifra para calibrar: MercadoFresco tiene hoy 2 instancias de tienda y llega a 4 en el pico de los viernes. Con 4.091 direcciones por subred de aplicación, el margen es de tres órdenes de magnitud. Las direcciones IP privadas no cuestan dinero. Ser generoso aquí es gratis; ser tacaño se paga con una migración de red dentro de dos años.
Las cinco IP que AWS reserva en cada subred
En cualquier subred, AWS se queda con cinco direcciones que no puedes asignar a nada. Tomando
como ejemplo 10.0.0.0/20 (de 10.0.0.0 a 10.0.15.255):
| Dirección | Reservada para |
|---|---|
10.0.0.0 |
Identificador de la red (estándar de redes, no es de AWS) |
10.0.0.1 |
Router de la VPC: la puerta de enlace por defecto de la subred |
10.0.0.2 |
Servidor DNS de la VPC (Route 53 Resolver, «la IP +2») |
10.0.0.3 |
Reservada por AWS para uso futuro |
10.0.15.255 |
Dirección de difusión (broadcast), aunque AWS no soporta broadcast |
Por eso un /28 con 16 direcciones solo da 11 utilizables, y por eso /28 es el mínimo: por
debajo no quedaría prácticamente nada. La dirección .2 merece recordarse: cuando en la lección
03-05 configuremos reglas de reenvío de DNS, esa es la dirección con la que hablarán todas las
instancias.
Por qué no solaparse con la red de la oficina
La oficina de MercadoFresco usa 192.168.10.0/24 para sus equipos y su NAS. Marta lo documenta
antes de crear nada, porque en el momento en que se quiera conectar la oficina con AWS —por VPN,
como veremos al final de la lección— los rangos solapados hacen la conexión imposible.
El motivo es puro enrutamiento. Si el portátil de Luis es 192.168.10.25 y en AWS existiera también
una instancia 192.168.10.25, cuando el portátil quisiera hablar con la instancia miraría su propia
tabla de rutas, vería que 192.168.10.0/24 es «mi red local» y enviaría el paquete al switch de al
lado. Nunca cruzaría el túnel. Y no hay ajuste que lo arregle: habría que renumerar una de las dos
redes enteras.
La regla que sigue Marta y que conviene adoptar: un documento único con el mapa de todos los rangos de la empresa, incluidos los que aún no existen.
| Red | Rango | Estado |
|---|---|---|
| Oficina de Barcelona | 192.168.10.0/24 |
En uso |
| VPC por defecto de AWS | 172.31.0.0/16 |
Existe, a eliminar más adelante |
vpc-mercadofresco (producción, eu-west-1) |
10.0.0.0/16 |
Se crea en esta lección |
| VPC de desarrollo (futura) | 10.1.0.0/16 |
Reservado |
| VPC de una segunda región (futura) | 10.2.0.0/16 |
Reservado |
| VPN de teletrabajo | 10.200.0.0/22 |
Reservado |
El diseño de red de MercadoFresco: seis subredes en dos AZ
El patrón que vamos a construir es el estándar de la industria: tres capas × dos zonas de disponibilidad. Cada capa tiene un nivel de exposición distinto y una tabla de rutas distinta.
| Subred | AZ | CIDR | IP útiles | Capa | Qué vive aquí |
|---|---|---|---|---|---|
snet-mercadofresco-publica-a |
eu-west-1a |
10.0.0.0/20 |
4.091 | Pública | ALB, NAT Gateway |
snet-mercadofresco-publica-b |
eu-west-1b |
10.0.16.0/20 |
4.091 | Pública | ALB, NAT Gateway |
snet-mercadofresco-app-a |
eu-west-1a |
10.0.32.0/20 |
4.091 | Privada de aplicación | Instancias del ASG, Lambda en VPC |
snet-mercadofresco-app-b |
eu-west-1b |
10.0.48.0/20 |
4.091 | Privada de aplicación | Instancias del ASG, Lambda en VPC |
snet-mercadofresco-datos-a |
eu-west-1a |
10.0.64.0/20 |
4.091 | Privada de datos | RDS primaria, EFS |
snet-mercadofresco-datos-b |
eu-west-1b |
10.0.80.0/20 |
4.091 | Privada de datos | RDS en espera, EFS |
Quedan libres los rangos de 10.0.96.0 en adelante: más de la mitad de la VPC sin usar, disponible
para futuras capas (contenedores en el módulo 10, caché en el 06-05) sin tocar nada de lo existente.
Tres decisiones de diseño que conviene entender:
- La capa de aplicación es privada. Las instancias de la tienda no tendrán IP pública. Recibirán el tráfico a través del balanceador (lección 03-03) y saldrán a internet, cuando lo necesiten, por el NAT Gateway.
- La capa de datos no tiene ninguna ruta a internet, ni siquiera por NAT. RDS no necesita descargar nada. Cuanto menos camino haya, menos superficie de ataque.
- Todo está duplicado en dos AZ. Si
eu-west-1acae entera,eu-west-1btiene subred pública (para el balanceador), subred de aplicación (para las instancias) y subred de datos (para la copia en espera de RDS). Esta es la razón práctica del diseño multi-AZ que estudiamos en 01-03.
Internet Gateway y qué hace realmente que una subred sea «pública»
Un Internet Gateway (IGW) es un componente gestionado, redundante y escalado horizontalmente por AWS que se adjunta a una VPC (una sola por VPC) y hace dos cosas:
- Proporciona el destino para el tráfico dirigido a internet.
- Traduce (NAT 1:1) la IP privada de una instancia a su IP pública, en ambos sentidos.
Y aquí está el concepto que más confusión genera en toda la lección:
No existe ninguna casilla llamada «subred pública». Una subred es pública si —y solo si— la tabla de rutas asociada a ella contiene una entrada
0.0.0.0/0que apunta a un Internet Gateway. Eso es todo. El nombre que le pongas es decorativo.
De ahí se derivan dos consecuencias muy prácticas:
- Una instancia con IP pública en una subred sin ruta al IGW no tiene internet. Tiene una IP que no sirve para nada.
- Una instancia sin IP pública en una subred con ruta al IGW tampoco tiene internet: el IGW necesita una IP pública que traducir.
Es decir, para que una instancia hable con internet directamente hacen falta las dos cosas a la vez: ruta al IGW e IP pública (o elástica).
Tablas de rutas: principal, personalizadas, asociaciones y la ruta local
Una tabla de rutas es una lista de reglas «para llegar a este destino, envía por aquí». Cada subred está asociada a exactamente una tabla de rutas; una tabla puede servir a muchas subredes.
Toda VPC nace con una tabla principal (main), que se aplica a cualquier subred que no tengas asociada explícitamente a otra. Y toda tabla contiene una ruta local que no se puede borrar ni modificar:
| Destino | Destino de reenvío | Significado |
|---|---|---|
10.0.0.0/16 |
local |
Todo el tráfico dentro de la VPC se enruta internamente |
Esa ruta local es la que hace que la instancia de la tienda pueda hablar con RDS sin que exista ninguna configuración adicional: dentro de una VPC, todas las subredes se alcanzan entre sí por defecto, estén en la AZ que estén. Lo que decide si esa conversación se permite no es la ruta, son los grupos de seguridad, que es exactamente el tema de la lección 03-02.
Las tres tablas de MercadoFresco quedan así:
| Tabla | Subredes asociadas | Rutas |
|---|---|---|
rt-mercadofresco-publica |
publica-a, publica-b |
10.0.0.0/16 → local0.0.0.0/0 → igw-mercadofresco |
rt-mercadofresco-app-a |
app-a |
10.0.0.0/16 → local0.0.0.0/0 → nat-mercadofresco-a |
rt-mercadofresco-app-b |
app-b |
10.0.0.0/16 → local0.0.0.0/0 → nat-mercadofresco-b |
rt-mercadofresco-datos |
datos-a, datos-b |
10.0.0.0/16 → local(ninguna más) |
Fíjate en que hay dos tablas separadas para la capa de aplicación, una por AZ. Es deliberado: si
app-a y app-b compartieran tabla, ambas saldrían por el mismo NAT Gateway, y si ese NAT cayera
con su AZ, las instancias de la otra zona se quedarían sin salida. Con una tabla por AZ, cada zona
es autosuficiente.
AWS aplica siempre la ruta más específica que coincida (longest prefix match). Si una tabla
tiene 0.0.0.0/0 → NAT y 52.94.0.0/16 → IGW, un paquete a 52.94.10.1 va por el IGW porque /16
es más específico que /0.
NAT Gateway y NAT instance: para qué sirven y cuánto cuestan de verdad
Las instancias de la capa de aplicación no tienen IP pública, pero necesitan salir a internet:
descargar parches de seguridad, instalar paquetes con dnf, llamar a la pasarela de pago. Necesitan
conexiones salientes sin aceptar entrantes. Para eso está el NAT Gateway.
El NAT Gateway se coloca en una subred pública, tiene una IP elástica, y hace de intermediario: recibe el paquete de la instancia privada, lo reenvía a internet con su propia IP pública y devuelve la respuesta. Como la conversación siempre la inicia la instancia, nadie puede iniciar una conexión desde internet hacia dentro.
flowchart LR
EC2["Instancia privada<br/>10.0.32.15<br/>(sin IP pública)"]
RT["Tabla rt-mercadofresco-app-a<br/>0.0.0.0/0 → nat-mercadofresco-a"]
NAT["NAT Gateway<br/>en snet-publica-a<br/>IP elástica 52.x.x.x"]
IGW["Internet Gateway"]
NET["Internet<br/>(repositorio de paquetes)"]
EC2 --> RT --> NAT --> IGW --> NET
NET -. "respuesta" .-> IGW -.-> NAT -.-> EC2
⚠️ Aviso de coste: el NAT Gateway es el recurso que más facturas sorpresa genera
En
eu-west-1un NAT Gateway cuesta aproximadamente 0,048 USD por hora más 0,048 USD por GB procesado. Con dos NAT Gateway (uno por AZ) funcionando todo el mes:
- 2 × 0,048 × 730 h = ≈ 70 USD/mes solo por existir, sin transferir un solo byte.
- Más 0,048 USD por cada GB que pase por ellos, en ambos sentidos.
No está en la capa gratuita. Si estás siguiendo el curso en una cuenta de pruebas con el presupuesto de 10 USD que configuramos en 01-02, la alerta a
[email protected]saltará en menos de una semana. Opciones:
- Una sola NAT Gateway para pruebas (≈ 35 USD/mes): crea solo
nat-mercadofresco-ay haz que las dos tablas de aplicación apunten a ella. Pierdes la tolerancia a fallos de zona, que en un entorno de pruebas no importa.- Ninguna NAT: si solo quieres practicar el direccionamiento, sáltate el NAT y usa Session Manager (visto en 02-01) para llegar a las instancias. Sin NAT no podrán actualizar paquetes, pero la red se estudia igual.
- Bórralo al terminar cada sesión de práctica. Hay comandos de limpieza al final de la lección.
La alternativa histórica es la NAT instance: una EC2 normal con reenvío de IP activado y la comprobación de origen/destino desactivada. Comparación honesta:
| NAT Gateway | NAT instance | |
|---|---|---|
| Gestión | AWS, cero mantenimiento | Tuya: parches, monitorización, reinicios |
| Disponibilidad | Redundante dentro de su AZ | Un único punto de fallo |
| Ancho de banda | Hasta 100 Gbps, escala solo | El de la instancia (0,5-25 Gbps) |
| Coste base | ≈ 35 USD/mes por gateway | Una t4g.nano ≈ 3 USD/mes |
| Coste por GB | 0,048 USD/GB | Solo la transferencia estándar |
| Grupos de seguridad | No aplica | Sí, se le pueden poner |
| Puede usarse de bastión | No | Sí |
| Recomendación | Producción | Laboratorios y cuentas de aprendizaje |
Para MercadoFresco en producción: NAT Gateway, dos, uno por AZ. Para quien siga el curso en su
cuenta personal: una NAT instance t4g.nano o directamente ninguna.
Y una tercera vía, la más elegante, que veremos en el apartado de endpoints: quitar del NAT todo el tráfico que en realidad va a servicios de AWS.
Direcciones IP privadas, públicas, elásticas e interfaces de red
Cuatro conceptos que se confunden constantemente:
| Concepto | Qué es | Persiste al parar la instancia | Coste |
|---|---|---|---|
| IP privada | Dirección dentro del CIDR de la subred (10.0.32.15) |
Sí, es fija mientras exista la ENI | Gratis |
| IP pública | IP enrutable asignada automáticamente al arrancar | No, cambia en cada arranque | Desde 2024, ≈ 0,005 USD/h |
| IP elástica (EIP) | IP pública tuya, que asignas y reasignas a voluntad | Sí | Gratis si está en uso; se cobra si está sin asignar |
| ENI | Interfaz de red virtual: la tarjeta de red de la instancia | Sí, puede desasociarse y moverse | Gratis |
La ENI (Elastic Network Interface) es la pieza que unifica todo. Una ENI pertenece a una subred, tiene una o varias IP privadas, opcionalmente una IP pública o elástica, una dirección MAC y los grupos de seguridad. Cuando dices «esta instancia está en la subred X con el grupo de seguridad Y», lo que en realidad estás describiendo es su ENI.
Esto explica cosas que de otro modo parecen mágicas:
- RDS, un ALB o una Lambda en VPC no son máquinas que veas, pero consumen IP de tus subredes: cada uno crea sus ENI. Un ALB puede crear ocho o más ENI al escalar. Otra razón para no hacer subredes pequeñas.
- Una EIP asociada a una ENI se puede mover a otra instancia en segundos, lo que permite sustituir una máquina sin cambiar el DNS.
Trampa clásica de facturación: una IP elástica asignada y en uso es gratis; una IP elástica reservada y sin asociar a nada cuesta ≈ 0,005 USD/hora (≈ 3,6 USD/mes). Las EIP huérfanas que quedan tras borrar una instancia son el gasto fantasma más común en cuentas de aprendizaje.
Endpoints de VPC: de puerta de enlace y de interfaz
Cuando la instancia mercadofresco-tienda-01, ya en una subred privada, pide una foto de
mercadofresco-catalogo-fotos, ¿por dónde va ese tráfico? Por defecto: instancia → NAT Gateway →
Internet Gateway → red pública de AWS → S3. Sale a internet para volver a entrar en AWS. Y por
cada GB se paga el NAT.
Los endpoints de VPC eliminan ese rodeo: llevan el tráfico a los servicios de AWS por la red interna de AWS, sin pasar por internet. Hay dos tipos y funcionan de forma completamente distinta.
| De puerta de enlace (Gateway) | De interfaz (Interface / PrivateLink) | |
|---|---|---|
| Servicios soportados | Solo S3 y DynamoDB | Casi todos: SSM, Secrets Manager, KMS, ECR, CloudWatch, SQS, SNS… |
| Cómo funciona | Una ruta en la tabla de rutas | Una ENI con IP privada en tu subred |
| Qué resuelve el DNS | El nombre público de S3, redirigido por ruta | Un nombre privado (o el público, con DNS privado activado) |
| Grupos de seguridad | No aplica | Sí, se le asigna uno |
| Coste | Gratis | ≈ 0,011 USD/h por AZ + 0,01 USD/GB |
| Alcance | Solo dentro de la VPC | Puede alcanzarse desde otras VPC y desde la oficina por VPN |
Para MercadoFresco, el endpoint de puerta de enlace hacia S3 es una decisión sin discusión: es gratis y ahorra dinero desde el primer byte.
flowchart TB
subgraph VPC["vpc-mercadofresco"]
EC2["Instancia de tienda<br/>snet-mercadofresco-app-a"]
VPCE(["Endpoint de puerta de enlace<br/>vpce-mercadofresco-s3<br/>(entrada en la tabla de rutas)"])
NAT["NAT Gateway<br/>0,048 USD/GB"]
end
S3[("mercadofresco-catalogo-fotos")]
INET["Internet"]
EC2 -- "pl-6da54004 → vpce (gratis)" --> VPCE --> S3
EC2 -. "0.0.0.0/0 → NAT (de pago)" .-> NAT --> INET
Lo interesante del mecanismo: al crear el endpoint, AWS añade a tus tablas de rutas una entrada cuyo
destino es una prefix list gestionada (pl-6da54004 para S3 en eu-west-1), que contiene todos
los rangos IP públicos de S3 en la región. Como esa ruta es más específica que 0.0.0.0/0, el
tráfico a S3 se desvía al endpoint y el resto sigue yendo por el NAT. No hay que cambiar ni una
línea de código de la aplicación.
Además, un endpoint de puerta de enlace admite una política de endpoint que restringe qué se puede hacer a través de él:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SoloBucketsDeMercadoFresco",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::mercadofresco-catalogo-fotos",
"arn:aws:s3:::mercadofresco-catalogo-fotos/*",
"arn:aws:s3:::mercadofresco-copias-basedatos",
"arn:aws:s3:::mercadofresco-copias-basedatos/*"
]
}
]
}Esta política dice: por este endpoint solo se puede leer y escribir en los dos buckets de
MercadoFresco. Si una instancia comprometida intentara subir datos a un bucket de un atacante, el
endpoint lo rechazaría. Principal: "*" aquí no significa «cualquiera de internet»: solo puede
entrar por este endpoint quien esté dentro de la VPC.
Los endpoints de interfaz que MercadoFresco acabará necesitando (ssm, ssmmessages, ec2messages
para Session Manager, y secretsmanager para lo que veremos en 04-03) sí cuestan dinero, pero
permiten algo valioso: usar Session Manager en instancias sin NAT y sin internet en absoluto.
DNS dentro de la VPC
Toda VPC lleva incorporado un resolvedor DNS, el Route 53 Resolver, accesible en la dirección
.2 de la VPC (10.0.0.2 en nuestro caso) y también en la dirección local 169.254.169.253. Es el
que traduce mercadofresco-pedidos.abc123.eu-west-1.rds.amazonaws.com a la IP privada correcta.
Dos atributos de la VPC gobiernan su comportamiento y confunden a todo el mundo:
| Atributo | Qué hace | Valor recomendado |
|---|---|---|
enableDnsSupport |
Activa el resolvedor de la VPC en la IP .2. Si está desactivado, nada resuelve nombres, ni siquiera los de RDS o S3 |
true siempre |
enableDnsHostnames |
Hace que las instancias con IP pública reciban además un nombre DNS público. Es imprescindible para que funcione el DNS privado de los endpoints de interfaz y para RDS | true |
Una VPC creada con create-vpc tiene enableDnsSupport=true pero enableDnsHostnames=false.
Es el primer ajuste que hay que corregir tras crearla, y la causa número uno de que un endpoint de
interfaz «no funcione».
Conectar con la oficina: peering, Transit Gateway, VPN y Direct Connect
MercadoFresco todavía tiene el ERP en un servidor de la oficina. Antes o después habrá que conectar las dos redes. Las cuatro opciones, que no desarrollamos aquí porque exceden el alcance del curso, pero que conviene saber nombrar:
| Opción | Conecta | Idea clave | Cuándo |
|---|---|---|---|
| VPC Peering | Dos VPC | Enlace directo 1 a 1, no transitivo | Pocas VPC, topología simple |
| Transit Gateway | Muchas VPC + VPN + Direct Connect | Router central en estrella | A partir de 3-4 VPC o varias cuentas |
| Site-to-Site VPN | Oficina ↔ AWS | Túnel IPsec cifrado sobre internet | Rápido, barato, ancho de banda variable |
| Direct Connect | Oficina ↔ AWS | Fibra dedicada, sin pasar por internet | Latencia estable y mucho volumen; caro y con meses de plazo |
Para MercadoFresco, la elección natural cuando llegue el momento es Site-to-Site VPN hacia
vpc-mercadofresco: se monta en una tarde y funciona precisamente porque 10.0.0.0/16 y
192.168.10.0/24 no se solapan, tal y como decidimos al principio de la lección.
Construcción completa de vpc-mercadofresco por CLI
Vamos a construirlo todo con AWS CLI v2 y el perfil mercadofresco-dev que configuramos en 01-05.
Cada bloque guarda el identificador que devuelve para usarlo en el siguiente.
Paso 1: la VPC y sus atributos de DNS
# Crear la VPC con el CIDR elegido y las etiquetas obligatorias del proyecto
VPC_ID=$(aws ec2 create-vpc \
--profile mercadofresco-dev --region eu-west-1 \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[
{Key=Name,Value=vpc-mercadofresco},
{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},
{Key=Componente,Value=tienda},
{Key=Propietario,Value=marta},
{Key=CentroCoste,Value=operaciones}]' \
--query 'Vpc.VpcId' --output text)
echo "VPC creada: $VPC_ID"
# Activar los nombres DNS (viene desactivado por defecto: este es EL ajuste que se olvida)
aws ec2 modify-vpc-attribute --profile mercadofresco-dev --region eu-west-1 \
--vpc-id "$VPC_ID" --enable-dns-hostnames
# Verificar ambos atributos
aws ec2 describe-vpc-attribute --profile mercadofresco-dev --region eu-west-1 \
--vpc-id "$VPC_ID" --attribute enableDnsHostnames \
--query 'EnableDnsHostnames.Value'--query 'Vpc.VpcId' --output text extrae solo el identificador, sin comillas ni JSON, para poder
guardarlo en una variable de shell. Es el patrón de JMESPath que vimos en 01-05 y que usaremos en
todo el módulo.
Paso 2: las seis subredes
# Función auxiliar: crea una subred y devuelve su ID
crear_subred() {
local nombre=$1 cidr=$2 az=$3 componente=$4
aws ec2 create-subnet \
--profile mercadofresco-dev --region eu-west-1 \
--vpc-id "$VPC_ID" --cidr-block "$cidr" --availability-zone "$az" \
--tag-specifications "ResourceType=subnet,Tags=[
{Key=Name,Value=$nombre},
{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},
{Key=Componente,Value=$componente},
{Key=Propietario,Value=marta},
{Key=CentroCoste,Value=operaciones}]" \
--query 'Subnet.SubnetId' --output text
}
PUB_A=$(crear_subred snet-mercadofresco-publica-a 10.0.0.0/20 eu-west-1a tienda)
PUB_B=$(crear_subred snet-mercadofresco-publica-b 10.0.16.0/20 eu-west-1b tienda)
APP_A=$(crear_subred snet-mercadofresco-app-a 10.0.32.0/20 eu-west-1a tienda)
APP_B=$(crear_subred snet-mercadofresco-app-b 10.0.48.0/20 eu-west-1b tienda)
DAT_A=$(crear_subred snet-mercadofresco-datos-a 10.0.64.0/20 eu-west-1a pedidos)
DAT_B=$(crear_subred snet-mercadofresco-datos-b 10.0.80.0/20 eu-west-1b pedidos)
# Solo las públicas asignan IP pública automáticamente a lo que se lance en ellas
for S in "$PUB_A" "$PUB_B"; do
aws ec2 modify-subnet-attribute --profile mercadofresco-dev --region eu-west-1 \
--subnet-id "$S" --map-public-ip-on-launch
done--map-public-ip-on-launch es una comodidad, no una decisión de seguridad: recuerda que sin la ruta
al IGW esa IP pública no serviría de nada.
Paso 3: Internet Gateway y tabla de rutas pública
IGW_ID=$(aws ec2 create-internet-gateway \
--profile mercadofresco-dev --region eu-west-1 \
--tag-specifications 'ResourceType=internet-gateway,Tags=[
{Key=Name,Value=igw-mercadofresco},{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},{Key=Componente,Value=tienda},
{Key=Propietario,Value=marta},{Key=CentroCoste,Value=operaciones}]' \
--query 'InternetGateway.InternetGatewayId' --output text)
aws ec2 attach-internet-gateway --profile mercadofresco-dev --region eu-west-1 \
--internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID"
RT_PUB=$(aws ec2 create-route-table --profile mercadofresco-dev --region eu-west-1 \
--vpc-id "$VPC_ID" \
--tag-specifications 'ResourceType=route-table,Tags=[
{Key=Name,Value=rt-mercadofresco-publica},{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},{Key=Componente,Value=tienda},
{Key=Propietario,Value=marta},{Key=CentroCoste,Value=operaciones}]' \
--query 'RouteTable.RouteTableId' --output text)
# ESTA es la línea que convierte a las subredes en "públicas"
aws ec2 create-route --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_PUB" --destination-cidr-block 0.0.0.0/0 --gateway-id "$IGW_ID"
aws ec2 associate-route-table --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_PUB" --subnet-id "$PUB_A"
aws ec2 associate-route-table --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_PUB" --subnet-id "$PUB_B"Paso 4: NAT Gateways (⚠️ empieza el gasto)
# Una IP elástica por NAT Gateway
EIP_A=$(aws ec2 allocate-address --profile mercadofresco-dev --region eu-west-1 \
--domain vpc --query 'AllocationId' --output text)
NAT_A=$(aws ec2 create-nat-gateway --profile mercadofresco-dev --region eu-west-1 \
--subnet-id "$PUB_A" --allocation-id "$EIP_A" \
--tag-specifications 'ResourceType=natgateway,Tags=[
{Key=Name,Value=nat-mercadofresco-a},{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},{Key=Componente,Value=tienda},
{Key=Propietario,Value=marta},{Key=CentroCoste,Value=operaciones}]' \
--query 'NatGateway.NatGatewayId' --output text)
# Un NAT Gateway tarda 1-2 minutos en estar disponible; esperamos activamente
aws ec2 wait nat-gateway-available --profile mercadofresco-dev --region eu-west-1 \
--nat-gateway-ids "$NAT_A"
echo "NAT $NAT_A disponible"Nota importante: el NAT Gateway se crea en la subred pública ($PUB_A), no en la privada.
Es el error de colocación más frecuente: si lo pones en la subred privada, el NAT no tiene salida y
nada funciona, sin ningún mensaje que lo explique.
Repite el bloque con $PUB_B para nat-mercadofresco-b, o sáltatelo si estás en modo económico y
haz que las dos tablas de aplicación apunten a $NAT_A.
Paso 5: tablas de rutas privadas
crear_rt_privada() {
local nombre=$1
aws ec2 create-route-table --profile mercadofresco-dev --region eu-west-1 \
--vpc-id "$VPC_ID" \
--tag-specifications "ResourceType=route-table,Tags=[
{Key=Name,Value=$nombre},{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},{Key=Componente,Value=tienda},
{Key=Propietario,Value=marta},{Key=CentroCoste,Value=operaciones}]" \
--query 'RouteTable.RouteTableId' --output text
}
RT_APP_A=$(crear_rt_privada rt-mercadofresco-app-a)
RT_APP_B=$(crear_rt_privada rt-mercadofresco-app-b)
RT_DATOS=$(crear_rt_privada rt-mercadofresco-datos)
# Salida a internet por el NAT de su propia AZ
aws ec2 create-route --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_APP_A" --destination-cidr-block 0.0.0.0/0 --nat-gateway-id "$NAT_A"
aws ec2 create-route --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_APP_B" --destination-cidr-block 0.0.0.0/0 --nat-gateway-id "$NAT_B"
aws ec2 associate-route-table --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_APP_A" --subnet-id "$APP_A"
aws ec2 associate-route-table --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_APP_B" --subnet-id "$APP_B"
# La capa de datos NO recibe ninguna ruta 0.0.0.0/0: es intencionado
aws ec2 associate-route-table --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_DATOS" --subnet-id "$DAT_A"
aws ec2 associate-route-table --profile mercadofresco-dev --region eu-west-1 \
--route-table-id "$RT_DATOS" --subnet-id "$DAT_B"Paso 6: endpoint de puerta de enlace hacia S3
VPCE_S3=$(aws ec2 create-vpc-endpoint --profile mercadofresco-dev --region eu-west-1 \
--query 'VpcEndpoint.VpcEndpointId' --output text \
--vpc-id "$VPC_ID" \
--service-name com.amazonaws.eu-west-1.s3 \
--vpc-endpoint-type Gateway \
--route-table-ids "$RT_APP_A" "$RT_APP_B" "$RT_DATOS" \
--tag-specifications 'ResourceType=vpc-endpoint,Tags=[
{Key=Name,Value=vpce-mercadofresco-s3},{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},{Key=Componente,Value=catalogo},
{Key=Propietario,Value=marta},{Key=CentroCoste,Value=operaciones}]')Al indicar --route-table-ids, AWS inserta automáticamente la ruta hacia la prefix list de S3 en
esas tres tablas. Compruébalo:
aws ec2 describe-route-tables --profile mercadofresco-dev --region eu-west-1 \
--route-table-ids "$RT_APP_A" \
--query 'RouteTables[0].Routes[].{Destino:DestinationCidrBlock,PrefixList:DestinationPrefixListId,Gateway:GatewayId,NAT:NatGatewayId}' \
--output tableLa red final
flowchart TB
USER["Usuarios de<br/>mercadofresco.example"]
IGW(["igw-mercadofresco"])
subgraph VPC["vpc-mercadofresco — 10.0.0.0/16 — eu-west-1"]
direction TB
subgraph AZA["Zona eu-west-1a"]
PA["snet-publica-a<br/>10.0.0.0/20<br/>NAT nat-mercadofresco-a"]
AA["snet-app-a<br/>10.0.32.0/20<br/>EC2 del ASG"]
DA["snet-datos-a<br/>10.0.64.0/20<br/>RDS mercadofresco-pedidos"]
end
subgraph AZB["Zona eu-west-1b"]
PB["snet-publica-b<br/>10.0.16.0/20<br/>NAT nat-mercadofresco-b"]
AB["snet-app-b<br/>10.0.48.0/20<br/>EC2 del ASG"]
DB["snet-datos-b<br/>10.0.80.0/20<br/>RDS en espera Multi-AZ"]
end
VPCE(["vpce-mercadofresco-s3"])
end
S3[("mercadofresco-catalogo-fotos")]
USER --> IGW
IGW --> PA
IGW --> PB
AA -->|salida| PA
AB -->|salida| PB
AA --> DA
AB --> DB
DA -. "Multi-AZ" .- DB
AA --> VPCE --> S3
Mover la base de datos mercadofresco-pedidos a las subredes privadas de datos
La instancia RDS creada en 02-04 vive todavía en el grupo de subredes sng-mercadofresco, que
apuntaba a la VPC por defecto. Hay que crear un grupo nuevo dentro de vpc-mercadofresco:
aws rds create-db-subnet-group --profile mercadofresco-dev --region eu-west-1 \
--db-subnet-group-name sng-mercadofresco-datos \
--db-subnet-group-description "Subredes privadas de datos de MercadoFresco" \
--subnet-ids "$DAT_A" "$DAT_B" \
--tags Key=Proyecto,Value=mercadofresco Key=Entorno,Value=produccion \
Key=Componente,Value=pedidos Key=Propietario,Value=marta \
Key=CentroCoste,Value=operacionesAdvertencia operativa: una instancia RDS no se puede mover de VPC cambiando su grupo de subredes. El camino real es: hacer un snapshot, restaurarlo indicando el nuevo grupo de subredes, y repuntar la aplicación. En MercadoFresco, Marta lo hace de madrugada un martes:
aws rds create-db-snapshot --profile mercadofresco-dev --region eu-west-1 \\ --db-instance-identifier mercadofresco-pedidos \\ --db-snapshot-identifier mercadofresco-pedidos-premigracion aws rds wait db-snapshot-completed --profile mercadofresco-dev --region eu-west-1 \\ --db-snapshot-identifier mercadofresco-pedidos-premigracion aws rds restore-db-instance-from-db-snapshot --profile mercadofresco-dev --region eu-west-1 \\ --db-instance-identifier mercadofresco-pedidos-v2 \\ --db-snapshot-identifier mercadofresco-pedidos-premigracion \\ --db-subnet-group-name sng-mercadofresco-datos \\ --multi-az --no-publicly-accessibleEl
--no-publicly-accessiblees tan importante como el grupo de subredes: aunque la subred no tenga ruta a internet, el atributoPubliclyAccessibleentrueharía que RDS intentara resolver a una IP pública y rompería la conexión desde dentro.
VPC Flow Logs: el registro de lo que pasa por la red
Los VPC Flow Logs capturan metadatos de cada flujo de tráfico IP: origen, destino, puertos,
protocolo, bytes, paquetes y —lo más valioso— si el flujo fue ACCEPT o REJECT. No capturan el
contenido, solo las cabeceras.
Se pueden activar a tres niveles: VPC entera, subred o interfaz de red. Y se pueden enviar a CloudWatch Logs (consulta interactiva, más caro) o a S3 (barato, para análisis masivo).
aws ec2 create-flow-logs --profile mercadofresco-dev --region eu-west-1 \
--resource-type VPC --resource-ids "$VPC_ID" \
--traffic-type ALL \
--log-destination-type s3 \
--log-destination arn:aws:s3:::mercadofresco-registros-web/flow-logs/ \
--max-aggregation-interval 60 \
--tag-specifications 'ResourceType=vpc-flow-log,Tags=[
{Key=Name,Value=flowlogs-mercadofresco},{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},{Key=Componente,Value=tienda},
{Key=Propietario,Value=marta},{Key=CentroCoste,Value=operaciones}]'Un registro tiene este aspecto:
2 111122223333 eni-0a1b2c3d 10.0.32.15 52.94.5.20 44321 443 6 12 3800 1738500000 1738500060 ACCEPT OK
Leído por partes: versión, cuenta, ENI, IP origen, IP destino, puerto origen, puerto destino,
protocolo (6 = TCP), paquetes, bytes, inicio, fin, acción y estado. Ese ACCEPT/REJECT final
es la herramienta de diagnóstico que usaremos en la lección 03-02 para saber si un problema de
conectividad lo causa un grupo de seguridad o una NACL. El análisis con CloudWatch Logs Insights y
las alarmas asociadas se estudian en 05-01; aquí basta con tenerlos encendidos.
Coste a tener en cuenta: los Flow Logs no tienen coste de servicio propio, pero sí se paga el
almacenamiento y la ingesta en S3 o en CloudWatch Logs. En una VPC con tráfico intenso, ALL
puede generar varios GB al día; empezar con --traffic-type REJECT es una forma barata de tener lo
importante.
Limpieza y control de coste
Si estás practicando en una cuenta propia, esto es lo que hay que borrar y en este orden, porque AWS bloquea el borrado de un recurso del que dependan otros:
# 1. Lo que más cuesta, primero
aws ec2 delete-nat-gateway --profile mercadofresco-dev --region eu-west-1 --nat-gateway-id "$NAT_A"
aws ec2 wait nat-gateway-deleted --profile mercadofresco-dev --region eu-west-1 --nat-gateway-ids "$NAT_A"
# 2. Liberar la IP elástica (si no, sigue costando ~3,6 USD/mes)
aws ec2 release-address --profile mercadofresco-dev --region eu-west-1 --allocation-id "$EIP_A"
# 3. Endpoints, subredes, tablas de rutas, IGW y VPC
aws ec2 delete-vpc-endpoints --profile mercadofresco-dev --region eu-west-1 --vpc-endpoint-ids "$VPCE_S3"
for S in "$PUB_A" "$PUB_B" "$APP_A" "$APP_B" "$DAT_A" "$DAT_B"; do
aws ec2 delete-subnet --profile mercadofresco-dev --region eu-west-1 --subnet-id "$S"
done
aws ec2 detach-internet-gateway --profile mercadofresco-dev --region eu-west-1 \
--internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID"
aws ec2 delete-internet-gateway --profile mercadofresco-dev --region eu-west-1 --internet-gateway-id "$IGW_ID"
aws ec2 delete-vpc --profile mercadofresco-dev --region eu-west-1 --vpc-id "$VPC_ID"Verificación final de que no queda nada cobrando:
# IP elásticas huérfanas en toda la región
aws ec2 describe-addresses --profile mercadofresco-dev --region eu-west-1 \
--query 'Addresses[?AssociationId==null].[PublicIp,AllocationId]' --output table
# NAT Gateways vivos
aws ec2 describe-nat-gateways --profile mercadofresco-dev --region eu-west-1 \
--filter Name=state,Values=available \
--query 'NatGateways[].[NatGatewayId,SubnetId]' --output tableErrores Comunes y Consejos
Elegir un CIDR demasiado pequeño. Un /24 para toda la VPC parece suficiente hasta que llega el
tercer servicio. El CIDR principal no se puede cambiar. Usa siempre /16: las IP privadas son
gratis.
Solapar rangos entre entornos. Producción 10.0.0.0/16 y desarrollo también 10.0.0.0/16 es
cómodo hasta el día del peering. Reserva el mapa de rangos antes de crear la primera VPC.
Poner el NAT Gateway en una subred privada. No dará ningún error al crearlo, y nada funcionará. El NAT va siempre en subred pública; lo privado es lo que lo usa.
Un solo NAT Gateway para dos AZ en producción. Ahorras 35 USD al mes y creas una dependencia entre zonas: si cae la AZ del NAT, las instancias de la otra zona pierden la salida. En pruebas es razonable; en producción, no.
Olvidar enableDnsHostnames. Los endpoints de interfaz y algunas integraciones de RDS fallan de
formas incomprensibles. Es lo primero que hay que activar tras crear la VPC.
Dejar PubliclyAccessible=true en RDS. Moverla a una subred privada no basta: si el atributo
sigue activo, RDS devuelve una IP pública y la aplicación deja de conectar.
No etiquetar la red. Una VPC sin Name y sin Proyecto es un vpc-0a1b2c3d que dentro de seis
meses nadie se atreve a borrar. Todos los comandos de esta lección llevan las cinco etiquetas
obligatorias por esa razón; en 11-02 veremos el valor económico que tiene.
Dejar IP elásticas sin asociar. Cuestan aunque no hagan nada. Revísalas con el comando de la sección de limpieza cada vez que borres una instancia.
Consejo de oro: antes de crear una sola subred, dibuja la tabla de rangos en un documento. Diez minutos de papel ahorran una migración de red.
Ejercicios
Ejercicio 1: planificar el direccionamiento de una segunda región
MercadoFresco quiere abrir una VPC de desarrollo en eu-west-1 y otra futura en eu-central-1, y
además conectar la oficina por VPN. Diseña el plan de direccionamiento completo: rangos que asignas
a cada red, justificación, y qué pasaría si asignaras 10.0.0.0/16 a las tres VPC.
Ejercicio 2: calcular subredes y IP útiles
Para una VPC 10.5.0.0/16 diseñada con tres AZ y dos capas (pública y privada), usando
máscara /22 en las públicas y /20 en las privadas: escribe la tabla completa de las seis subredes
con sus CIDR sin solapamiento, indica cuántas IP útiles tiene cada una y cuánto espacio queda libre.
Ejercicio 3: diagnosticar una instancia sin internet
Luis lanza una instancia en snet-mercadofresco-app-a y no puede ejecutar dnf update. Escribe la
secuencia de comprobaciones por CLI, en orden, y qué buscar en cada una. Considera al menos cuatro
causas posibles distintas.
Soluciones
Solución 1
Plan de direccionamiento, respetando el mapa que ya definimos:
| Red | Rango | Justificación |
|---|---|---|
| Oficina de Barcelona | 192.168.10.0/24 |
Ya existente, se documenta |
vpc-mercadofresco (prod, eu-west-1) |
10.0.0.0/16 |
La red principal, ya creada |
VPC de desarrollo (eu-west-1) |
10.1.0.0/16 |
Segundo bloque contiguo, fácil de recordar |
VPC de producción (eu-central-1) |
10.2.0.0/16 |
Tercer bloque, reservado desde ahora |
| VPN de teletrabajo | 10.200.0.0/22 |
Rango alto, separado, 1.024 direcciones |
Con 10.0.0.0/16 en las tres VPC: cada una funcionaría perfectamente por separado, y ese es el
peligro, porque el problema no aparece hasta meses después. Al intentar el primer peering, AWS
rechaza la petición directamente: no se puede emparejar VPC con CIDR solapados. Al montar la VPN
con la oficina, la oficina no podría distinguir a qué VPC enviar un paquete destinado a 10.0.32.15.
La única solución sería recrear una VPC entera y migrar todos sus recursos, porque el CIDR principal
es inmutable.
Solución 2
VPC 10.5.0.0/16 (de 10.5.0.0 a 10.5.255.255). Un /22 son 1.024 direcciones (bloques de 4 en
el tercer octeto); un /20 son 4.096 (bloques de 16).
| Subred | AZ | CIDR | Rango | IP útiles |
|---|---|---|---|---|
| pública-a | eu-west-1a |
10.5.0.0/22 |
10.5.0.0 – 10.5.3.255 |
1.019 |
| pública-b | eu-west-1b |
10.5.4.0/22 |
10.5.4.0 – 10.5.7.255 |
1.019 |
| pública-c | eu-west-1c |
10.5.8.0/22 |
10.5.8.0 – 10.5.11.255 |
1.019 |
| privada-a | eu-west-1a |
10.5.16.0/20 |
10.5.16.0 – 10.5.31.255 |
4.091 |
| privada-b | eu-west-1b |
10.5.32.0/20 |
10.5.32.0 – 10.5.47.255 |
4.091 |
| privada-c | eu-west-1c |
10.5.48.0/20 |
10.5.48.0 – 10.5.63.255 |
4.091 |
Total asignado: 3.072 + 12.288 = 15.360 direcciones. La VPC tiene 65.536, así que quedan 50.176
libres (desde 10.5.64.0 en adelante), es decir, un 76 % del espacio. Detalle de diseño: las
públicas ocupan de 10.5.0.0 a 10.5.11.255 y las privadas empiezan en 10.5.16.0 dejando un
hueco deliberado en 10.5.12.0/22, para poder ampliar la capa pública sin fragmentar el plan.
Solución 3
# 1. ¿La subred está asociada a la tabla de rutas correcta?
aws ec2 describe-route-tables --profile mercadofresco-dev --region eu-west-1 \
--filters Name=association.subnet-id,Values=$APP_A \
--query 'RouteTables[].{Tabla:RouteTableId,Rutas:Routes[].{D:DestinationCidrBlock,NAT:NatGatewayId,IGW:GatewayId}}'Qué buscar: que exista 0.0.0.0/0 con un NatGatewayId. Si no aparece ninguna tabla, la subred
está usando la tabla principal, que no tiene ruta de salida: hay que asociarla.
# 2. ¿El NAT Gateway existe y está disponible?
aws ec2 describe-nat-gateways --profile mercadofresco-dev --region eu-west-1 \
--nat-gateway-ids "$NAT_A" --query 'NatGateways[].[State,SubnetId]' --output tableQué buscar: estado available. Y comprobar que su SubnetId es la subred pública, no la
privada. Un NAT en subred privada es la causa clásica.
# 3. ¿La subred del NAT tiene realmente ruta al IGW?
aws ec2 describe-route-tables --profile mercadofresco-dev --region eu-west-1 \
--filters Name=association.subnet-id,Values=$PUB_A \
--query 'RouteTables[].Routes[?DestinationCidrBlock==`0.0.0.0/0`]'Qué buscar: GatewayId empezando por igw-. Sin esto, el NAT tampoco tiene salida.
# 4. ¿El grupo de seguridad de la instancia permite tráfico de SALIDA?
aws ec2 describe-instances --profile mercadofresco-dev --region eu-west-1 \
--instance-ids "$ID_INSTANCIA" \
--query 'Reservations[].Instances[].SecurityGroups[].GroupId' --output textQué buscar: por defecto todo grupo de seguridad permite toda la salida, pero si alguien la ha
restringido, dnf no llegará al repositorio. Esto entra ya en el terreno de la lección 03-02.
Una quinta causa a descartar: la instancia arrancó antes de que existiera la ruta del NAT y
tiene la caché de red antigua; basta con reiniciarla. Y una sexta: los Flow Logs muestran REJECT
en el tráfico de vuelta, lo que apuntaría a una NACL, que también es materia de 03-02.
Conclusión
MercadoFresco ya no vive en la red que le tocó por defecto: vive en vpc-mercadofresco, una red
diseñada. Sabes que una VPC es regional y una subred es zonal, que el CIDR principal 10.0.0.0/16
es inmutable y por eso se elige generoso, y que las direcciones privadas son gratis. Puedes leer
una máscara y calcular sus IP útiles, y sabes que AWS reserva cinco direcciones en cada subred,
entre ellas la .1 del router y la .2 del resolvedor DNS. Has documentado el mapa de rangos de la
empresa para que 10.0.0.0/16 nunca choque con el 192.168.10.0/24 de la oficina cuando llegue la
VPN.
Has construido las seis subredes en tres capas y dos zonas de disponibilidad, y entiendes el
concepto que sostiene todo el módulo: una subred es pública únicamente porque su tabla de rutas
tiene un 0.0.0.0/0 apuntando al Internet Gateway, no por un ajuste ni por su nombre. Sabes que
la ruta local es la que permite que la tienda hable con la base de datos sin configurar nada, y
que la capa de datos no tiene ninguna salida a internet por diseño: eso es defensa en
profundidad, no una regla que alguien pueda borrar por error.
Conoces el NAT Gateway —dónde se coloca, por qué uno por AZ, y que cuesta unos 35 USD al mes por
unidad más 0,048 USD por GB, lo que lo convierte en el recurso más caro que has creado hasta ahora—
y sus alternativas para una cuenta de aprendizaje. Distingues IP privada, pública, elástica y ENI, y
sabes que una EIP sin asociar sigue cobrando. Has montado el endpoint de puerta de enlace hacia
S3, que es gratuito y saca del NAT todo el tráfico del catálogo de fotos, y sabes cuándo hace
falta un endpoint de interfaz con PrivateLink. Has activado enableDnsHostnames, has movido la base
de datos mercadofresco-pedidos a sng-mercadofresco-datos mediante snapshot y restauración —con
--no-publicly-accessible— y has encendido los VPC Flow Logs hacia
mercadofresco-registros-web.
Pero la red que has construido, ahora mismo, no filtra nada. La ruta local permite que cualquier
instancia de la VPC abra una conexión al puerto 5432 de la base de datos, y la subred pública acepta
lo que llegue por el Internet Gateway. Falta el cortafuegos. En la lección 03-02, «Grupos de
seguridad y listas de control de acceso», montaremos las dos capas de filtrado de AWS: los grupos
de seguridad —con estado y, sobre todo, con la técnica de referenciar unos grupos desde otros en
lugar de escribir rangos de IP— y las NACL, sin estado, con sus reglas numeradas y su trampa de los
puertos efímeros. Al terminar, el puerto 5432 de mercadofresco-pedidos solo aceptará conexiones
del grupo de seguridad de la tienda, y sabrás leer un REJECT de los Flow Logs que acabas de
encender para averiguar exactamente cuál de las dos capas ha bloqueado un paquete.
Curso de AWS
Módulo 1: Introducción a AWS
- ¿Qué es AWS?
- Configuración de tu cuenta de AWS
- Infraestructura global de AWS
- Consola de administración de AWS
- AWS CLI y SDKs
Módulo 2: Servicios principales de AWS
Módulo 3: Redes y entrega de contenido
- Amazon VPC
- Grupos de seguridad y listas de control de acceso
- Elastic Load Balancing
- Amazon CloudFront
- Route 53
Módulo 4: Seguridad e identidad
- AWS Identity and Access Management (IAM)
- AWS Key Management Service (KMS)
- Secrets Manager y Parameter Store
- AWS Shield
- AWS WAF
Módulo 5: Monitorización y gestión
- Amazon CloudWatch
- AWS X-Ray y trazabilidad distribuida
- AWS CloudTrail
- AWS Config
- AWS Trusted Advisor
Módulo 6: Bases de datos
- Cómo elegir la base de datos adecuada
- Amazon DynamoDB
- Amazon Aurora
- Amazon Redshift
- Amazon ElastiCache
Módulo 7: Integración de aplicaciones
- Amazon SQS
- Amazon SNS
- Amazon EventBridge
- AWS Step Functions
- Patrones de integración: idempotencia, reintentos y colas de mensajes fallidos
