Aller au contenu

Lambda dans un VPC : les erreurs réseau qui brisent l'accès Internet et RDS

Attachez une fonction Lambda à un VPC et soudain elle ne peut plus atteindre Internet, ou toujours pas RDS. Les cinq erreurs réseau derrière presque tous les échecs Lambda-VPC, et comment corriger chacune.

Attacher une fonction Lambda à un VPC change une chose du tout au tout : la fonction cesse d’utiliser le réseau de Lambda, connecté à Internet, et se met à envoyer tout son trafic à travers une interface réseau élastique dans vos sous-réseaux. À partir de ce moment, vos tables de routage, groupes de sécurité et choix de sous-réseaux décident de ce que la fonction peut atteindre — et le mode d’échec n’est presque jamais un message d’erreur : c’est un blocage silencieux suivi d’une expiration. Presque chaque montage Lambda-dans-un-VPC brisé se ramène à cinq erreurs, toutes vérifiables en quinze minutes.

Ce qui se passe

Une fonction attachée à un VPC reçoit une ENI Hyperplane dans chaque sous-réseau sélectionné, et chaque paquet sortant part par elle. L’ENI ne reçoit jamais d’adresse IP publique. Ce seul fait explique l’échec le plus fréquent : placer la fonction dans un sous-réseau public, dont la table de routage envoie 0.0.0.0/0 vers une passerelle Internet. Une passerelle Internet ne fonctionne que pour les ressources avec des IP publiques — les paquets de la fonction sortent, rien ne peut revenir, et chaque appel externe reste suspendu jusqu’à l’expiration de la fonction.

L’accès Internet pour une fonction attachée à un VPC exige donc le même chemin que n’importe quel serveur privé : des sous-réseaux dont la table de routage envoie 0.0.0.0/0 vers une passerelle NAT (ou instance NAT) qui vit elle-même dans un sous-réseau public. Les appels aux services AWS — S3, Secrets Manager, SQS — peuvent soit emprunter ce chemin NAT, soit, mieux, utiliser des points de terminaison VPC et éviter Internet complètement.

La deuxième famille d’échecs, ce sont les groupes de sécurité. Le groupe de sécurité de la fonction gouverne son trafic sortant (habituellement ouvert par défaut), mais le groupe de sécurité de la cible doit permettre l’entrant depuis la fonction. Une instance RDS dont le groupe de sécurité ne permet l’entrant 5432 que depuis le groupe du serveur d’application refusera la fonction Lambda jusqu’à ce que le groupe de la fonction soit ajouté comme source.

Le reste est de la tenue de livres : les réglages de résolution DNS du VPC, les sous-réseaux qui manquent d’adresses IP libres, et les fonctions attachées à des sous-réseaux carrément dans le mauvais VPC — tous des cas réels trouvés dans des comptes de production.

Quoi vérifier en premier

  • À quels sous-réseaux la fonction est attachée, et où pointe leur route par défaut. Passerelle NAT : bon. Passerelle Internet : c’est le bogue. Pas de route par défaut : pas d’Internet par conception — confirmez que c’est voulu.
  • Le groupe de sécurité de la cible. Le groupe de RDS/ElastiCache/ALB interne permet-il l’entrant depuis le groupe de sécurité de la fonction Lambda sur le bon port?
  • Si les deux côtés sont dans le même VPC. Sinon, il faut du peering ou une passerelle de transit avec des routes dans les deux sens.
  • Les réglages DNS du VPC. enableDnsSupport et enableDnsHostnames doivent être actifs pour que les noms d’hôte des points de terminaison RDS se résolvent.
  • Les IP libres dans les sous-réseaux. Chaque configuration de fonction unique consomme de la capacité d’ENI; les minuscules sous-réseaux /28 causent des échecs à l’échelle.

Comment vérifier

Tirez la configuration réseau de la fonction et suivez-la vers l’extérieur :

aws lambda get-function-configuration --function-name my-function \
  --query 'VpcConfig'

# Où chaque sous-réseau route-t-il 0.0.0.0/0 ?
aws ec2 describe-route-tables \
  --filters "Name=association.subnet-id,Values=subnet-0abc123" \
  --query 'RouteTables[].Routes[?DestinationCidrBlock==`0.0.0.0/0`]'

# Que permet en entrant le groupe de sécurité cible ?
aws ec2 describe-security-groups --group-ids sg-0db123 \
  --query 'SecurityGroups[].IpPermissions'

Dans la console : Lambda > Functions > (fonction) > Configuration > VPC montre les sous-réseaux et groupes de sécurité; VPC > Subnets > Route table montre le chemin de sortie. Pour un test en direct, une fonction de diagnostic temporaire qui tente un curl vers une URL externe et une connexion TCP vers la base de données, en journalisant chaque étape avec le temps, vous dit en une invocation quel saut bloque. Les concepts de routage VPC sont documentés à https://docs.aws.amazon.com/vpc/.

