Déployer une API Python FastAPI en production sur AWS avec Lambda, SAM, Docker et GitHub Actions
Pour la majorité des APIs FastAPI modernes, Lambda + API Gateway avec des images Docker hébergées en ECR, pilotés par SAM et GitHub Actions, offrent le meilleur compromis entre coût, scalabilité et maintenance.
Pourquoi AWS pour une API Python en production
AWS fournit les primitives utiles sans forcer à réinventer l’infrastructure : Lambda pour exécuter des functions, API Gateway pour exposer des endpoints HTTPS, ECR pour stocker des images Docker, IAM pour les permissions, CloudWatch pour les logs et les métriques.
Pourquoi FastAPI est un bon choix pour une app moderne
Asynchrone, légère, s’intègre bien au runtime Python moderne. En serverless, FastAPI reste adaptée pour exposer des routes REST et valider les payloads, avec un code qui reste testable.
Ce que change le passage en production
Production implique configuration, secrets, audits IAM, pipelines de build et un plan d’observabilité. La même image ou le même package doit pouvoir passer du repository GitHub au registre ECR puis à la Lambda (ou au conteneur) avec les mêmes étapes qu’en local.
Choisir la bonne architecture : Lambda, conteneur ou Elastic Beanstalk
Trois options, selon la charge et la nature des dépendances.
Lambda et API Gateway : le modèle serverless
Lambda convient quand le trafic est variable et qu’on veut payer à l’usage. Une function charge un runtime Python, exécute la request, se termine. API Gateway expose le tout en HTTPS et gère l’authentification. SAM simplifie la déclaration des resources et des permissions associées.
Avantages : pas de serveur à maintenir, scalabilité automatique, intégration native IAM et CloudWatch. Inconvénients : cold starts, limites de durée et de taille, packaging parfois contraignant pour les dépendances lourdes.
Conteneur Docker et image dans ECR
Un conteneur dans ECR permet un contrôle complet sur le runtime. On crée un Dockerfile optimisé, on build l’image, on push vers ECR, puis on déploie cette image vers Lambda (Runtime container support) ou vers ECS. Ce modèle est adapté quand l’application dépend de bibliothèques lourdes, ou quand on a besoin d’un runtime précis.
Tableau mental rapide :
| Cas | Choix recommandé | Pourquoi |
|---|---|---|
| Dépendances légères, bursts | Lambda + API Gateway | Simplicité, coût à l’usage |
| Bibliothèques natives lourdes | Conteneur + ECR | Contrôle du runtime |
| App stateful, longue exécution | Elastic Beanstalk / ECS | Plus de contrôle, moins de contraintes serverless |
Elastic Beanstalk : dans quels cas l’utiliser
Solution viable pour des apps à charge stable qui n’ont pas besoin de toucher aux images ECR. L’abstraction masque une partie de l’infra, ce qui peut gêner dès qu’on veut customiser.
Préparer le projet FastAPI pour AWS
Structure de repository recommandée
Une structure simple et efficace :
app/: code FastAPI et routesrequirements.txtoupyproject.toml: dependencies PythonDockerfile: build local et pour ECRtemplate.yaml: template SAM.github/workflows/: workflows Actionstests/: tests unitaires et d’intégration
Conserver la configuration séparée du code évite de révéler secrets dans GitHub.
Fichiers essentiels du projet
Le fichier requirements (ou équivalent) liste les dépendances avec versions figées. Le Dockerfile produit une image légère. Le template SAM déclare la Lambda, l’API Gateway et les rôles IAM. Le workflow GitHub Actions enchaîne build, test et deploy.
Organisation du code FastAPI
Organiser les routes par module, extraire la logique métier hors des endpoints et privilégier des fonctions pures facilite les tests. Une application FastAPI prête pour production initialise la configuration via variables d’environment, charge les dépendances au démarrage et évite les imports lourds dans le handler de la function.
Requirements, dépendances et configuration de base
Privilégier des versions figées dans requirements, exécuter les tests en CI, et packager uniquement ce qui est nécessaire dans l’image. Charger les credentials AWS via le pipeline GitHub plutôt que dans le repository.
Créer l’application FastAPI et la function Lambda
Créer le handler de base
Deux chemins : un adaptateur ASGI qui monte l’app FastAPI telle quelle, ou une petite couche qui transforme l’event API Gateway en request Starlette. Le handler reste minimal : on initialise l’app FastAPI une fois, on réutilise l’instance entre invocations quand c’est possible.
Adapter FastAPI au runtime serverless
Avec un adaptateur ASGI on conserve la même application pour local et pour Lambda. Cela simplifie le code et évite des duplications. L’objectif est de réduire l’InitDuration et les cold starts en chargeant les modules essentiels au démarrage.
Gérer les routes, réponses et erreurs
Structurer les routes pour renvoyer des réponses JSON standardisées. Utiliser des exceptions métier et des handlers dédiés permet d’avoir des logs clairs dans CloudWatch.
Configurer SAM pour le déploiement de l’API
Créer le template SAM
Le template déclare la Lambda, l’API Gateway, les rôles IAM et les variables d’environnement. Utiliser des parameters pour passer le nom du repository ECR, des valeurs d’environment et des secrets rend le template réutilisable entre staging et production.
Déclarer Lambda, API Gateway et les permissions
Définir la propriété Events pour l’API Gateway qui mappe les méthodes HTTP au handler Lambda. Ajouter des policies IAM strictes pour limiter l’accès aux ressources nécessaires : DynamoDB, S3, SecretsManager, etc.
Paramétrer les variables d’environnement
Les variables d’environnement incluent le nom de la table, l’url d’un service externe, ou le flag de mode. Ne pas mettre de secrets en clair ; référencer un secret manager via IAM pour que la function récupère les credentials au runtime.
Définir les outputs et les ressources liées
Produire des outputs pour l’endpoint API Gateway, l’ARN de la Lambda et l’URL de l’image ECR aide les pipelines automatisés et les validations manuelles après deploy.
Conteneuriser l’application avec Docker et ECR
Créer le Dockerfile pour FastAPI
Un Dockerfile en plusieurs étapes permet de réduire la taille de l’image. Installer uniquement les dependencies listées dans requirements, copier le code et exposer le port utilisé par Uvicorn. Inclure une commande de santé pour faciliter les checks.
Build de l’image et optimisation
Minimiser la taille de l’image réduit les cold starts pour les Lambdas basées sur image. Supprimer caches de package, utiliser des images de base slim et regrouper les couches d’installation.
Publier l’image dans ECR
Créer le repository ECR, tagger l’image et pousser. La pipeline GitHub Actions authentifie avec des credentials limités IAM, build l’image et la push vers ECR. L’image peut ensuite être utilisée par Lambda ou ECS.
Gérer les dépendances et la taille de l’image
Externaliser les dépendances volumineuses ou recompresser les librairies natives quand c’est possible. Réévaluer si une image complète est nécessaire ou si un package zip suffit pour Lambda.
Sécuriser l’accès AWS avec IAM, secrets et permissions
Créer les rôles et politiques IAM
Définir des policies IAM qui accordent uniquement ce qui est nécessaire : accès S3, accès DynamoDB, lecture de SecretsManager. Appliquer la séparation des rôles entre build (GitHub), deploy (SAM) et runtime (Lambda).
Gérer les secrets et variables d’environnement
Utiliser un secret manager ou les variables chiffrées du pipeline GitHub. Les secrets ne doivent jamais être dans le repository. Le pipeline Actions injecte les secrets dans l’environnement de build et dans SAM lors du deploy.
Bonnes pratiques de sécurité pour GitHub et AWS
Limiter les credentials stockés dans GitHub, activer des règles de protection de branches, révoquer les tokens obsolètes et surveiller les logs CloudWatch pour détecter des usages anormaux.
Automatiser le deployment avec GitHub Actions
Créer le workflow GitHub Actions
Le workflow commence par checkout du repository, install des dependencies, exécution des tests, build de l’image Docker, push vers ECR, puis utilisation de SAM pour empaqueter et deployer la template. Les secrets AWS sont fournis via les variables chiffrées du repository.
Étapes de test, build et déploiement
Inclure des tests unitaires et un linting avant le build. Le build génère soit une image soit un artefact SAM. Le déploiement applique la template et met à jour la Lambda et l’API Gateway.
Gérer les credentials et variables du pipeline
Les credentials AWS temporaires pour Actions doivent être limités en permissions IAM. Eviter de donner un rôle trop permissif au mécanisme de deployment.
Stratégie de branches et validations avant production
Protéger la branche main, exiger des pull requests avec validation, et utiliser une branche staging pour un deploy automatique en environnement de test.
Déployer l’API en production sur AWS
Déploiement initial et vérifications
Effectuer un premier deploy sur un environnement isolé, vérifier les logs CloudWatch et tester l’endpoint. Valider l’authentification via API Gateway et les intégrations avec les ressources AWS.
Contrôler l’endpoint API Gateway
S’assurer que l’URL publique renvoie les bonnes réponses et que les headers CORS sont correctement configurés. Vérifier que les quotas et throttling répondent aux attentes.
Valider la configuration de production
Vérifier variables d’environment, versions de package, permissions IAM, et l’absence de secrets dans les outputs. Confirmer que le pipeline GitHub Actions peut redéployer de manière répétable.
Gérer les performances, les limites et les cold starts
Comprendre les quotas et la concurrence Lambda
La concurrence par défaut d’une région limite le nombre d’invocations simultanées. API Gateway a des limites de RPS. Il faut configurer les réservations de concurrency et planifier le comportement lors des pics.
Réduire les cold starts et optimiser InitDuration
Réduire la taille de l’image et optimiser les imports Python limite l’InitDuration. Préférer des libraries légères, initialiser la connexion à une base de données en mode lazy et réutiliser les ressources entre invocations.
Viser un P95 bas
Alléger le travail fait lors de l’init, cacher en mémoire ce qui peut l’être, et choisir le bon modèle (fonction courte vs conteneur) selon la latence cible.
Réduire la taille de l’image et des dépendances
Auditer les dépendances, supprimer celles non utilisées et basculer certaines fonctions vers des micro-services si une dépendance unique alourdit toute l’image.
Ajouter l’observabilité : logs, métriques et monitoring
Configurer les logs CloudWatch
Structurer les logs JSON pour faciliter les recherches. Envoyer les erreurs, les événements métier et les traces de performance vers CloudWatch.
Suivre les métriques de performance et d’erreur
Suivre latence, taux d’erreur, cold starts et throttles. Créer des dashboards centrés sur l’endpoint et sur la function Lambda pour détecter rapidement les régressions après chaque build.
Mettre en place des alertes utiles
Définir des alertes pour taux d’erreur élevé, augmentation de latence, ou saturation des quotas. Une alerte pertinente déclenche une investigation, pas immédiatement une escalation.
Checklist de mise en production et bonnes pratiques finales
Checklist avant le premier deploy
- Valider le build local et les tests unitaires
- S’assurer que les secrets sont gérés hors du repository
- Vérifier les policies IAM minimales
- Mettre en place le pipeline GitHub Actions
- Tagger la version de l’image et pousser sur ECR
Checklist sécurité et configuration
Assigner des rôles différents pour build et runtime, vérifier les ACL et revues de permissions IAM, configurer le Secret Manager et activer les logs CloudWatch.
Checklist tests et validation
Inclure des smoke tests sur l’endpoint, des tests d’intégration pour les accès DB, et un plan de rollback via SAM ou via le tag d’image dans ECR.
Erreurs fréquentes et troubleshooting
Les problèmes courants incluent une policy IAM trop restrictive ou trop permissive, un template SAM mal configuré, une image Docker trop lourde, des variables d’environment manquantes. Premier réflexe quand un deploy échoue : lire les logs CloudWatch et vérifier les permissions du rôle de déploiement.
Côté permissions, deux causes dominent : rôle IAM non attaché à la Lambda, ou token GitHub Actions avec des droits insuffisants pour push sur ECR. C’est toujours la chaîne GitHub → IAM → SAM qu’il faut dérouler.
Questions fréquentes
Quelle est la différence entre déployer une API en Lambda ou avec un conteneur ?
Lambda est serverless et facture à l’usage, idéal pour des endpoints stateless et des pulsations de trafic. Un conteneur offre un contrôle complet du runtime et convient si l’image contient des dépendances natives ou si la durée d’exécution est longue.
Faut-il prendre SAM ou un autre outil IaC pour deploy sur AWS ?
SAM simplifie la déclaration des functions et d’API Gateway et s’intègre bien avec les workflows de build et deploy. Si vous préférez du multi-cloud, un autre framework IaC peut être adapté.
Comment réduire les cold starts d’une API FastAPI sur Lambda ?
Réduire la taille de l’image, limiter les imports au démarrage, utiliser un runtime allégé et optimiser les dependencies réduit l’InitDuration et les cold starts.
Votre recommandation sur déployer api python en production sur aws
Quelques questions rapides pour adapter la recommandation à votre cas.