xpeditis2.0/docs/deployment/AWS_COSTS_KUBERNETES.md
2026-03-26 18:08:28 +01:00

22 KiB
Raw Permalink Blame History

Estimation des Coûts AWS — Déploiement Production Kubernetes (EKS)

Document de référence — Xpeditis 2.0 Région cible : us-east-1 (ou eu-west-1 pour conformité RGPD) Base tarifaire : AWS on-demand, mars 2026 MinIO remplacé par S3


Table des matières

  1. Architecture cible sur EKS
  2. Inventaire des composants analysés
  3. Hypothèses par palier d'utilisateurs
  4. Détail des coûts — 100 utilisateurs
  5. Détail des coûts — 1 000 utilisateurs
  6. Détail des coûts — 10 000 utilisateurs
  7. Tableau récapitulatif
  8. Économies avec Reserved Instances
  9. Facteurs de risque et dépassements potentiels
  10. Recommandations d'optimisation
  11. Architecture Kubernetes recommandée

1. Architecture cible sur EKS

                          ┌─────────────────────────────────────────────┐
                          │               AWS VPC (Multi-AZ)            │
                          │                                             │
  Internet ──── Route53 ──┤── CloudFront ──── ALB ──┬── NestJS Pods    │
                          │                         │   (EKS NodeGroup) │
                          │                         └── Next.js Pods    │
                          │                                             │
                          │   ┌──────────┐  ┌──────────┐  ┌─────────┐ │
                          │   │ RDS PG15 │  │ElastiCache│  │   S3    │ │
                          │   │ Multi-AZ │  │  Redis7  │  │ Bucket  │ │
                          │   └──────────┘  └──────────┘  └─────────┘ │
                          │                                             │
                          │   ┌──────────┐  ┌──────────┐              │
                          │   │  SES     │  │Secrets   │              │
                          │   │  Email   │  │Manager   │              │
                          │   └──────────┘  └──────────┘              │
                          └─────────────────────────────────────────────┘

Services AWS utilisés :

Service AWS Remplace / Rôle
EKS Orchestration des containers (backend NestJS + frontend Next.js)
RDS PostgreSQL 15 Base de données principale (18 tables, 29 migrations)
ElastiCache Redis 7 Cache des rate quotes (TTL 15 min), pub/sub WebSocket
S3 Remplace MinIO — PDFs, documents carrier, exports CSV/Excel
ALB Load balancer HTTPS + WebSocket (sticky sessions)
CloudFront CDN pour assets frontend et PDFs publics
SES 10 types d'emails transactionnels (confirmations, invitations, magic links)
Secrets Manager JWT secret, DB passwords, API keys carriers (5 carriers)
Route 53 DNS
CloudWatch Logs (nestjs-pino), métriques, alertes
WAF Protection OWASP (Rate limiting déjà implémenté dans NestJS)
NAT Gateway Accès internet pour les pods (appels APIs carriers)

2. Inventaire des composants analysés

Backend NestJS (charges identifiées)

Endpoints critiques en charge :

  • POST /api/v1/rates/search — appelle 5 carriers APIs en parallèle (Maersk, MSC, CMA CGM, Hapag-Lloyd, ONE) avec circuit breaker 5s timeout. C'est le endpoint le plus coûteux en compute.
  • GET /api/v1/rates/csv-search — filtrage in-memory de fichiers CSV uploadés
  • WebSocket /notifications — connexions persistantes Socket.IO, pub/sub via Redis

Redis (ElastiCache) :

  • Clés : rate:{origin}:{destination}:{containerType} — TTL 15 minutes
  • Taux de cache hit estimé : 7090% pendant les heures de bureau
  • Pas de cluster mode nécessaire avant ~500 utilisateurs actifs simultanés

Base de données (RDS) :

  • 18 tables avec indexes composites
  • Tables à forte croissance : bookings, audit_logs, notifications, rate_quotes
  • audit_logs peut grossir très vite (~50200K lignes/mois à 1 000 users)
  • Extensions PostgreSQL : pg_trgm (recherche textuelle sur ports)

S3 (remplace MinIO) :

  • PDFs booking : 100500 KB/document, 1 par booking + exports
  • Documents carrier : jusqu'à 10 MB/fichier (PDF, images, Excel, CSV)
  • Logos d'organisations
  • Exports CSV/Excel des bookings

Emails (SES) :

  1. Vérification email à l'inscription
  2. Mot de passe oublié / reset
  3. Email de bienvenue
  4. Invitation d'utilisateur (token 1h)
  5. Confirmation de booking avec PDF en pièce jointe
  6. Demande CSV booking au carrier (magic link)
  7. Création compte carrier
  8. Reset password carrier
  9. Notification nouveaux documents
  10. Alerte accès documents

