Conectar a S3 de forma privada con un endpoint de VPC

AWSBeginner
Practicar Ahora

Introducción

Una aplicación privada de entregas lee un manifiesto de S3 mediante NAT. Necesita una ruta específica del servicio que funcione sin acceso general a Internet. Crearás un endpoint de gateway de S3, compararás solicitudes reales, diagnosticarás una asociación incorrecta y restaurarás la red suministrada.

Completa primero Give a Private Subnet Outbound Access. Este entorno nuevo proporciona su propia aplicación, objeto de S3, subredes pública y privada, gateway NAT y reglas de seguridad. La CLI está configurada. Conserva estos recursos y la red de referencia; crea y elimina únicamente tu endpoint y restaura la ruta predeterminada NAT privada que quitarás temporalmente.

Relación con certificaciones

Este laboratorio ofrece práctica básica sobre estos temas:

Crear un endpoint de gateway de S3 para la aplicación privada

Inspeccionarás la ruta NAT inicial, identificarás los rangos de S3 y crearás el endpoint en la tabla privada.

Usa Terminal para los comandos y abre AWS View al lado. La aplicación conserva 10.20.2.10. El bucket suministrado parcel-delivery-storage contiene message.txt con Parcel manifest ready.

cd /home/labex/project

Selecciona la VPC por su etiqueta Name. Los filtros seleccionan recursos, la consulta extrae el ID y $(...) lo guarda:

VPC_ID=$(aws ec2 describe-vpcs \
  --filters Name=tag:Name,Values=application-network \
  --query 'Vpcs[0].VpcId' \
  --output text)

Guarda los IDs de las tablas privada y pública. Sus asociaciones con subredes ya son correctas:

PRIVATE_RT_ID=$(aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=$VPC_ID" Name=tag:Name,Values=private-routes \
  --query 'RouteTables[0].RouteTableId' \
  --output text)
PUBLIC_RT_ID=$(aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=$VPC_ID" Name=tag:Name,Values=public-routes \
  --query 'RouteTables[0].RouteTableId' \
  --output text)

Lee sus rutas y asociaciones:

aws ec2 describe-route-tables \
  --route-table-ids "$PRIVATE_RT_ID" "$PUBLIC_RT_ID" \
  --query 'RouteTables[].{ID:RouteTableId,Routes:Routes,Associations:Associations}' \
  --output json

La ruta privada 0.0.0.0/0 apunta al NAT suministrado; la pública apunta al gateway de Internet. Ambas conservan la ruta local. Guarda el ID de NAT para restaurarlo durante la limpieza:

NAT_ID=$(aws ec2 describe-nat-gateways \
  --filter "Name=vpc-id,Values=$VPC_ID" Name=state,Values=available \
  --query 'NatGateways[0].NatGatewayId' \
  --output text)

Consulta sus direcciones para compararlas con las solicitudes:

aws ec2 describe-nat-gateways \
  --nat-gateway-ids "$NAT_ID" \
  --query 'NatGateways[].{State:State,Addresses:NatGatewayAddresses}' \
  --output json

En AWS View, pulsa Read storage object: debe devolver Success y el manifiesto. Source address muestra la dirección pública de NAT. Request outbound service también tiene éxito con esa dirección. Esta es la configuración inicial que restaurarás.

Una lista de prefijos administrada por AWS agrupa los rangos del servicio en una región. Un endpoint de gateway de S3 agrega una ruta a esa lista en las tablas asociadas, sin asignar una dirección pública ni ofrecer acceso general a Internet. Selecciona la lista de S3 y consulta sus rangos IPv4:

PREFIX_ID=$(aws ec2 describe-prefix-lists \
  --filters Name=prefix-list-name,Values=com.amazonaws.us-east-1.s3 \
  --query 'PrefixLists[0].PrefixListId' \
  --output text)
aws ec2 get-managed-prefix-list-entries \
  --prefix-list-id "$PREFIX_ID" \
  --query 'Entries[].Cidr' \
  --output json

Crea el endpoint para S3 en us-east-1, asociado solo con la tabla privada. --vpc-endpoint-type Gateway elige el tipo basado en rutas; --service-name identifica el servicio regional; --route-table-ids elige la tabla de la aplicación. Las etiquetas identifican tu recurso:

ENDPOINT_ID=$(aws ec2 create-vpc-endpoint \
  --vpc-id "$VPC_ID" \
  --vpc-endpoint-type Gateway \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids "$PRIVATE_RT_ID" \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=parcel-s3-endpoint},{Key=Project,Value=parcel}]' \
  --query 'VpcEndpoint.VpcEndpointId' \
  --output text)

Lee el estado y la asociación:

aws ec2 describe-vpc-endpoints \
  --vpc-endpoint-ids "$ENDPOINT_ID" \
  --query 'VpcEndpoints[].{ID:VpcEndpointId,State:State,Type:VpcEndpointType,Service:ServiceName,Tables:RouteTableIds}' \
  --output json

Continúa cuando State sea available. Si no está listo, espera unos segundos y repite la consulta. Debe ser Gateway, para S3 y asociado solo con la tabla privada. Mantén Terminal abierto para conservar las variables.

Vuelve a pulsar Read storage object. El texto no cambia, pero la dirección de origen es 10.20.2.10. La ruta de prefijos de S3 es más específica que la predeterminada NAT; S3 utiliza el endpoint y otras solicitudes siguen usando NAT.

Mantener acceso a S3 sin la ruta NAT predeterminada

Quitarás la ruta de salida general y comprobarás que la ruta del servicio sigue funcionando.

Elimina únicamente la ruta NAT predeterminada privada. Conserva el gateway, su dirección, la ruta pública y el endpoint:

aws ec2 delete-route --route-table-id "$PRIVATE_RT_ID" --destination-cidr-block 0.0.0.0/0

La eliminación correcta no produce salida. Consulta las rutas:

aws ec2 describe-route-tables \
  --route-table-ids "$PRIVATE_RT_ID" \
  --query 'RouteTables[].Routes' \
  --output json

Permanecen local y la ruta S3 DestinationPrefixListId; no queda la predeterminada. El GatewayId del servicio es el ID del endpoint y el estado es active. Estas rutas se gestionan mediante asociaciones del endpoint, no con comandos ordinarios para editar o eliminar rutas.

Pulsa Read storage object: la nueva solicitud devuelve Parcel manifest ready desde 10.20.2.10. Request outbound service falla porque 198.51.100.20:9000 está fuera del prefijo S3 y no tiene ruta predeterminada. Request private application from outside también falla. El endpoint proporciona conectividad privada con S3, sin dirección pública ni rutas a otros destinos de Internet.

La aplicación privada lee S3 sin una ruta NAT predeterminada

Ejemplo: la tabla privada contiene la ruta local y el prefijo S3, sin 0.0.0.0/0. La respuesta real contiene el manifiesto y origen 10.20.2.10. NAT sigue disponible, pero no participa en esta ruta S3. Los IDs y direcciones generados pueden variar.

Observar una asociación con la tabla incorrecta

Moverás el endpoint fuera de la tabla de la aplicación para comprobar por qué un endpoint disponible puede ser inaccesible.

La asociación del endpoint con tablas y la asociación de una subred con una tabla son relaciones diferentes. Modifica solo la primera:

aws ec2 modify-vpc-endpoint \
  --vpc-endpoint-id "$ENDPOINT_ID" \
  --add-route-table-ids "$PUBLIC_RT_ID" \
  --remove-route-table-ids "$PRIVATE_RT_ID"

La respuesta indica Return: true. Consulta el endpoint:

aws ec2 describe-vpc-endpoints \
  --vpc-endpoint-ids "$ENDPOINT_ID" \
  --query 'VpcEndpoints[].{State:State,Tables:RouteTableIds}' \
  --output json

Continúa available, pero solo figura la tabla pública. Consulta ambas tablas:

aws ec2 describe-route-tables \
  --route-table-ids "$PRIVATE_RT_ID" "$PUBLIC_RT_ID" \
  --query 'RouteTables[].{ID:RouteTableId,Routes:Routes,Associations:Associations}' \
  --output json

La ruta automática S3 pasó a la tabla pública; la privada conserva solo local. Las asociaciones originales de las subredes no cambian. Compartir una VPC no permite a todas las subredes usar una misma ruta de endpoint.

Cuando AWS View refleje el cambio, pulsa Read storage object: la nueva solicitud muestra Connection failed y Storage unavailable, porque falta una ruta S3 en la tabla de la aplicación. Request outbound service también falla. Un éxito anterior es histórico. Conserva esta avería para la comprobación del paso; la repararás después.

Restaurar la ruta privada del servicio

Repararás la asociación sin recrear el endpoint, asignar una dirección pública ni restaurar NAT.

Devuelve el mismo endpoint a la tabla privada y quita la pública:

aws ec2 modify-vpc-endpoint \
  --vpc-endpoint-id "$ENDPOINT_ID" \
  --add-route-table-ids "$PRIVATE_RT_ID" \
  --remove-route-table-ids "$PUBLIC_RT_ID"

Consulta la asociación:

aws ec2 describe-vpc-endpoints \
  --vpc-endpoint-ids "$ENDPOINT_ID" \
  --query 'VpcEndpoints[].{State:State,Tables:RouteTableIds}' \
  --output json

Solo debe aparecer la privada. Inspecciona las rutas:

aws ec2 describe-route-tables \
  --route-table-ids "$PRIVATE_RT_ID" "$PUBLIC_RT_ID" \
  --query 'RouteTables[].{ID:RouteTableId,Routes:Routes}' \
  --output json

La ruta S3 privada vuelve automáticamente y desaparece de la tabla pública. La ruta pública de Internet permanece; la privada aún no tiene ruta predeterminada.

Envía una nueva Read storage object: debe devolver el manifiesto original desde 10.20.2.10. Request outbound service sigue fallando: el endpoint S3 no proporciona Internet general. Request private application from outside continúa bloqueada. La reparación conserva la dirección privada y las reglas suministradas.

Eliminar el endpoint y restaurar NAT

Eliminarás tu endpoint, verificarás que desaparezcan sus rutas automáticas y restaurarás la ruta privada al NAT suministrado.

Elimina solo tu endpoint:

aws ec2 delete-vpc-endpoints --vpc-endpoint-ids "$ENDPOINT_ID"

Unsuccessful debe estar vacío. Consulta el inventario completo, sin depender de etiquetas que podrían borrarse:

aws ec2 describe-vpc-endpoints \
  --query 'VpcEndpoints[].{ID:VpcEndpointId,State:State,Tables:RouteTableIds}' \
  --output json

El endpoint puede seguir listado como deleted, pero no debe quedar activo. Ese registro no puede enrutar tráfico. Si figura deleting, espera unos segundos y repite la misma consulta. Consulta ambas tablas:

aws ec2 describe-route-tables \
  --route-table-ids "$PRIVATE_RT_ID" "$PUBLIC_RT_ID" \
  --query 'RouteTables[].{ID:RouteTableId,Routes:Routes}' \
  --output json

Ninguna debe conservar el prefijo S3. Pulsa Read storage object: falla mientras la privada solo contiene local, comprobando que no hay una ruta alternativa oculta.

Restaura la ruta predeterminada al ID de NAT guardado. No elimines NAT, su dirección, la aplicación ni sus datos S3:

aws ec2 create-route \
  --route-table-id "$PRIVATE_RT_ID" \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id "$NAT_ID"

Lee las rutas restauradas:

aws ec2 describe-route-tables \
  --route-table-ids "$PRIVATE_RT_ID" \
  --query 'RouteTables[].Routes' \
  --output json

local y la ruta NAT activa coinciden con el estado inicial. Una consulta fallida no prueba eliminación: el inventario autenticado debe responder correctamente y mostrar ausencia o deleted, sin rutas administradas.

Pulsa Read storage object nuevamente: devuelve el manifiesto mediante NAT y Source address muestra su dirección pública. Request outbound service tiene éxito con la misma dirección; Request private application from outside permanece bloqueada. Conserva VPC, subredes, NAT, reglas, objeto S3 y red de referencia.

Ejecuta la comprobación de este paso.

Resumen

Creaste un endpoint S3 y verificaste lecturas reales con dirección privada. Al quitar la ruta NAT predeterminada, S3 permaneció accesible y otros destinos quedaron bloqueados. La asociación con la tabla pública rompió el acceso; devolverla a la privada lo reparó sin cambiar la aplicación ni sus reglas.

Eliminaste el endpoint, verificaste la retirada de sus rutas y restauraste NAT.