Une analyse de flow logs montre que 70 % du sortant NAT du VPC va vers des plages IP S3. Les runners CI de l’équipe tirent des artefacts de build depuis S3 quelques milliers de fois par heure ; les serveurs applicatifs streament des logs vers S3 ; les sauvegardes vont vers S3. Chaque octet sort via la NAT Gateway et est facturé au GB. Ajouter un endpoint de passerelle pour S3 prend une modification de table de routage et fait chuter la facture NAT d’environ 70 % du jour au lendemain. La même chose est vraie pour DynamoDB, plus petit en volume mais gratuit quand même. Les endpoints d’interface pour ECR coûtent un petit frais horaire par AZ mais économisent un frais au GB plus important sur les tirages d’images conteneur. Le calcul est tellement déséquilibré que tout VPC exécutant NAT sans endpoints laisse de l’argent sur la table. Voici la mise en place qui marche.
Ce qui se passe
Un endpoint VPC permet au trafic entre votre VPC et un service AWS de circuler sur le réseau interne d’AWS sans jamais transiter par un internet gateway ou une NAT Gateway. Il y a deux types d’endpoints :
Endpoints de passerelle — pour S3 et DynamoDB seulement. Aucun frais horaire. Aucun frais au GB. Implémentés comme une entrée de table de routage : la prefix list du service (par exemple pl-63a5400a pour S3 dans us-east-1) route vers l’endpoint de passerelle, qu’AWS résout vers le point d’accès S3 qui sert le sous-réseau appelant. Le trafic des instances du sous-réseau privé vers S3 atteint l’endpoint, contourne NAT et contourne l’internet gateway. Le trafic apparaît toujours à S3 comme venant du CIDR du VPC, ce qui fait que les politiques de bucket S3 qui filtrent par VPC source fonctionnent.
Endpoints d’interface — pour chaque autre service AWS et pour PrivateLink vers des services tiers. Implémentés comme une ENI dans le sous-réseau de chaque AZ, avec une IP d’ENI du CIDR de votre sous-réseau. Frais horaire par AZ par endpoint. Frais au GB sur les données traitées (plus bas que celui de NAT Gateway). Chaque AZ reçoit une ENI ; le SDK AWS résout le nom d’hôte régional du service vers l’IP d’ENI appropriée à travers Route 53 DNS privé (si vous activez le DNS privé sur l’endpoint).
Le calcul de coût :
- Un endpoint de passerelle pour S3 est gratuit. Le seuil de rentabilité est zéro — si vous avez du trafic S3, l’endpoint se rentabilise instantanément.
- Un endpoint d’interface coûte un frais horaire par AZ. Pour trois AZ, c’est un coût horaire modeste. Le seuil de rentabilité face à NAT Gateway dépend du différentiel de tarif de traitement de données et du volume. Approximativement : si le service bouge plus de 10 GB/mois par AZ, l’endpoint d’interface est moins cher que NAT.
- Pour les services à très faible trafic (un appel d’API Step Functions une fois par jour), l’endpoint d’interface peut ne pas se rentabiliser en coût — mais les bénéfices de sécurité et de routage (aucun chemin public) justifient souvent quand même.
Le piège DNS : quand vous activez le DNS privé sur un endpoint d’interface, le nom d’hôte régional du service (api.ecr.us-east-1.amazonaws.com) est résolu par le résolveur Route 53 de votre VPC vers l’IP d’ENI de l’endpoint. À l’intérieur du VPC qui possède l’endpoint, ça marche automatiquement. À travers un Transit Gateway ou un peering VPC, la résolution DNS NE traverse PAS — le résolveur du VPC partenaire ne sait rien du DNS privé de votre endpoint. Les consommateurs inter-comptes ou inter-VPC d’un endpoint d’interface ont besoin de leur propre endpoint, ou ils ont besoin d’une zone hébergée privée Route 53 partagée via Resource Access Manager et associée à leur VPC.
Comment vérifier
La liste des services avec endpoints de passerelle versus endpoints d’interface :
| Service | Type d’endpoint | Coût |
|---|---|---|
| S3 | passerelle (aussi interface pour usage inter-région/inter-compte) | gratuit |
| DynamoDB | passerelle seulement | gratuit |
| ECR (registre) | interface | horaire + au GB |
| ECR (docker pull) | interface (*.dkr.ecr.*) | horaire + au GB |
| KMS | interface | horaire + au GB |
| Secrets Manager | interface | horaire + au GB |
| Systems Manager (SSM) | interface (com.amazonaws.<region>.ssm, ssmmessages, ec2messages) | horaire + au GB |
| STS | interface | horaire + au GB |
| CloudWatch Logs | interface | horaire + au GB |
| SQS | interface | horaire + au GB |
| SNS | interface | horaire + au GB |
| Lambda | interface | horaire + au GB |
| API Gateway (API privées) | interface | horaire + au GB |
Inspecter les endpoints courants :
aws ec2 describe-vpc-endpoints \
--filters Name=vpc-id,Values=vpc-0123456789abcdef0 \
--query 'VpcEndpoints[].[VpcEndpointId,ServiceName,VpcEndpointType,State]' \
--output table
Inspecter ceux qui devraient en avoir un (basé sur les flow logs) :
-- Athena sur les flow logs : principales destinations sortantes résolvant vers des IP de service AWS
SELECT
dstaddr,
SUM(bytes) AS total_bytes
FROM vpc_flow_logs
WHERE year = '2026' AND month = '5' AND day = '25'
AND flow_direction = 'egress'
AND NOT regexp_like(dstaddr, '^10\.')
GROUP BY dstaddr
ORDER BY total_bytes DESC
LIMIT 50;
Croisez les principales IP avec les plages IP des services AWS (https://ip-ranges.amazonaws.com/ip-ranges.json). Toute IP dans la plage d’un service AWS qui génère un sortant significatif est candidate à un endpoint.
La correction
La procédure de déploiement pour un VPC qui n’a actuellement aucun endpoint :
Étape 1 — endpoints de passerelle pour S3 et DynamoDB. Les deux sont gratuits. Déployez-les en premier.
# Trouver les tables de routage pour les sous-réseaux privés
PRIVATE_RTBS=$(aws ec2 describe-route-tables \
--filters Name=vpc-id,Values=vpc-0123456789abcdef0 Name=tag:Tier,Values=private \
--query 'RouteTables[].RouteTableId' --output text)
# Créer l'endpoint de passerelle S3, attaché à toutes les tables de routage privées
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0123456789abcdef0 \
--vpc-endpoint-type Gateway \
--service-name com.amazonaws.us-east-1.s3 \
--route-table-ids $PRIVATE_RTBS
# Même chose pour DynamoDB
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0123456789abcdef0 \
--vpc-endpoint-type Gateway \
--service-name com.amazonaws.us-east-1.dynamodb \
--route-table-ids $PRIVATE_RTBS
Vérifiez depuis une instance de sous-réseau privé : aws s3 cp s3://bucket/key /tmp/test devrait réussir ; l’entrée flow log pour l’appel devrait montrer la source comme l’IP privée de l’instance et la destination comme l’IP du service AWS S3, avec le trafic NE passant PAS à travers l’ENI de la NAT Gateway.
Surveillez la facture de sortie NAT le lendemain. Le trafic S3 devrait chuter à près de zéro.
Étape 2 — endpoints d’interface pour les services lourds. Choisissez à partir des preuves de flow logs. Les trois habituels sont ECR (pour les tirages de conteneurs), CloudWatch Logs (pour le streaming de logs) et Systems Manager (pour SSM session manager et patch baselines).
# Créer un groupe de sécurité pour les endpoints d'interface
# Le SG d'endpoint autorise 443 entrant depuis le CIDR du VPC
aws ec2 create-security-group \
--group-name sg-vpc-endpoints \
--description "Autoriser 443 du VPC vers les endpoints d'interface" \
--vpc-id vpc-0123456789abcdef0
aws ec2 authorize-security-group-ingress \
--group-id sg-vpc-endpoints-id \
--protocol tcp --port 443 --cidr 10.20.0.0/16
# Endpoint registre ECR (l'API)
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0123456789abcdef0 \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.us-east-1.ecr.api \
--subnet-ids subnet-private-1a subnet-private-1b subnet-private-1c \
--security-group-ids sg-vpc-endpoints-id \
--private-dns-enabled
# Endpoint docker ECR (le tirage d'image)
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0123456789abcdef0 \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.us-east-1.ecr.dkr \
--subnet-ids subnet-private-1a subnet-private-1b subnet-private-1c \
--security-group-ids sg-vpc-endpoints-id \
--private-dns-enabled
ECR exige spécifiquement les deux endpoints — l’API de registre pour l’authentification et l’endpoint dkr pour le tirage d’image réel. Avec les deux en place et l’endpoint de passerelle S3 déjà déployé (les couches d’image vivent en S3 derrière ECR), un docker pull depuis une instance de sous-réseau privé circule entièrement à travers les endpoints.
Étape 3 — vérifier le routage. Depuis une instance de sous-réseau privé :
# Devrait résoudre vers une adresse 10.x.x.x (l'ENI), pas une IP AWS publique
dig api.ecr.us-east-1.amazonaws.com
# Devrait réussir et ne pas apparaître dans les flow logs NAT
aws ecr get-login-password --region us-east-1
Étape 4 — accès inter-comptes et inter-VPC aux endpoints d’interface. C’est là que le piège DNS mord. Si un endpoint d’interface vit dans le VPC du compte A, et que le VPC du compte B doit l’utiliser via un Transit Gateway :
- Désactivez le DNS privé sur l’endpoint (ou acceptez que le consommateur ne puisse pas utiliser le nom d’hôte régional).
- Créez une zone hébergée privée Route 53 pour le nom d’hôte du service dans le compte B, avec un CNAME ou alias pointant sur le nom DNS régional de l’endpoint (par exemple
vpce-12345-abcdef.api.ecr.us-east-1.vpce.amazonaws.com). - Associez la zone hébergée privée au VPC du compte B.
- Autorisez TCP 443 depuis le CIDR du VPC de B sur le SG de l’endpoint.
- Confirmez le routage — les tables de routage TGW doivent autoriser le VPC de B à atteindre le VPC de A (l’IP de l’ENI de l’endpoint).
L’alternative plus simple : chaque VPC consommateur crée son propre endpoint. Le coût horaire est plus élevé ; la plomberie DNS disparaît.
Étape 5 — politiques de bucket et politiques d’endpoint, si nécessaire. Les endpoints de passerelle et d’interface supportent tous deux des politiques d’endpoint qui restreignent quels principaux AWS ou ressources peuvent être accédés via l’endpoint. Le motif courant est de cibler un endpoint de passerelle S3 à « seulement les buckets dans ce compte » pour prévenir l’exfiltration de données vers un bucket S3 tiers. Les politiques d’endpoint sont en JSON, semblables à IAM, et s’appliquent au niveau endpoint.
L’erreur la plus commune : activer le DNS privé sur un endpoint d’interface puis se demander pourquoi le SDK AWS depuis un VPC partenaire échoue. Le DNS privé ne marche que dans le VPC qui possède l’endpoint sauf si vous partagez la zone hébergée. Soit donnez à chaque VPC consommateur son propre endpoint, soit partagez le DNS explicitement.
L’autre règle qu’on tient : les endpoints sont l’optimisation de facture AWS la moins chère pour à peu près n’importe quel VPC. L’endpoint de passerelle S3 ne coûte rien à déployer et se rentabilise dès le premier jour. Les endpoints d’interface pour ECR, CloudWatch Logs et SSM se rentabilisent en un mois sur n’importe quelle taille de charge non-triviale. L’exception est un VPC de développement à très faible trafic — là, le coût horaire d’endpoint peut ne pas atteindre la rentabilité, et la réponse plus simple est « laissez-le sur NAT, ce VPC bouge cinq GB par mois ».
Pour le côté sortie de la même décision, voir NAT Gateway vs instance NAT. Pour l’analyse de flow logs qui identifie les candidats à endpoint, voir Analyse des Flow Logs VPC. Pour la version inter-comptes de la connectivité, voir Peering VPC vs PrivateLink.
Stack Harbor déploie des architectures d’endpoints dans le cadre des audits de factures NAT en Gestion AWS et des Environnements infogérés en continu. Si vos sous-réseaux privés paient des prix NAT pour du trafic qui devrait être sur un endpoint, commencez par une consultation d’infrastructure.