Appels APIs externes :

  • 5 carriers APIs consultées à chaque rate search non mis en cache
  • Latence estimée : 13 secondes par carrier
  • Volume estimé : 1030% des searches frappent les APIs (le reste vient du cache Redis)

Frontend Next.js (charges identifiées)

  • Mode standalone — container Docker autonome avec Node.js
  • SSR / SSG hybride — pages dashboard en CSR, landing page statique
  • Bundle gzippé estimé : 200400 KB (React 19 + Shadcn/ui + TanStack Query)
  • Leaflet (cartes), Recharts (graphiques), Framer Motion (animations)
  • Images optimisées via next/image avec support S3 (**.amazonaws.com)

3. Hypothèses par palier d'utilisateurs

Paramètre 100 users 1 000 users 10 000 users
Utilisateurs actifs simultanés (pic) 1020 100300 1 0003 000
Rate searches / jour 200500 2 0008 000 20 00080 000
Bookings créés / mois 2050 300800 3 0008 000
Connexions WebSocket simultanées 1020 100300 1 0003 000
Emails / mois 200500 5 00020 000 50 000200 000
Volume S3 total 520 GB 100300 GB 13 TB
Upload S3 / mois 15 GB 2050 GB 200500 GB
Trafic sortant APIs carriers / mois 520 GB 100300 GB 13 TB
Lignes audit_logs cumulées < 50K < 1M < 20M

4. Détail des coûts — 100 utilisateurs

Phase early-stage / MVP. Architecture sans Multi-AZ sur certains composants pour réduire les coûts.

Compute — EKS

Ressource Config Coût/mois
EKS Control Plane 1 cluster $73
Worker nodes 2× t3.medium (2 vCPU, 4 GB) — backend + frontend $61
Total compute $134

Pods : 2 replicas NestJS (500m CPU / 512Mi chacun) + 1 replica Next.js (250m CPU / 256Mi). HPA désactivé à ce stade.

Base de données — RDS PostgreSQL

Ressource Config Coût/mois
Instance db.t4g.medium (2 vCPU, 4 GB) — Single-AZ $60
Stockage 20 GB gp3 $2
Backups 7 jours retention $2
Total RDS $64

Cache — ElastiCache Redis

Ressource Config Coût/mois
Instance cache.t4g.micro (1 nœud, 0.5 GB) $12

Suffisant pour ~10 000 clés rate quotes en cache. Pas de réplication à ce stade.

Stockage — S3

Ressource Volume Coût/mois
Stockage standard 10 GB $0.23
Requêtes PUT/GET ~50 000/mois $0.50
Transfert sortant 5 GB $0.45
Total S3 ~$2

Réseau

Ressource Config Coût/mois
ALB 1 load balancer, ~5 LCU $22
NAT Gateway 1 NAT, ~20 GB data processing $34
CloudFront Distribution basique, ~5 GB transfert $5
Total réseau $61

Services managés

Ressource Usage Coût/mois
SES ~500 emails (dont ~50 avec PDF joint ~250 KB) $1
Secrets Manager 12 secrets $5
Route 53 1 hosted zone + queries $2
CloudWatch Logs 5 GB/mois + métriques de base $15
Total services $23

Total Tier 1 — 100 utilisateurs

Catégorie Coût/mois
Compute (EKS) $134
RDS PostgreSQL $64
ElastiCache Redis $12
S3 $2
Réseau (ALB + NAT + CloudFront) $61
Services (SES + Secrets + R53 + CloudWatch) $23
TOTAL ~$296/mois
Avec buffer 15% ~$340/mois

5. Détail des coûts — 1 000 utilisateurs

Phase croissance. Multi-AZ activé sur RDS, Redis répliqué, autoscaling EKS.

Compute — EKS

Ressource Config Coût/mois
EKS Control Plane 1 cluster $73
Worker nodes 3× t3.xlarge (4 vCPU, 16 GB) — autoscaling 36 nodes $362
Total compute $435

Pods : 4 replicas NestJS (1 CPU / 1 GB chacun) + 2 replicas Next.js. HPA activé (CPU > 70%).

Base de données — RDS PostgreSQL

Ressource Config Coût/mois
Instance db.r6g.large (2 vCPU, 16 GB) — Multi-AZ $350
Stockage 100 GB gp3 $10
RDS Proxy Connection pooling (critique pour NestJS) $36
Backups 30 jours retention $20
Total RDS $416

