Tout le monde publie des diagrammes d'architecture. Personne ne publie la facture. C'est dommage, parce que la facture est l'endroit où l'architecture devient honnête : le service dont vous étiez fier se révèle une erreur d'arrondi, et la chose à laquelle vous n'avez jamais pensé est la troisième ligne.
Nous ne pouvons pas non plus publier la facture de notre client. Ce que nous pouvons faire, c'est la meilleure chose après. Ci-dessous, l'architecture que nous faisons tourner pour la plateforme d'un client américain, chiffrée ligne par ligne au prix catalogue en us-east-1 pour un mois typique, sans engagement et sans crédits. La vraie facture a le même classement et les mêmes surprises. Prenez les chiffres comme une forme, pas comme un reçu.
Ce qui tourne
Trois ingénieurs, trois comptes AWS (dev, staging, prod), tous déployés depuis une seule base de code CDK. Dans chaque compte : trois applications Next.js sur App Runner, un cluster Aurora Serverless v2 PostgreSQL, quelques tables DynamoDB, une douzaine de fonctions Lambda (certaines dans le VPC pour atteindre Aurora), des buckets S3 derrière CloudFront, un WAF devant l'application publique, CodeBuild pour les images, Secrets Manager et KMS pour tout ce qui est sensible, CloudWatch pour les logs et les alarmes. La production fait tourner deux instances App Runner chaudes pour l'application publique ; dev et staging font tout tourner à la taille minimale.
La facture
| Ligne | Mensuel (catalogue) | Part | Ce qui la détermine |
|---|---|---|---|
| App Runner (9 services sur 3 comptes) | ~190 $ | 25 % | 2 instances chaudes de 2 vCPU / 4 Go en prod ; le reste dort à la taille minimale |
| Aurora Serverless v2 (3 clusters) | ~130 $ | 17 % | plancher de 0,5 ACU en prod en continu ; dev et staging se mettent en pause seuls |
| NAT Gateway (3, un par compte) | ~100 $ | 13 % | 0,045 $ par heure chacun, avant de traiter le moindre octet |
| CloudWatch (logs, métriques, alarmes) | ~95 $ | 13 % | ~5 Go de logs par jour à 0,50 $ par Go ingéré |
| CloudFront + S3 | ~55 $ | 7 % | ~500 Go sortants, 200 Go stockés |
| DynamoDB (à la demande, PITR activé) | ~35 $ | 5 % | ~10 M d'écritures, 50 M de lectures |
| Secrets Manager (3 comptes) | ~33 $ | 4 % | 0,40 $ par secret et par mois, environ 25 secrets par compte |
| KMS (clés gérées par le client) | ~33 $ | 4 % | 1 $ par clé et par mois, environ 10 clés par compte |
| Transfert de données, inter-AZ | ~20 $ | 3 % | Lambda ↔ Aurora entre zones, plus l'egress occasionnel |
| Lambda | ~15 $ | 2 % | ~20 M d'invocations |
| CodeBuild | ~15 $ | 2 % | ~200 builds par mois, 8 minutes chacun |
| WAF | ~16 $ | 2 % | Web ACL + 5 groupes de règles managées + 10 M de requêtes |
| Route 53, ECR, SES, SQS, SNS | ~15 $ | 2 % | La longue traîne |
| Total | ~750 $ |
Quelque part entre 700 et 850 $ dans un mois normal, pour une plateforme avec de vrais utilisateurs, de l'argent réel qui y circule et trois environnements isolés. C'est moins qu'une journée d'ingénieur au tarif de conseil. Gardez ça en tête quand quelqu'un propose une semaine d'optimisation des coûts.
Les trois surprises
Le NAT Gateway est une taxe fixe pour le fait d'avoir un VPC. Nous avons des Lambdas qui parlent à Aurora, donc elles vivent dans des sous-réseaux privés, donc elles ont besoin d'un NAT pour atteindre quoi que ce soit sur Internet, y compris les API AWS. Un NAT par compte, c'est environ 33 $ par mois avant de traiter un octet. Trois comptes, trois NAT, 100 $. C'est plus que Lambda, DynamoDB et WAF réunis. La solution est partielle : les gateway endpoints pour S3 et DynamoDB sont gratuits et éliminent l'essentiel du trafic, les interface endpoints pour Secrets Manager et consorts coûtent 7 $ chacun et ne se rentabilisent qu'au-delà d'un certain volume, et en dev nous envisageons sérieusement de ne pas avoir de NAT du tout et de laisser les Lambdas qui ont besoin d'Internet échouer bruyamment.
La sécurité a un prix par compte. Secrets Manager facture par secret, KMS facture par clé, et CloudTrail veut son propre bucket. Rien de tout cela n'est cher en soi. Multiplié par trois comptes, ça fait 8 % de la facture, à peu près ce que coûte CloudFront pour servir chaque octet du produit. Nous l'avons réduit en regroupant les valeurs liées dans un seul secret JSON (un secret, plusieurs clés) au lieu d'un secret par valeur. Nous n'avons pas réduit les clés KMS : une clé par magasin de données et par compte, c'est tout l'intérêt de la configuration à trois comptes.
Les logs coûtent plus cher que les fonctions qui les écrivent. CloudWatch Logs à 0,50 $ par Go ingéré est la ligne la plus chère qui grandit avec le trafic plutôt qu'avec l'effectif. Cinq gigaoctets par jour, ce n'est rien pour trois applications qui loguent chaque requête en JSON, et c'est déjà 75 $ par mois. Nous avons réduit la rétention à 30 jours, déplacé les groupes de logs bruyants vers la classe Infrequent Access à moitié prix d'ingestion, et arrêté de loguer les corps de requêtes. La réponse à long terme, c'est de ne pas laisser CloudWatch posséder les logs applicatifs du tout.
Ce qui n'est pas une surprise mais devrait vous inquiéter
La non-production représente environ un tiers de la facture. Dev et staging sont « petits », et ils portent quand même un NAT chacun, un cluster Aurora chacun, neuf services App Runner à eux deux, et leurs propres copies de chaque secret et de chaque clé. L'auto-pause d'Aurora Serverless v2 (0 ACU en veille, depuis fin 2024) a fait passer les deux clusters non-prod d'environ 90 $ à environ 20 $. App Runner à la taille minimale, c'est 5 $ par service, ce qui va bien. Les NAT restent le problème.
Ce que nous n'optimisons volontairement pas
Nous payons tout à la demande. Pas de Savings Plans, pas de capacité réservée, pas d'instances Aurora réservées. À 750 $ par mois, l'économie maximale d'un engagement d'un an est d'environ 100 $ par mois, et la forme de la plateforme change encore : App Runner peut devenir Fargate, Aurora peut devenir un simple RDS, l'une des Lambdas peut devenir un conteneur. Un engagement est un pari que l'architecture ne bougera pas, et nous ne sommes pas prêts à le prendre. Nous y reviendrons quand la facture dépassera environ 3 000 $, là où la conversation vaut un après-midi.
Nous ne courons pas non plus après la longue traîne. Route 53, ECR, SES et SQS font 15 $ à eux tous. Toute heure passée là est une heure perdue.
Comment lire votre propre facture
Trois habitudes qui ont rendu cet exercice possible et que nous recommanderions à toute équipe de notre taille :
- Activez Cost Explorer avec une granularité horaire et taguez par environnement dès le premier jour. Chez nous, c'est un seul tag CDK,
env, appliqué au niveau du stack. Sans lui, « prod vs non-prod » est une devinette. - Regardez la facture par type d'usage, pas par service. « EC2-Other » est l'endroit où se cachent les NAT gateways. « CloudWatch » mélange ingestion, stockage et appels d'API qui ont des solutions complètement différentes.
- Mettez une alerte de budget à 120 % du mois précédent. Non pas pour économiser, mais pour apprendre un changement le troisième jour plutôt que le trentième. La nôtre s'est déclenchée deux fois : une fois pour un groupe de logs hors de contrôle, une fois pour une Lambda qui réessayait un webhook en échec chaque minute pendant une semaine.
La facture n'est pas un problème à cette taille. C'est une carte. Elle nous a dit que l'ingénierie intéressante n'est pas dans le compute que nous avons choisi, mais dans la plomberie qui est venue avec, et c'est là que vont les trois prochains articles : les NAT gateways, les logs et les engagements.
Si vous voulez un second regard sur votre propre facture, parlons-en. Nous les lisons pour vivre.