La suite de tests d’intégration de l’API doit parler à une instance RDS privée, un microservice interne sans endpoint public et un cluster ElastiCache Redis. Le buildspec actuel contourne ça en tunnelant en SSH à travers un bastion, qui échoue par intermittence et fuit des credentials quand ça plante. La bonne réponse, c’est le mode VPC de CodeBuild — le build s’exécute à l’intérieur du VPC et peut atteindre les ressources privées directement. Mais le mode VPC n’est pas gratuit, et la plupart des projets CodeBuild ne devraient pas l’utiliser. Voici le cadre de décision.
Ce qui se passe
Par défaut, CodeBuild s’exécute dans une infrastructure gérée par AWS hors de votre VPC. Le build a un accès internet complet via le NAT géré par AWS et aucun chemin vers vos sous-réseaux privés. C’est correct pour le cas courant — tirer la source, installer les dépendances, exécuter les tests contre des services publics, pousser les artefacts. La plupart des builds ont besoin exactement de ça.
Le mode VPC attache une interface réseau élastique (ENI) de votre VPC au conteneur de build au démarrage. Le build s’assoit alors dans un de vos sous-réseaux privés, atteint les ressources privées via le routage du VPC et utilise la passerelle NAT de votre VPC pour la sortie internet (pour tirer les paquets de npm, le Docker Hub public, etc.). Le build est terminé, l’ENI est détachée à la fin du build.
Les compromis sont réels et pas évidents :
Démarrage à froid de l’ENI. Chaque build en mode VPC paie une pénalité de 30 à 90 secondes au démarrage pendant que l’ENI est provisionnée et attachée. CodeBuild a amélioré ça avec le temps (c’était 5+ minutes avant), mais 30-90 secondes sur un build de 2 minutes, c’est 25 % à 75 % de surcharge. Sur un build de 20 minutes, c’est négligeable. La pénalité frappe le début de chaque build, y compris les builds ratés.
Coût de la passerelle NAT. Le trafic sortant du build (tirer les paquets npm, les images Docker de base, sync S3 vers un bucket public) passe par votre passerelle NAT. NAT facture au Go traité. Un build qui tire 500 Mo de paquets npm et une image Docker de base de 1 Go traite 1,5 Go à travers NAT. Multipliez par la fréquence des builds. Sur une équipe à haute vélocité, le coût NAT venant de CodeBuild devient une ligne notable — parfois plus que le compute CodeBuild lui-même.
Épuisement d’IPs de sous-réseau. Chaque build en cours consomme une IP du sous-réseau. Une équipe qui exécute 30 builds simultanés dans un sous-réseau /26 (64 IPs), c’est correct. Une équipe qui exécute 100 builds simultanés dans le même sous-réseau verra des builds en file d’attente avec INSUFFICIENT_FREE_ADDRESSES. Dimensionnez les sous-réseaux pour CodeBuild en supposant le pic de builds simultanés plus une marge.
Exigences des endpoints VPC. Sans endpoints VPC pour S3, ECR, Secrets Manager, KMS et CloudWatch Logs, chaque interaction du build avec ces services passe par la passerelle NAT. Ajoutez les endpoints — endpoints d’interface pour les services AWS, endpoint de passerelle pour S3 — et la facture NAT chute peut-être de 70 %. L’endpoint de passerelle pour S3 est gratuit ; les endpoints d’interface ont un coût horaire fixe mais se rentabilisent à un trafic modeste.
La règle de décision qu’on applique : utilisez le mode VPC seulement quand le build a besoin d’atteindre des ressources privées. N’utilisez pas le mode VPC pour la commodité de « tout est dans le VPC ».
Comment vérifier
Cas où le mode VPC est la bonne réponse :
-
Tests d’intégration contre un RDS privé. La BD est dans un sous-réseau privé sans IP publique. Le test doit exécuter les migrations et assertionner contre les vraies rangées. Le tunnel SSH à travers un bastion est fragile ; le mode VPC est direct.
-
Builds qui touchent une API interne. Un dépôt multi-services où le build du service A exécute des tests de contrat contre le service B déployé, qui est seulement atteignable à l’intérieur du VPC.
-
Conformité — pas d’IPs publiques sur l’infra de build. Certaines charges de travail réglementées exigent que tout le trafic de build traverse un réseau privé. Le mode VPC plus les endpoints VPC signifie que le build ne touche jamais l’internet public.
-
Tirer depuis un registre de paquets privé. Un dépôt CodeArtifact privé configuré pour accès VPC seulement, ou un registre npm auto-hébergé derrière un ALB sans listener public.
Cas où le mode VPC est la mauvaise réponse :
-
« Notre infra est dans un VPC, donc le build devrait l’être aussi. » Non. Le build n’a pas besoin d’être dans le même VPC que l’application déployée. Buildez à l’extérieur, déployez via les APIs qui rejoignent l’intérieur.
-
Tirer les images Docker depuis un registre public. Docker Hub public, ECR public, GitHub Container Registry public — aucun n’a besoin du mode VPC. Les images ECR dans votre compte sont atteignables depuis le réseau par défaut de CodeBuild via l’endpoint public avec auth IAM.
-
Builds qui ne font que lire S3 et pousser S3. S3 est atteignable depuis le réseau par défaut. Le mode VPC ajoute le coût NAT et la surcharge ENI sans bénéfice.
-
Lint, typecheck, tests unitaires. Si le build ne touche jamais une ressource privée, le mode VPC est de la surcharge pure.
Le pattern hybride qui fonctionne pour beaucoup d’équipes : séparez le build en deux projets CodeBuild dans un pipeline. Le premier projet exécute lint/typecheck/tests-unitaires hors VPC (rapide, peu cher). Le second projet exécute les tests d’intégration dans le VPC (lent, cher, seulement quand nécessaire). Le second projet se déclenche seulement sur les changements affectant le service ou sur la branche main. La plupart des commits ne paient pas la pénalité VPC.
Configuration du mode VPC au niveau du projet :
aws codebuild update-project \
--name web-api-integration-tests \
--vpc-config '{
"vpcId": "vpc-0abc123def456",
"subnets": ["subnet-0aaa", "subnet-0bbb", "subnet-0ccc"],
"securityGroupIds": ["sg-0codebuild123"]
}'
Le groupe de sécurité a besoin d’une sortie vers les ressources privées ciblées par le build, plus une sortie vers 0.0.0.0/0 pour l’internet via NAT (ou une sortie restreinte si toutes les dépendances sont miroirées en interne).
Piège courant : le rôle IAM attaché au projet CodeBuild a besoin de ec2:CreateNetworkInterface, ec2:DeleteNetworkInterface, ec2:DescribeSubnets, ec2:DescribeSecurityGroups, et de l’inhabituel ec2:CreateNetworkInterfacePermission scopé à un principal de service spécifique. La politique gérée AWSCodeBuildDeveloperAccess n’inclut pas toutes ces actions ; vous avez besoin d’une politique personnalisée :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:DescribeDhcpOptions",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeVpcs"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "ec2:CreateNetworkInterfacePermission",
"Resource": "arn:aws:ec2:us-east-1:ACCOUNT-ID:network-interface/*",
"Condition": {
"StringEquals": {
"ec2:Subnet": [
"arn:aws:ec2:us-east-1:ACCOUNT-ID:subnet/subnet-0aaa",
"arn:aws:ec2:us-east-1:ACCOUNT-ID:subnet/subnet-0bbb",
"arn:aws:ec2:us-east-1:ACCOUNT-ID:subnet/subnet-0ccc"
],
"ec2:AuthorizedService": "codebuild.amazonaws.com"
}
}
}
]
}
La correction
Le cadre de décision qui tient pour chaque décision de mode VPC sur CodeBuild :
-
Par défaut, pas de VPC. Ne basculez en mode VPC que quand la correction du build dépend de l’atteinte d’une ressource privée. Le démarrage à froid de l’ENI, le coût NAT et le risque d’épuisement d’IPs sont des surcharges réelles.
-
Séparez les projets par besoin. Si 80 % de vos builds n’ont pas besoin du VPC et 20 % oui, exécutez deux projets. Ne payez pas la surcharge VPC sur chaque build.
-
Ajoutez les endpoints VPC avant d’activer le mode VPC. Endpoints d’interface pour ECR (api et dkr), Secrets Manager, KMS, STS, CloudWatch Logs, et endpoint de passerelle pour S3. Sans ça, votre facture NAT venant de CodeBuild croît linéairement avec le volume de builds.
-
Sous-réseaux multi-AZ. Configurez CodeBuild avec au moins deux sous-réseaux dans des AZs différentes. Les projets à sous-réseau unique échouent quand cette AZ a un bref problème réseau et qu’il n’y a pas d’alternative pour le placement d’ENI.
-
Dimensionnez correctement le sous-réseau. Estimez le pic de builds simultanés et choisissez des sous-réseaux avec au moins 4× ce nombre d’IPs libres. Un
/24(251 IPs utilisables après les cinq réservées par AWS) est confortable pour la plupart des équipes. Ne fourrez pas CodeBuild dans un/28partagé avec d’autres charges de travail. -
Groupe de sécurité avec sortie explicite. N’utilisez pas le groupe de sécurité par défaut du VPC. Le SG CodeBuild devrait permettre la sortie seulement vers ce dont le build a réellement besoin — port RDS vers le SG de la BD, SG de l’ALB de l’API interne, 443 vers 0.0.0.0/0 pour les téléchargements de paquets. Une sortie étroite empêche le build d’atteindre tout ce qu’il ne devrait pas.
-
Surveillez la métrique de démarrage à froid.
CodeBuild/DownloadSourceDurationetCodeBuild/QueuedDurationde CloudWatch montrent le temps avant la première commande. Pour les projets VPC, c’est votre temps d’attachement d’ENI. Si c’est constamment au-dessus de 90 secondes, le soutien AWS peut aider — parfois c’est un problème régional.
Le test le plus simple pour confirmer que vous avez fait le bon choix : buildez un projet CodeBuild avec mode VPC, exécutez un buildspec vide qui ne fait qu’un echo « bonjour », et chronométrez-le. Si le temps total est au-dessus de 90 secondes pour « bonjour », vous payez cette surcharge sur chaque build. Demandez-vous ensuite : ce build a-t-il vraiment besoin d’une ressource privée ? Si non, n’utilisez pas le mode VPC.
Stack Harbor opère CodeBuild + CodePipeline à l’échelle production dans le cadre de l’onboarding Gestion AWS et des Environnements infogérés en continu. Si vos builds tunnellent à travers un bastion ou si votre facture NAT a grandi plus vite que votre équipe, commencez par une consultation d’infrastructure.