Comment une petite équipe fait tourner ses propres produits SaaS
Chez Tadata, nous conseillons nos clients sur leurs plateformes cloud, et nous exploitons aussi nos propres produits : memo, l'application de notes PDF, et les autres applications réunies sur waiyers.com. Cet article décrit une architecture qu'une petite équipe peut réellement opérer, et les leçons qui nous ont coûté du temps ou de l'argent.
La pile en un coup d'œil
| Couche | Choix | Pourquoi |
|---|---|---|
| Cloud | AWS, région de Paris | Données en France, proches des utilisateurs, services managés matures |
| Calcul | Un seul cluster Amazon EKS | Un seul plan de contrôle à payer et à mettre à jour |
| Packaging | Charts Helm | Un chart par service, des valeurs par environnement |
| Déploiement | Argo CD (GitOps) | Le cluster converge vers ce que dit Git |
| Développement local | Skaffold sur un cluster k3s local | Les mêmes manifestes en local et dans le cloud |
| CI/CD | GitHub Actions | main → test, tag de version → prod |
| Connexion | Zitadel (OIDC), avec Google comme fournisseur d'identité | Une seule connexion pour tous les produits, OIDC standard |
| Backends | Python FastAPI (HTTP) + services gRPC | FastAPI pour les API publiques, gRPC entre services |
| Code partagé | Paquets Python et npm dans un registre privé (AWS CodeArtifact) | Des bibliothèques versionnées plutôt que du copier-coller |
| Sites vitrines | Sites statiques | Peu coûteux, rapides, rien à patcher |
| Secrets | Un gestionnaire de secrets cloud, synchronisé dans le cluster | Aucun secret dans Git ni dans les images |
| Suivi des coûts | OpenCost | Coût par namespace et par produit |
Un cluster, plusieurs produits
Tout tourne dans un seul cluster EKS, avec un namespace par produit et par environnement. Un plan de contrôle managé est facturé à l'heure par cluster, et chaque cluster apporte ses propres add-ons, mises à jour et supervision. Pour une petite équipe, un deuxième cluster double le travail d'exploitation bien avant d'apporter le moindre bénéfice.
L'isolation repose sur les namespaces, les network policies, les quotas de ressources et des comptes de service distincts aux droits cloud restreints. Voir Patterns Kubernetes pour les briques de base.
Extrait de la fiche « GitOps and Argo CD for Model Serving » · Demander la fiche complète
GitOps avec Helm et Argo CD
Chaque service a son chart Helm ; chaque environnement a son fichier de valeurs. Argo CD surveille le dépôt Git et applique les changements. Personne ne lance kubectl apply sur la test ou la prod.
| Bénéfice | En pratique |
|---|---|
| Traçabilité | Chaque modification du cluster est un commit |
| Retour arrière | On annule le commit ; Argo CD reconverge |
| Détection des dérives | Les modifications manuelles apparaissent « out of sync » |
| Reprise | Un nouveau cluster se reconstruit à partir de Git |
Plus de détails dans Patterns GitOps.
Extrait de la fiche « GitOps and Argo CD for Model Serving » · Demander la fiche complète
Le local d'abord : Skaffold sur k3s
Les développeurs font tourner toute la pile sur leur portable avec k3s (un Kubernetes léger) et Skaffold, qui construit les images, déploie les mêmes charts Helm avec des valeurs locales et synchronise les modifications de code dans les pods en cours d'exécution. Les paquets Python partagés sont montés dans les pods pendant le développement : une modification de bibliothèque est visible immédiatement, sans publier de nouvelle version.
L'avantage : « ça marche sur ma machine » signifie « ça marche avec les mêmes manifestes qu'en production ». Le prix : une installation plus lourde qu'un docker compose, que nous acceptons parce que les charts sont testés tous les jours.
CI/CD : deux règles
| Événement | Résultat |
|---|---|
Merge sur main | Build des images, push, mise à jour des valeurs de test → Argo CD déploie en test |
Push d'un tag de version (v1.4.0) | Promotion des mêmes images en prod |
Les images sont construites une fois puis promues, jamais reconstruites par environnement. Une mise en production est un acte délibéré (un tag), pas un effet de bord d'un merge. Détails dans Bonnes pratiques CI/CD.
Connexion : OIDC partout
Tous les produits utilisent Zitadel comme fournisseur OIDC, avec Google comme fournisseur d'identité en amont. Chaque application est un client OIDC standard ; aucune ne stocke de mot de passe. Ajouter un produit, c'est enregistrer un client, pas développer une page de connexion. Les organisations Zitadel correspondent naturellement aux équipes des applications collaboratives.
code_verifier aléatoire (43 à 128 caractères) et envoie code_challenge = BASE64URL(SHA256(verifier)) avec code_challenge_method=S256, state et nonce. Le code est à usage unique (10 minutes au plus) et ne part que vers la redirect_uri exacte enregistrée ; le client vérifie state. Sur /token, l'AS recalcule le challenge à partir du verifier : un code volé seul est inutile ; le client s'authentifie par un secret, private_key_jwt ou mTLSExtrait de la fiche « Identity Protocols: OAuth, OIDC, SAML, FIDO2 » · Demander la fiche complète
Backends et paquets
Les backends sont en Python : FastAPI pour les API HTTP utilisées par les applications web et mobiles, gRPC pour les appels entre services lorsque les contrats typés et le streaming comptent. La logique métier vit dans des paquets versionnés publiés dans un registre privé (AWS CodeArtifact), pour Python et npm. Les services sont minces : ils importent des paquets, câblent la configuration et exposent des endpoints.
| Pratique | Pourquoi |
|---|---|
| Logique dans les paquets, services minces | Le même code tourne dans une API, un worker ou une CLI |
| Versions sémantiques, publiées par la CI | Les services fixent ce qu'ils utilisent ; les montées de version sont explicites |
| Aucun chemin local inter-dépôts dans les builds de production | Des builds reproductibles sur n'importe quelle machine |
Les leçons
1. Garder un seul cluster
Voir plus haut. Ne scinder que lorsqu'une contrainte forte (conformité, locataire bruyant, région) l'impose.
2. Des environnements peu coûteux au repos
Un environnement de test allumé en permanence coûte presque autant que la production. Le nôtre est conçu pour être détruit puis recréé à partir de Terraform et de Git quand personne ne teste. Les vraies économies ne portaient pas que sur les nœuds :
| Poste | Leçon |
|---|---|
| Passerelles NAT | Facturées à l'heure et au Go ; souvent la ligne surprise d'une petite facture |
| Load balancers | Un par ingress, ça s'additionne ; mutualisez un contrôleur d'ingress |
| Bases managées | Arrêtez ou supprimez les instances de test ; restaurez depuis un snapshot au besoin |
| Adresses IPv4 publiques | Facturées une à une chez AWS |
Gardez ce qui est long à recréer et coûte peu (DNS, secrets, registres d'images) ; détruisez ce qui se recrée vite et coûte cher.
3. Les secrets vivent dans un gestionnaire de secrets
Les secrets sont stockés dans un gestionnaire de secrets managé et synchronisés dans le cluster. Ils ne passent jamais par Git, les images ou les logs de CI. Un code d'infrastructure qui écrit des secrets ne doit jamais être appliqué sans ses valeurs d'entrée, sous peine d'écraser les vrais secrets par des valeurs vides : une erreur facile à commettre une fois. Voir Gestion des secrets.
4. Suivre le coût par produit dès le premier jour
OpenCost répartit le coût du cluster par namespace, donc par produit et par environnement. « La facture AWS a augmenté » devient « la test du produit X a doublé ses demandes de mémoire la semaine dernière ». Complétez avec les tags de facturation cloud pour ce qui vit hors du cluster. Notre comparateur de prix cloud aide à vérifier si une ligne reste dans la norme.
5. Construire une plateforme, mais petite
Une petite équipe n'a pas besoin d'une plateforme interne complète. Il lui faut une voie balisée : un modèle de chart, un workflow de CI, une façon de se connecter, une façon de publier un paquet. Voir Platform Engineering.
Ce que nous referions
| Décision | Verdict |
|---|---|
| Un seul cluster | Oui |
| GitOps dès le départ | Oui : la reprise et l'audit viennent gratuitement |
| Kubernetes local plutôt que compose | Oui, avec une bonne configuration Skaffold |
| Mises en production par tag | Oui |
| Détruire la test au repos | Oui : la plus grosse économie au regard de l'effort |
| Un fournisseur OIDC dédié plutôt qu'une authentification maison | Oui |