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 :

CasChoix recommandéPourquoi
Dépendances légères, burstsLambda + API GatewaySimplicité, coût à l’usage
Bibliothèques natives lourdesConteneur + ECRContrôle du runtime
App stateful, longue exécutionElastic Beanstalk / ECSPlus 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 routes
  • requirements.txt ou pyproject.toml : dependencies Python
  • Dockerfile : build local et pour ECR
  • template.yaml : template SAM
  • .github/workflows/ : workflows Actions
  • tests/ : 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.

Quiz personnalisé

Votre recommandation sur déployer api python en production sur aws

Quelques questions rapides pour adapter la recommandation à votre cas.

Q1 Votre situation sur déployer api python en production sur aws ?
Q2 Votre priorité ?
Q3 Votre horizon ?