Lambda vers RDS privé : configuration VPC, sous-réseaux et groupes de sécurité
Vous avez déployé une fonction Lambda et une instance RDS dans un sous-réseau privé, mais la connexion échoue silencieusement — timeout après 30 secondes, aucun message d'erreur applicatif, juste un délai d'attente. Ce scénario est l'un des plus fréquents en production AWS, et la cause racine est presque toujours une mauvaise compréhension de la façon dont Lambda s'intègre au réseau VPC.
TL;DR — Lambda vers RDS privé
| Point clé | Détail |
|---|---|
| Configuration VPC obligatoire | Sans configuration VPC sur la fonction Lambda, elle s'exécute dans le réseau AWS géré et ne peut pas atteindre vos ressources privées. |
| Sous-réseaux privés | Attachez Lambda aux mêmes sous-réseaux privés (ou à des sous-réseaux avec routage vers RDS) que votre instance RDS. |
| Groupes de sécurité | Le groupe de sécurité de RDS doit autoriser le trafic entrant depuis le groupe de sécurité de Lambda sur le port de la base de données. |
| Accès Internet depuis Lambda-VPC | Une Lambda dans un VPC perd l'accès Internet par défaut — un NAT Gateway est nécessaire pour les appels externes. |
| Permissions IAM | Le rôle d'exécution Lambda doit inclure les permissions ec2:CreateNetworkInterface, ec2:DescribeNetworkInterfaces, ec2:DeleteNetworkInterface. |
Comment Lambda s'intègre au VPC
Par défaut, une fonction Lambda s'exécute dans un environnement réseau géré par AWS, complètement isolé de votre VPC. Elle peut appeler des API AWS publiques et Internet, mais elle ne voit pas vos ressources privées — RDS, ElastiCache, instances EC2 dans des sous-réseaux privés. Pour changer ce comportement, vous devez explicitement attacher la fonction à votre VPC.
Quand vous activez la configuration VPC sur une Lambda, AWS crée une interface réseau élastique (ENI) dans chaque sous-réseau que vous spécifiez. Cette ENI est le point d'entrée réseau de la fonction dans votre VPC. La fonction reçoit une adresse IP privée dans ces sous-réseaux et peut alors atteindre les ressources réseau comme n'importe quelle autre ressource VPC.
Pensez à la configuration VPC de Lambda comme à brancher un câble réseau virtuel entre l'environnement d'exécution Lambda et votre VPC. Sans ce câble, les deux réseaux sont complètement séparés.
Un point souvent mal compris : attacher Lambda à un sous-réseau privé sans NAT Gateway supprime l'accès Internet de la fonction. Si votre code appelle des API externes ou des services AWS via endpoints publics, vous aurez besoin soit d'un NAT Gateway dans un sous-réseau public, soit de VPC Endpoints pour les services AWS concernés.
- Sans VPC : Lambda s'exécute dans le réseau AWS géré, accès Internet direct, aucune visibilité sur les ressources VPC privées.
- Avec VPC : Lambda crée une ENI dans vos sous-réseaux privés, obtient une IP privée, et peut atteindre RDS.
- NAT Gateway : Nécessaire uniquement si Lambda doit accéder à Internet depuis un sous-réseau privé.
- VPC Endpoint : Alternative au NAT pour les appels vers les services AWS (S3, Secrets Manager, etc.).
Diagnostic : pourquoi la connexion Lambda vers RDS échoue
Avant de corriger, il faut identifier la couche exacte du problème. Un timeout de connexion et un refus de connexion n'ont pas la même cause — confondre les deux mène à des heures de débogage inutiles.
Étape 1 — Vérifier si Lambda est bien attachée au VPC
C'est la vérification la plus basique, mais elle est souvent ignorée. Si la fonction n'a aucune configuration VPC, toutes les autres vérifications sont inutiles.
aws lambda get-function-configuration \
--function-name nom-de-votre-fonction \
--query 'VpcConfig' \
--region us-east-1
Si la réponse retourne SubnetIds: [] et SecurityGroupIds: [], la fonction n'est pas dans votre VPC. C'est la cause racine.
Étape 2 — Vérifier les sous-réseaux configurés
Même avec une configuration VPC présente, si les sous-réseaux ne permettent pas d'atteindre RDS (mauvaise AZ, table de routage incorrecte), la connexion échouera. Vérifiez que les sous-réseaux de Lambda ont une route vers les sous-réseaux de RDS — dans la plupart des architectures, ils partagent les mêmes sous-réseaux privés.
aws lambda get-function-configuration \
--function-name nom-de-votre-fonction \
--query 'VpcConfig.SubnetIds' \
--region us-east-1
aws rds describe-db-instances \
--db-instance-identifier votre-instance-rds \
--query 'DBInstances[0].DBSubnetGroup.Subnets[*].SubnetIdentifier' \
--region us-east-1
Comparez les résultats. Lambda n'a pas besoin d'être dans exactement les mêmes sous-réseaux que RDS, mais le routage entre eux doit exister. Pour simplifier, utiliser les mêmes sous-réseaux privés est la pratique la plus courante.
Étape 3 — Auditer les règles des groupes de sécurité
C'est là que la majorité des problèmes se cachent. Le groupe de sécurité attaché à RDS doit explicitement autoriser le trafic entrant depuis le groupe de sécurité de Lambda. Un timeout sans message d'erreur applicatif est presque toujours un blocage au niveau du groupe de sécurité ou des ACL réseau.
aws ec2 describe-security-groups \
--group-ids sg-XXXXXXXX \
--query 'SecurityGroups[0].IpPermissions' \
--region us-east-1
Récupérez d'abord le groupe de sécurité de RDS :
aws rds describe-db-instances \
--db-instance-identifier votre-instance-rds \
--query 'DBInstances[0].VpcSecurityGroups[*].VpcSecurityGroupId' \
--region us-east-1
Dans les règles entrantes du groupe de sécurité RDS, cherchez une règle qui autorise le port de la base de données (3306 pour MySQL, 5432 pour PostgreSQL) avec comme source le groupe de sécurité de Lambda (référencé par son ID, pas par une plage CIDR). Référencer le SG de Lambda directement est plus robuste qu'une plage IP, car les IPs des ENI Lambda peuvent changer.
- Le groupe de sécurité Lambda contrôle le trafic sortant de la fonction.
- Le groupe de sécurité RDS contrôle le trafic entrant vers l'instance.
- La règle critique est sur le SG RDS : autoriser le port DB depuis le SG Lambda.
- Sans cette règle, les paquets sont silencieusement abandonnés — d'où le timeout.
Étape 4 — Vérifier les permissions IAM du rôle d'exécution
Lambda a besoin de permissions pour créer et gérer les ENIs dans votre VPC. Sans ces permissions, l'attachement VPC échoue au déploiement ou au démarrage de la fonction. AWS fournit la politique gérée AWSLambdaVPCAccessExecutionRole qui couvre exactement ces permissions.
aws iam list-attached-role-policies \
--role-name nom-du-role-execution-lambda \
--query 'AttachedPolicies[*].PolicyName'
Si AWSLambdaVPCAccessExecutionRole n'est pas listée, vérifiez les politiques inline pour les permissions ec2:CreateNetworkInterface, ec2:DescribeNetworkInterfaces, et ec2:DeleteNetworkInterface. Ces trois permissions sont le minimum requis.
Étape 5 — Vérifier les ACL réseau des sous-réseaux
Les groupes de sécurité sont stateful — si le trafic sortant est autorisé, la réponse rentre automatiquement. Les ACL réseau sont stateless — vous devez explicitement autoriser le trafic dans les deux sens. Si vos sous-réseaux ont des ACL réseau personnalisées, elles peuvent bloquer le trafic même si les groupes de sécurité sont corrects.
aws ec2 describe-network-acls \
--filters Name=association.subnet-id,Values=subnet-XXXXXXXX \
--query 'NetworkAcls[0].Entries' \
--region us-east-1
Vérifiez que les règles entrantes et sortantes autorisent le trafic sur le port de la base de données entre les sous-réseaux Lambda et RDS. Les ACL par défaut autorisent tout le trafic — ce problème n'apparaît que si des ACL personnalisées ont été configurées.
CLI examples omitted for steps N, M — aucune omission dans ce cas, tous les exemples CLI sont présents.
Configuration Lambda VPC — procédure complète
1. Attacher Lambda au VPC via la console ou CLI
aws lambda update-function-configuration \
--function-name nom-de-votre-fonction \
--vpc-config SubnetIds=subnet-aaa111,subnet-bbb222,SecurityGroupIds=sg-lambda-XXXXXX \
--region us-east-1
Spécifiez au moins deux sous-réseaux dans des zones de disponibilité différentes pour la résilience. Lambda créera des ENIs dans chaque sous-réseau spécifié.
2. Créer la règle de sécurité sur RDS
aws ec2 authorize-security-group-ingress \
--group-id sg-rds-YYYYYYYY \
--protocol tcp \
--port 5432 \
--source-group sg-lambda-XXXXXX \
--region us-east-1
Remplacez le port 5432 par le port correspondant à votre moteur de base de données. Cette règle dit : 'autorise le trafic TCP sur le port 5432 provenant de toute ressource attachée au groupe de sécurité Lambda'.
3. Attacher la politique IAM au rôle d'exécution
aws iam attach-role-policy \
--role-name nom-du-role-execution-lambda \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
4. Politique IAM minimale si vous préférez une politique inline
🔽 Cliquer pour afficher la politique IAM minimale
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/*"
}
]
}
Notez que ec2:CreateNetworkInterface, ec2:DescribeNetworkInterfaces, et ec2:DeleteNetworkInterface requièrent "Resource": "*" — ces actions ne supportent pas la restriction au niveau de la ressource dans le Service Authorization Reference AWS.
Le piège classique : symptôme trompeur en production
Voici un scénario réel. La fonction Lambda était correctement attachée au VPC, les groupes de sécurité semblaient corrects, mais les connexions à RDS timeoutaient de façon intermittente — pas systématiquement, seulement sous charge.
Le diagnostic initial pointait vers un problème de pool de connexions ou de limites RDS. Après investigation, la vraie cause : Lambda était configurée avec un seul sous-réseau dans une seule zone de disponibilité. Sous charge, AWS créait de nouvelles ENIs pour les nouvelles instances d'exécution Lambda, et l'espace d'adressage IP du sous-réseau était épuisé. Les nouvelles invocations ne pouvaient pas obtenir d'ENI, donc pas de connexion réseau.
La correction : ajouter des sous-réseaux dans deux autres zones de disponibilité, augmentant ainsi le pool d'adresses IP disponibles. La règle pratique est de dimensionner vos sous-réseaux Lambda avec suffisamment d'IPs pour couvrir le nombre maximum d'exécutions simultanées attendues, plus une marge confortable.
Un sous-réseau /28 (16 IPs, 11 utilisables) est insuffisant pour une fonction Lambda à fort trafic. Préférez des /24 ou /22 pour les sous-réseaux dédiés aux ENIs Lambda.
Architecture recommandée
- Sous-réseaux privés Lambda : dédiés aux ENIs Lambda, dimensionnés généreusement (/22 recommandé).
- Sous-réseaux privés RDS : isolés, accessibles uniquement depuis les SGs autorisés.
- NAT Gateway : dans le sous-réseau public, pour que Lambda puisse atteindre Internet ou les endpoints AWS publics si nécessaire.
- VPC Endpoints : alternative au NAT pour Secrets Manager, S3, et autres services AWS — réduit les coûts de transfert et améliore la sécurité.
- Secrets Manager : stockage recommandé pour les credentials RDS, accessible via VPC Endpoint sans passer par Internet.
Vérification finale — tester la connectivité
Après avoir appliqué la configuration, testez avec une invocation Lambda simple qui tente une connexion TCP sur le port de la base de données. Si vous utilisez Python, le module socket suffit pour un test de connectivité réseau avant d'introduire un driver de base de données dans l'équation.
import socket
import os
def lambda_handler(event, context):
host = os.environ['DB_HOST']
port = int(os.environ['DB_PORT'])
try:
sock = socket.create_connection((host, port), timeout=5)
sock.close()
return {'statusCode': 200, 'body': 'Connexion TCP reussie'}
except socket.timeout:
return {'statusCode': 500, 'body': 'Timeout - verifier SG et routage'}
except ConnectionRefusedError:
return {'statusCode': 500, 'body': 'Connexion refusee - RDS accessible mais port ferme'}
Un timeout indique un problème de groupe de sécurité ou de routage. Un ConnectionRefusedError signifie que le réseau fonctionne mais que le port est fermé — ce qui est en réalité un bon signe pour le diagnostic réseau.
Lambda vers RDS privé — récapitulatif et prochaines étapes
La connexion Lambda vers RDS dans un sous-réseau privé nécessite trois éléments alignés : la configuration VPC sur la fonction Lambda (sous-réseaux et groupe de sécurité), une règle entrante sur le groupe de sécurité RDS autorisant le SG Lambda sur le port de la base de données, et les permissions IAM pour la gestion des ENIs. Si l'un de ces trois éléments manque, la connexion échoue.
Pour aller plus loin :
- Documentation officielle — Lambda dans un VPC
- Groupes de sécurité RDS
- Envisagez RDS Proxy pour gérer le pool de connexions et réduire la pression sur RDS lors de pics d'invocations Lambda simultanées.
- Utilisez AWS Secrets Manager avec un VPC Endpoint pour récupérer les credentials RDS sans exposer le trafic à Internet.
Glossaire
| Terme | Définition |
|---|---|
| ENI (Elastic Network Interface) | Interface réseau virtuelle créée par Lambda dans vos sous-réseaux VPC pour permettre la connectivité réseau privée. |
| Groupe de sécurité | Pare-feu stateful au niveau de la ressource dans AWS VPC, contrôlant le trafic entrant et sortant. |
| ACL réseau | Pare-feu stateless au niveau du sous-réseau, évalué avant les groupes de sécurité. |
| NAT Gateway | Service géré permettant aux ressources dans des sous-réseaux privés d'initier des connexions vers Internet sans être directement accessibles depuis Internet. |
| VPC Endpoint | Connexion privée entre votre VPC et les services AWS, sans passer par Internet ni par un NAT Gateway. |
Commentaires
Enregistrer un commentaire