Le correctif

  1. Déplacez la fonction vers des sous-réseaux privés qui routent par une passerelle NAT. C’est le correctif canonique pour « plus d’Internet après l’attachement VPC ». Sélectionnez deux ou trois sous-réseaux privés répartis sur les AZ, confirmez que leur table de routage envoie 0.0.0.0/0 vers la passerelle NAT, et redéployez. Les compromis de dimensionnement et de coût sont couverts dans Passerelle NAT ou instance NAT.
  2. Ajoutez le groupe de sécurité de la fonction comme source sur la cible. Pour RDS : modifiez le groupe de sécurité de la base, ajoutez une règle entrante pour le port de la base avec le groupe de sécurité de la fonction Lambda comme source. Référencez les groupes par ID, pas par CIDR — ça survit au roulement des IP.
  3. Utilisez des points de terminaison VPC pour le trafic vers les services AWS. Les points de terminaison de passerelle pour S3 et DynamoDB sont gratuits et retirent ce trafic du chemin NAT; les points de terminaison d’interface couvrent Secrets Manager, SQS et presque tout le reste. La logique de sélection est dans Points de terminaison VPC pour S3 et DynamoDB.
  4. Corrigez le DNS du VPC si les noms d’hôte ne se résolvent pas. Activez le soutien DNS et les noms d’hôte DNS sur le VPC (aws ec2 modify-vpc-attribute --vpc-id vpc-0abc --enable-dns-hostnames), et rappelez-vous que des ensembles d’options DHCP personnalisés ou des règles Route 53 Resolver peuvent modifier le comportement.
  5. Donnez de l’espace à Lambda dans les sous-réseaux. Dédiez des sous-réseaux privés de taille raisonnable (un /24 par AZ est un plancher confortable) plutôt que d’en partager des bondés, pour que l’allocation d’ENI n’entre jamais en compétition avec d’autres charges.
  6. N’attachez que ce qui doit l’être. Si une fonction ne touche pas de ressources privées, sortez-la complètement du VPC — elle retrouve l’accès Internet direct et vous supprimez toute une classe d’échecs.

Quand ce n’est pas la bonne approche

Si la seule raison d’être de la fonction dans le VPC est d’atteindre RDS, et que les tempêtes de connexions sont la vraie douleur, le correctif plus profond est peut-être RDS Proxy plutôt que plus de chirurgie réseau — le comportement de Lambda, qui monte à des centaines d’exécutions, est fondamentalement hostile aux connexions de base de données par invocation. Et si vous bâtissez de l’infrastructure NAT uniquement pour qu’une petite fonction appelle une API externe, repensez-y : gardez cette fonction hors du VPC, ou routez l’appel par un chemin de sortie existant.

Erreurs fréquentes

  • Sous-réseau public plus passerelle Internet, en s’attendant à avoir Internet — le classique, parce que ça fonctionne pour les instances EC2 avec IP publiques et échoue en silence pour Lambda.
  • Tester depuis un bastion EC2 dans un autre sous-réseau et conclure « le réseau est correct » — autre sous-réseau, autre table de routage, autre résultat.
  • Ouvrir le groupe de sécurité de la base à 0.0.0.0/0 « temporairement » pendant le débogage et le livrer comme ça.
  • Attacher chaque fonction du compte au VPC par défaut, traînant le trafic destiné à Internet à travers le NAT et payant des frais de traitement pour aucun bénéfice.

Prévention

  • Standardisez deux ou trois sous-réseaux « lambda-private » par VPC dans votre IaC, précâblés à la table de routage NAT, et interdisez la sélection de sous-réseaux à l’improviste.
  • Référencez les groupes de sécurité par ID dans l’IaC pour que la règle Lambda-vers-base soit créée en même temps que la fonction, pas retenue de mémoire après coup.
  • Ajoutez les points de terminaison de passerelle pour S3 et DynamoDB à chaque gabarit de VPC par défaut — ils sont gratuits et retirent à la fois du coût et de la surface d’échec.
  • Incluez un test de fumée réseau (appel HTTPS externe plus connexion TCP à la base) dans le pipeline de déploiement des fonctions attachées à un VPC.

Lambda attachée à un VPC fonctionne de façon fiable une fois que les routes, les groupes et les sous-réseaux sont délibérés — chaque blocage silencieux remonte à l’une des cinq erreurs ci-dessus. Si personne dans votre équipe ne possède vraiment l’environnement AWS de bout en bout, c’est la racine de la plupart de ces problèmes — Stack Harbor opère des comptes AWS au quotidien sous Opérations AWS, et vous pouvez réserver une revue AWS.