RDS Proxy devient essentiel à partir de ~50 connexions concurrentes pour éviter les too many connections.

Cache — ElastiCache Redis

Ressource Config Coût/mois
Instance cache.r6g.large (2 nœuds, 13 GB) — réplication activée $242

La réplication est nécessaire pour le pub/sub WebSocket multi-pods (Socket.IO scale-out).

Stockage — S3

Ressource Volume Coût/mois
Stockage standard 150 GB $3.45
Stockage Intelligent-Tiering (archives) 50 GB $2.50
Requêtes PUT/GET ~500 000/mois $3
Transfert sortant 50 GB $4.50
Total S3 ~$13

Réseau

Ressource Config Coût/mois
ALB 1 load balancer, ~50 LCU $38
NAT Gateway 2 NATs (HA Multi-AZ), ~150 GB data $73
CloudFront ~50 GB transfert (assets + PDFs) $25
Total réseau $136

Services managés

Ressource Usage Coût/mois
SES ~15 000 emails/mois $1.50
SES — pièces jointes PDF ~300 bookings × 250 KB $0.10
Secrets Manager 15 secrets $6
Route 53 1 zone + queries $3
CloudWatch Logs 20 GB/mois + métriques + dashboards $50
WAF 1 WebACL, 5 rules, ~5M requêtes/mois $12
Total services $73

Total Tier 2 — 1 000 utilisateurs

Catégorie Coût/mois
Compute (EKS) $435
RDS PostgreSQL (Multi-AZ + Proxy) $416
ElastiCache Redis (répliqué) $242
S3 $13
Réseau (ALB + NAT + CloudFront) $136
Services (SES + Secrets + R53 + CW + WAF) $73
TOTAL ~$1 315/mois
Avec buffer 15% ~$1 512/mois

6. Détail des coûts — 10 000 utilisateurs

Phase scale. Read replica RDS, Redis cluster mode, autoscaling agressif, WAF renforcé.

Compute — EKS

Ressource Config Coût/mois
EKS Control Plane 1 cluster $73
Worker nodes — backend 4× m6i.xlarge (4 vCPU, 16 GB) — autoscaling 412 $560
Worker nodes — frontend 2× m6i.large (2 vCPU, 8 GB) — autoscaling 26 $140
Total compute $773

Pods NestJS : 815 replicas (1.5 CPU / 1.5 GB chacun). HPA + KEDA si adoption de SQS. Pods Next.js : 48 replicas (500m CPU / 512 Mi chacun).

Base de données — RDS PostgreSQL

Ressource Config Coût/mois
Instance primaire db.r6g.2xlarge (8 vCPU, 64 GB) — Multi-AZ $1 402
Read Replica db.r6g.xlarge (analytics + audit queries) $350
Stockage 1 TB gp3 (SSD) $100
RDS Proxy Haute disponibilité $100
Backups 30 jours + point-in-time recovery $100
Total RDS $2 052

À 10 000 users, audit_logs peut dépasser 10M lignes. Envisager un archivage vers S3/Athena après 90 jours.

Cache — ElastiCache Redis

Ressource Config Coût/mois
Cluster mode 3 shards × 2 nœuds cache.r6g.large (13 GB/shard) $1 452

Cluster mode nécessaire pour distribuer les ~100 000+ clés rate quotes et supporter le pub/sub à grande échelle.

Stockage — S3

Ressource Volume Coût/mois
Stockage Standard 500 GB (documents actifs < 30 jours) $11.50
Stockage Intelligent-Tiering 1 TB (documents anciens) $23
Glacier Instant Retrieval 2 TB (archives > 6 mois) $8
Requêtes PUT/GET ~5M/mois $20
Transfert sortant S3 200 GB (via CloudFront réduit les coûts) $9
Total S3 ~$72

Réseau

Ressource Config Coût/mois
ALB 2 load balancers (backend + frontend), ~200 LCU $110
NAT Gateway 2 NATs, ~1 TB appels carriers + Redis $111
CloudFront ~500 GB transfert (assets + PDFs + exports) $125
Total réseau $346

Services managés

Ressource Usage Coût/mois
SES ~120 000 emails/mois $12
SES — pièces jointes PDF ~5 000 bookings × 300 KB $1.80
Secrets Manager 20 secrets + 2M API calls/mois $18
Route 53 2 zones (prod + staging), traffic routing $10
CloudWatch Logs 100 GB/mois + métriques + Container Insights $200
WAF + Shield Standard WebACL, 10 rules, ~50M requêtes/mois, DDoS basique $65
KMS Encryption at rest RDS/S3, rotation clés $10
Total services $317

Total Tier 3 — 10 000 utilisateurs

Catégorie Coût/mois
Compute (EKS) $773
RDS PostgreSQL (Multi-AZ + Replica + Proxy) $2 052
ElastiCache Redis (cluster mode) $1 452
S3 (avec tiering) $72
Réseau (ALB + NAT + CloudFront) $346
Services (SES + Secrets + R53 + CW + WAF + KMS) $317
TOTAL ~$5 012/mois
Avec buffer 15% ~$5 764/mois

7. Tableau récapitulatif

Composant 100 users 1 000 users 10 000 users
EKS (Control Plane + Nodes) $134 $435 $773
RDS PostgreSQL $64 $416 $2 052
ElastiCache Redis $12 $242 $1 452
S3 $2 $13 $72
Réseau (ALB + NAT + CDN) $61 $136 $346
Services managés $23 $73 $317
TOTAL (on-demand) $296 $1 315 $5 012
TOTAL avec buffer 15% ~$340 ~$1 512 ~$5 764

Note hors scope : Stripe facture 2.9% + $0.30 par transaction. Pour 500 transactions/mois à $500 chacune, cela représente ~$7 400/mois de frais Stripe — à prendre en compte dans la marge business, pas dans l'infra.


8. Économies avec Reserved Instances

Engager 1 ou 3 ans sur les ressources stables (RDS, ElastiCache, nœuds EKS de base) permet des économies significatives.

1 an — Savings Plans

Composant Coût on-demand Après 1 an RI (~35% réduction)
RDS (1 000 users) $416 ~$270
ElastiCache (1 000 users) $242 ~$157
EC2 workers EKS (1 000 users) $362 ~$235
Économie mensuelle ~$358/mois

Impact par palier avec Reserved Instances 1 an

Palier On-demand Avec RI 1 an Économie annuelle
100 users $296 ~$220 ~$912
1 000 users $1 315 ~$950 ~$4 380
10 000 users $5 012 ~$3 600 ~$16 944

9. Facteurs de risque et dépassements potentiels

🔴 Risque élevé — Appels APIs carriers

Chaque POST /rates/search sans cache Redis déclenche 5 appels HTTP externes en parallèle. À 1 000 users avec 30% de cache miss → ~2 400 appels/heure vers les carriers. Impact NAT Gateway : transfert data $0.045/GB. Si chaque réponse carrier fait 10 KB → ~100 GB/mois → $4.50. Si les réponses sont plus volumineuses (50 KB+) ou si le cache miss monte → coût × 5 à × 10.

Mitigation : Ajuster le TTL Redis (actuellement 15 min) à 3060 min pour les routes peu demandées.

🔴 Risque élevé — audit_logs à 10 000 users

À 10 000 users, audit_logs peut atteindre 50200M lignes/an (toutes actions loggées). RDS db.r6g.2xlarge avec 1 TB de stockage sera rapidement saturé. Mitigation : Mettre en place un archivage automatique des logs > 90 jours vers S3 + Athena pour les requêtes analytiques.

🟡 Risque moyen — WebSocket à grande échelle

Socket.IO avec Redis adapter fonctionne bien jusqu'à ~2 000 connexions simultanées sur un cache.r6g.large. Au-delà, envisager de passer à Redis Cluster mode ou à une gateway WebSocket dédiée.

🟡 Risque moyen — PDFs avec pièces jointes emails (SES)

Les booking confirmations envoient le PDF en base64 dans le corps de l'email (détecté dans le code email service). Pour 5 000 bookings/mois à 300 KB/PDF → 1.5 GB de data SES/mois → $0.18/mois en plus des emails. À grande échelle, préférer un lien S3 signé dans l'email plutôt qu'une pièce jointe.

🟡 Risque moyen — ElastiCache sous-dimensionné

Le nombre de clés Redis peut exploser si les recherches sont très diversifiées (nombreuses combinaisons origin/destination/containerType). Monitorer cache.CurrItems et BytesUsedForCache dans CloudWatch dès le démarrage.

🟢 Risque faible — S3

Les coûts S3 restent maîtrisés avec les politiques de cycle de vie (Intelligent-Tiering + Glacier). La migration MinIO → S3 est transparente (l'app utilise déjà le SDK AWS S3 v3).


10. Recommandations d'optimisation

Priorité haute (impact fort, faible effort)

  1. S3 Lifecycle Policies dès le J1

    • Documents > 30 jours → Intelligent-Tiering
    • Documents > 180 jours → Glacier Instant Retrieval
    • Économie estimée : 5070% sur les coûts de stockage long terme
  2. RDS Proxy activé dès 1 000 users

    • NestJS ouvre N connexions par pod × N pods → sans proxy, RDS sature
    • db.r6g.large supporte ~150 connexions max, 10 pods × 10 connexions = limite atteinte
  3. CloudFront pour tous les assets S3 publics

    • Élimine le transfert sortant S3 (×8 fois moins cher via CloudFront)
    • Mettre en cache les PDFs de booking (signé URL → CloudFront signed URL)
  4. Reserved Instances 1 an sur RDS + ElastiCache

    • Ces deux services représentent 5060% de la facture à 1 000+ users
    • Le ROI est atteint dès le premier mois comparé à l'on-demand

Priorité moyenne

  1. Archivage audit_logs vers S3 + Athena

    • Créer un job cron mensuel qui exporte les logs > 90 jours en Parquet vers S3
    • Requêtes analytiques via Athena ($5 par TB scanné)
    • Libère l'espace RDS et maintient les performances des indexes
  2. SQS + Lambda pour la génération de PDFs et l'envoi d'emails

    • Actuellement synchrone → bloque le thread NestJS
    • Découpler : POST /bookings → enfile en SQS → Lambda génère PDF + envoie email
    • Réduit les besoins CPU des pods NestJS (~20% de réduction possible)
  3. Lien S3 signé dans les emails plutôt que pièce jointe

    • Remplacer le PDF base64 dans SES par un lien CloudFront signé (1h expiry)
    • Réduit la taille des emails de 6070% et évite les filtres anti-spam

Priorité basse

  1. Fargate Spot pour les pods non-critiques

    • Workers de génération PDF/export peuvent tourner sur Fargate Spot (70% moins cher)
  2. KEDA (Kubernetes Event-Driven Autoscaling)

    • Scaler les pods NestJS selon la profondeur de la file SQS plutôt que le CPU

11. Architecture Kubernetes recommandée

Namespaces

xpeditis-prod
├── backend          # NestJS pods
├── frontend         # Next.js pods
└── monitoring       # Prometheus + Grafana (optionnel)

Sizing des pods par palier

Backend NestJS

Palier Replicas (base) Replicas (max HPA) CPU request/limit RAM request/limit
100 users 2 3 500m / 1500m 512Mi / 1Gi
1 000 users 4 8 750m / 2000m 768Mi / 1.5Gi
10 000 users 8 20 1000m / 3000m 1Gi / 2Gi

Frontend Next.js (standalone)

Palier Replicas (base) Replicas (max HPA) CPU request/limit RAM request/limit
100 users 1 2 250m / 1000m 256Mi / 512Mi
1 000 users 2 4 500m / 1500m 512Mi / 1Gi
10 000 users 3 8 750m / 2000m 512Mi / 1Gi

Variables d'environnement Kubernetes (Secrets)

À stocker dans AWS Secrets Manager et monter via External Secrets Operator :

  • DATABASE_URL → RDS connection string avec RDS Proxy endpoint
  • REDIS_HOST / REDIS_PASSWORD → ElastiCache primary endpoint
  • JWT_SECRET → rotation automatique mensuelle recommandée
  • AWS_S3_BUCKET → remplace MINIO_ENDPOINT / MINIO_ACCESS_KEY / MINIO_SECRET_KEY
  • STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET
  • API keys × 5 carriers (Maersk, MSC, CMA CGM, Hapag-Lloyd, ONE)
  • SMTP_HOST → SES SMTP endpoint + credentials

Ingress (ALB Ingress Controller)

# Règles d'ingress recommandées
/api/*           → backend service (port 4000)
/socket.io/*     → backend service (sticky sessions activées)
/*               → frontend service (port 3000)

Le WebSocket Socket.IO nécessite alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true


Résumé exécutif

100 users 1 000 users 10 000 users
Coût mensuel estimé ~$340 ~$1 500 ~$5 800
Coût annuel ~$4 080 ~$18 000 ~$69 600
Avec RI 1 an ~$2 640 ~$11 400 ~$43 200
Poste dominant Compute + Réseau RDS Multi-AZ RDS + Redis
Principal risque Sur-dimensionnement Connexions DB audit_logs volume

Les prix sont indicatifs en us-east-1 (on-demand, mars 2026). eu-west-1 (Paris : eu-west-3) est ~510% plus cher. Ces estimations excluent : les frais Stripe (2.9% + $0.30/transaction), les licences SaaS tierces éventuelles, et les coûts de développement/opération.