
Le Volet 6 est le projet fil rouge du parcours OUTSCALE — un récit linéaire qui déploie une application 3-tiers complète sur un compte réel, du J0 au cleanup, en consommant chapitre après chapitre les références techniques du Volet 3. Les 7 piliers Well-Architected sont audités en continu, pas à la fin. Le code complet du capstone vit dans le dépôt lab-outscale-capstone que vous pouvez cloner et exécuter sur votre propre compte.
Le projet en deux phrases
Section intitulée « Le projet en deux phrases »Une application web 3-tiers haute disponibilité (frontend Nginx, backend applicatif, base PostgreSQL primaire + replicas) déployée sur OUTSCALE eu-west-2 dans une architecture multi-Net HA : trois VPC indépendants, un par sous-région (eu-west-2a/b/c), interconnectés en full-mesh par Net Peering. La BDD primaire vit dans Net-A, deux replicas synchrones dans Net-B et Net-C. Les flux applicatifs traversent les peerings, jamais Internet.
L'infrastructure est entièrement codée (Terraform + Packer + Ansible), versionnée (backend d'état OOS), et alignée sur les 7 piliers Well-Architected dès la conception. C'est l'architecture top du top que viserait un OIV ou un OSE soumis à NIS 2.
Une architecture haute disponibilité, pas un lab single-AZ
Section intitulée « Une architecture haute disponibilité, pas un lab single-AZ »Le capstone vise explicitement la haute disponibilité — la perte d'une sous-région entière (eu-west-2a, b ou c) ne doit pas faire tomber l'application. Chaque tier est dupliqué dans les 3 sous-régions : 3 frontends Nginx, 3 backends, 1 BDD primaire + 2 replicas synchrones. Le service reste accessible avec dégradation maîtrisée (RPO < 1 min sur la BDD, RTO ≤ 1 h en bascule replica) si une AZ disparaît. Cette posture HA structure toutes les décisions techniques qui suivent — découpage en 3 Nets, Net Peering full-mesh, NAT par Net, sauvegardes 3-2-1, etc. Si vous cherchez un lab single-AZ d'apprentissage, ce volet n'est pas le bon choix — voyez plutôt les guides ponctuels du Volet 3.
Périmètre — couvert vs hors capstone
Section intitulée « Périmètre — couvert vs hors capstone »Couvert :
- Réseau complet : 3 Nets
/22, 9 Subnets/24(3 tiers × 3 Nets), 3 IGW, 3 NAT Services, 9 route tables, peerings full-mesh. - Bastion SSH unique (Net-A) avec EIP fixe (allouée hors Terraform), compte EIM dédié, accès humain via
ProxyJump. - Application : 3 frontends Nginx, 3 backends, 1 BDD primaire + 2 replicas.
- Front-end public HA : 3 LBU OUTSCALE (un par AZ) en TCP/443 passthrough, leurs 3 EIPs publiées en DNS round-robin côté client. Le client TCP retry naturellement sur l'IP suivante en cas de perte d'une AZ, healthcheck DNS externe pour retirer l'IP morte du carrousel.
- Sauvegardes : snapshots BSU quotidiens + exports OOS dans un compte audit séparé.
- Configuration Ansible via inventaire dynamique (plugin
osc_vmdu Volet 3). - Audit Well-Architected final — checklist par pilier sur l'infrastructure réelle.
- Cleanup propre — démonstration de réversibilité.
Hors capstone : analyse FinOps post-deploy, observabilité applicative, DR drill, supply-chain et audit conformité — sujets connexes notés dans la roadmap pour plus tard.
RTO / RPO documentés avant le code
Section intitulée « RTO / RPO documentés avant le code »Pilier Reliability — décision la plus structurante du projet. Définir les objectifs métier d'abord, choisir la technique ensuite.
| Tier | Service | RTO cible | RPO cible | Justification |
|---|---|---|---|---|
| Frontend | Nginx | 15 min | 0 (stateless) | Recréation à la demande depuis l'OMI Packer. Pas de données. |
| Backend | Application | 30 min | 5 min | Stateless aussi. Le 5 min RPO concerne les sessions actives stockées en BDD. |
| BDD primaire | PostgreSQL Net-A | 1 h | 1 min | Replica synchrone Net-B prend la main automatiquement (failover). |
| Replicas | PostgreSQL Net-B/C | 4 h | 5 min | Reconstruction depuis snapshot ou réplication continue après failover. |
Conséquences techniques : frontends et backends sont stateless (OMI Packer + Terraform suffit), la BDD utilise un volume io1 provisionné avec snapshots horaires + export OOS quotidien, la réplication PostgreSQL passe par le Net Peering (pas par Internet).
Choix de région — eu-west-2 vs cloudgouv-eu-west-1
Section intitulée « Choix de région — eu-west-2 vs cloudgouv-eu-west-1 »Le capstone est conçu pour les deux régions européennes d'OUTSCALE. Le choix dépend du contexte client :
| Région | Quand l'utiliser |
|---|---|
eu-west-2 (commerciale, France) | Workloads RGPD avec localisation France, certifié HDS et ISO 27001. Cas par défaut pour ce capstone. |
cloudgouv-eu-west-1 (SecNumCloud, France) | Workloads OIV/OSE, données sensibles, doctrine Cloud au centre. Nécessite un contrat SecNumCloud séparé. |
Le code Terraform du capstone est compatible avec les deux — la région est paramétrée dans variables.tf sous var.region. Bascule en changeant la valeur par défaut. Tous les timings observés dans les chapitres ont été validés sur eu-west-2.
Pourquoi 3 Nets full-mesh plutôt qu'un Net multi-AZ
Section intitulée « Pourquoi 3 Nets full-mesh plutôt qu'un Net multi-AZ »C'est le choix architectural le plus distinctif du capstone.
Pattern « 1 Net multi-AZ » (classique chez les hyperscalers)
Section intitulée « Pattern « 1 Net multi-AZ » (classique chez les hyperscalers) »Un seul VPC qui couvre les 3 sous-régions avec des subnets dédiés par AZ. C'est ce qu'on déploie 80 % du temps. Avantages : simplicité opérationnelle, peering inutile, IP allocation unifiée. Inconvénients :
- Blast radius unique — une mauvaise modification du VPC (route, peering, ACL) impacte les 3 AZ d'un coup.
- IAM partagé au niveau VPC — pas de cloisonnement organisationnel par AZ.
- Audits cross-AZ plus complexes — toutes les ressources se mélangent.
Pattern « 3 Nets en full-mesh »
Section intitulée « Pattern « 3 Nets en full-mesh » »Un Net par sous-région, chacun avec son propre IGW, NAT, route tables. Trois outscale_net_peering interconnectent les Nets en mesh complet (A↔B, A↔C, B↔C).
| Aspect | 1 Net multi-AZ | 3 Nets full-mesh |
|---|---|---|
| Blast radius (mauvaise modif réseau) | 3 AZ d'un coup | 1 AZ uniquement |
| Cloisonnement IAM par AZ | Impossible nativement | Naturel — un Net = un périmètre |
| Audit indépendant par AZ | Filtrage explicite à appliquer | Trivial — oapi-cli ReadVms --Filters.NetIds[] vpc-XXX |
| Coût (3 NAT au lieu d'1) | 1× NAT facturé | 3× NAT facturés |
| Complexité Terraform | Modérée | Plus dense (peerings + routes inter-Net) |
| Cohérence de routage inter-AZ | Implicite (interne au Net) | Explicite via peerings — visible et auditable |
La décision : pour ce capstone, on adopte 3 Nets full-mesh parce que (1) c'est l'architecture qu'on rencontre chez les OIV / OSE soumis à NIS 2, (2) la complexité Terraform reste maîtrisée avec for_each, (3) le surcoût NAT est minoritaire dans la facture totale, (4) l'audit indépendant par Net prépare directement le Chapitre 9 (audit WAF). Pour un projet réel sans contrainte de cloisonnement, le Net unique multi-AZ reste une option valide.
Plan d'adressage — 3 Nets /22, 9 Subnets /24
Section intitulée « Plan d'adressage — 3 Nets /22, 9 Subnets /24 »Aucun chevauchement entre les Nets pour permettre le Net Peering (Chapitre 2).
| Net | CIDR | IPs | Sous-région | Subnet public | Subnet privé | Subnet data |
|---|---|---|---|---|---|---|
| Net-A | 10.10.0.0/22 | 1 024 | eu-west-2a | 10.10.0.0/24 | 10.10.1.0/24 | 10.10.2.0/24 |
| Net-B | 10.11.0.0/22 | 1 024 | eu-west-2b | 10.11.0.0/24 | 10.11.1.0/24 | 10.11.2.0/24 |
| Net-C | 10.12.0.0/22 | 1 024 | eu-west-2c | 10.12.0.0/24 | 10.12.1.0/24 | 10.12.2.0/24 |
Pourquoi /22 et pas /16
Section intitulée « Pourquoi /22 et pas /16 »Le piège classique est de prendre /16 par défaut (65 536 IPs par Net) parce que c'est la valeur évoquée dans la plupart des tutoriels AWS. Pour un capstone qui hébergera ~10 VMs par Net, c'est 64 fois trop grand. Conséquences du sur-dimensionnement :
- IP allocation gaspillée dans la planification du peering.
- Routes plus larges dans les tables de routage — moins lisibles, plus dur à auditer.
- Risque de chevauchement futur si on ajoute un peering vers un autre projet déjà en
10.x.0.0/16.
/22 (1 024 IPs) est le bon compromis : 4 subnets /24 possibles (3 actifs + 1 réserve pour un tier futur), 256 IPs par subnet (largement suffisant pour 50+ VMs par tier), CIDR encore lisible.
Architecture cible
Section intitulée « Architecture cible »Chaque Net est isolé au niveau IAM et réseau ; un incident dans Net-B ne propage pas vers Net-A et Net-C. Le Net Peering rétablit la connectivité contrôlée pour la réplication BDD et les flux applicatifs inter-tiers. Segmentation maximale, blast radius minimal, audit indépendant possible par Net.
Tagging Well-Architected — 5 dimensions
Section intitulée « Tagging Well-Architected — 5 dimensions »Pilier Operational Excellence et Cost. Toute ressource créée par le capstone porte ces 5 tags, sans exception.
| Tag | Valeur dans ce capstone | Pilier servi |
|---|---|---|
Name | capstone-<rôle>-<id> (ex. capstone-bastion-a, capstone-rt-b-private) | OpEx |
project | capstone | OpEx, Cost |
env | lab | OpEx, Cost |
owner | stephane-robert | OpEx |
cost-center | formation | Cost |
Discipline non négociable : le module Terraform commun local.base_tags est référencé par TOUTES les ressources via dynamic "tags" { ... }. À terme, un contrôle CI bloquant via osc-policy scan plan rejettera tout terraform apply sans ces tags.
Décisions techniques OUTSCALE-spécifiques
Section intitulée « Décisions techniques OUTSCALE-spécifiques »Trois pièges spécifiques OUTSCALE à connaître avant de toucher au code :
- Net Peering — acceptation explicite. Sur OUTSCALE, les peerings intra-compte ne sont pas auto-acceptés ; ils restent en
pending-acceptancejusqu'à ce qu'une ressourceoutscale_net_peering_acceptationsoit créée. Sans elle, les routes pointant vers le peering tombent enblackhole. Le Chapitre 2 détaille ce point — c'est l'erreur la plus fréquente quand on porte un module de peering AWS. - Backend Terraform sur OOS — checksum HTTP. Avec Terraform 1.10+, le SDK AWS Go v2 envoie un trailing checksum non supporté par OOS (erreur
HTTP 400 trailing checksum is not supported). Contournement : exporterAWS_REQUEST_CHECKSUM_CALCULATION=when_requiredetAWS_RESPONSE_CHECKSUM_VALIDATION=when_requiredAVANTterraform init/plan/apply. Inclus dans le.envrcdu dépôt capstone. - EIP du bastion hors Terraform. L'EIP du bastion est créée une seule fois par
oapi-cli(Pré-requis B) parce qu'elle doit survivre aux cyclesterraform destroy/apply. Toute la configuration cliente (DNS,~/.ssh/config, firewalls amont) en dépend. Terraform référence cette EIP via un datasource filtré par tag, puis crée uniquement leoutscale_public_ip_link(la liaison VM ↔ EIP) qui, lui, est versionné et reproductible.
Plan du capstone
Section intitulée « Plan du capstone »Deux pré-requis hors numérotation sont à exécuter avant le Chapitre 1 :
- Pré-requis A — OMI durcie (Packer Ubuntu 24.04). Construire l'image applicative versionnée. Référence : Packer. Compter 1-2 h. Réutilisable pour d'autres projets.
- Pré-requis B — EIP fixe pour le bastion (
oapi-cli). Allouer une seule fois une EIP qui survivra aux cyclesterraform destroy/apply. Référence : oapi-cli. Compter 5 min.
Une fois ces deux pré-requis en place, le récit linéaire commence :
| Chap. | Sujet | Durée estimée | Référence(s) consommée(s) |
|---|---|---|---|
| 1 | Provisionner les 3 Nets en /22 (un Net par sous-région, IGW, NAT, route tables) | 2-3 h | Référence Terraform, Réseau — design |
| 2 | Établir le Net Peering full-mesh (3 peerings A↔B, A↔C, B↔C) + acceptation explicite + routes inter-Net | 1-2 h | Référence Terraform |
| 3 | Déployer le bastion SSH (compte EIM dédié, SG SSH restreint, EIP du pré-requis B attachée via datasource) | 1-2 h | Référence Terraform, Réseau — IGW/NAT/EIP/bastion |
| 4 | Frontends Nginx HTTPS — 3 instances Nginx (une par AZ) avec SSL bout en bout : CA interne, cert serveur par instance, page de démo, configurées via Ansible | 2-3 h | Référence Terraform, Référence inventaire dynamique |
| 5 | 3 LBU + DNS round-robin (cloud-native) — 3 LBU OUTSCALE managés (un par AZ, TCP/443 passthrough), 3 EIPs publiées en DNS round-robin côté client, healthcheck DNS externe pour la résilience perte d'AZ | 2-3 h | Référence Terraform, Calcul TINA |
| 6 | 3 VMs HAProxy + cluster Corosync/Pacemaker (alternative souveraine) — 3 VMs HAProxy auto-gérées (une par AZ), cluster Pacemaker à quorum 3, EIP flottante pilotée par un agent OCF IMDS-first. Solution 100 % dans le compte, indépendante d'un DNS tiers | 3-4 h | EIP flottante HA — page concept détaillée |
| 7 (à venir) | Backend + BDD HA dans les 3 Nets (backends applicatifs + 1 BDD primaire + 2 replicas synchrones, configurés via Ansible) | 3-4 h | Référence Terraform |
| 8 (à venir) | Sauvegardes (snapshots BSU + exports OOS dans compte audit) | 1-2 h | Sauvegardes — RPO/RTO/PRA |
| 9 (à venir) | Audit Well-Architected final — checklist par pilier sur l'infra réelle | 2 h | Volet 5 — 7 piliers |
| 10 (à venir) | Cleanup (démontage propre dans l'ordre inverse, démonstration de réversibilité) | 30 min | Pilier Sovereignty |
Les chapitres 5 et 6 présentent deux approches complémentaires de la HA cross-AZ pour l'exposition publique. Choisir selon le contexte : DNS round-robin pour la simplicité cloud-native, Pacemaker pour la souveraineté pure (cas SecNumCloud / OIV). Les deux peuvent coexister — par exemple LBU+DNS RR en prod commerciale, HAProxy+Pacemaker en environnement sensible.
| Critère | Chap 5 — LBU + DNS RR | Chap 6 — HAProxy + Pacemaker |
|---|---|---|
| Souveraineté | Dépendance DNS tiers (Cloudflare/NS1) | 100 % dans le compte OUTSCALE |
| Complexité opérationnelle | Faible (3 ressources Terraform + zone DNS) | Moyenne (cluster + agent OCF + runbook) |
| RTO bascule | TTL-bound (30 s à 5 min) | ~30 s (timeout monitor pacemaker) |
| Patching OS | Nul (LBU managé) | À la charge de l'opérateur (3 VMs) |
| Coût mensuel additionnel | ~30 € (3 LBU) + healthcheck DNS | ~25 € (3 VMs) |
| SPOF résiduel | Le DNS du tiers | STONITH absent en cloud (à documenter) |
Pré-requis
Section intitulée « Pré-requis »- Compte OUTSCALE actif sur la région
eu-west-2(commerciale, France) avec quotas suffisants pour ~10 VMs. - Profil OSC
defaultconfiguré dans~/.osc/config.jsonavec une paire AK/SK valide. - Outils locaux installés et pinnés en versions exactes : Terraform 1.10+, Packer 1.15.0, Ansible 2.16+,
osc-sdk-python0.40+,oapi-cli0.13+,aws-cli2.x,jq,direnv. - Avoir lu au moins le Volet 1 — Découvrir et Volet 2 — Fondations, idéalement parcouru les Références du Volet 3.
Discipline transverse
Section intitulée « Discipline transverse »| Pilier | Application dans le capstone |
|---|---|
| Operational Excellence | Tagging unifié sur 5 dimensions ; backend d'état Terraform sur OOS dédié ; chaque chapitre = un commit Git de la stack. |
| Security | Compte EIM scopé pour le pipeline ; pas de secrets en clair dans le code ; SG-to-SG entre tiers ; SSH uniquement via bastion ; isolation par Net = blast radius par AZ. |
| Reliability | RTO/RPO documentés ; 3 Nets multi-AZ en full-mesh ; 2 patterns HA étudiés (Chap 5 LBU+DNS RR cloud-native, Chap 6 HAProxy+Pacemaker souverain) ; sauvegardes 3-2-1 testées au Chapitre 8 ; runbook PRA versionné. La perte d'un Net entier ne contamine pas les autres. |
| Performance Efficiency | Sizing TINA tinav5.c2r4p2 par défaut ajusté par tier ; volumes BSU gp2 (io1 justifié uniquement pour la BDD) ; co-localisation chaîne front-back-data sur la même AZ. |
| Cost Optimization | Tag cost-center=formation ; cleanup automatisé au Chapitre 10 ; lifecycle OOS expiration 30 jours sur les logs et exports. |
| Sustainability | ReadCO2EmissionAccount mesuré avant et après le capstone ; choix génération tinav5 récente. |
| Sovereignty | Région eu-west-2 (France) ; OMI durcie souveraine ; aucun module Terraform tiers non européen. |
Code source
Section intitulée « Code source »Le code complet du capstone vit dans le dépôt lab-outscale-capstone (à publier sur GitHub outscale-srt20). Structure :
lab-outscale-capstone/├── packer/ # Pré-requis A — OMI durcie├── terraform/│ ├── 00-nets/ # Chapitre 1 — 3 Nets /22 (a/b/c) + IGW + NAT│ ├── 05-peering/ # Chapitre 2 — Net Peering full-mesh + acceptation│ ├── 10-bastion/ # Chapitre 3 — Bastion + SG dans Net-A (EIP via datasource)│ ├── 20-app/ # Chapitre 4 — 3 frontends Nginx HTTPS (un par AZ)│ ├── 25-lbu/ # Chapitre 5 — 3 LBU TCP/443 passthrough + DNS RR│ ├── 30-haproxy-cluster/ # Chapitre 6 — 3 HAProxy + Corosync/Pacemaker + EIP flottante│ └── 40-backend-db/ # Chapitre 7 — Backends applicatifs + BDD primaire + 2 replicas├── ansible/│ ├── inventory_plugins/ # Plugin osc_vm (référence du Volet 3)│ ├── inventory/│ │ └── capstone.osc_vm.yml│ ├── playbooks/ # Configurations Nginx, backends, BDD (chapitres 4 et 7)│ └── roles/└── scripts/ └── bootstrap-tfstate-bucket.sh # Création idempotente du bucket OOS de backendChaque chapitre du site renvoie au sous-dossier correspondant — le narratif vit ici, le code vit dans le dépôt.
Articulation avec les autres volets
Section intitulée « Articulation avec les autres volets »Ce volet est l'aboutissement pédagogique du parcours. Il utilise les concepts du Volet 2, consomme les références du Volet 3, met en œuvre les services managés du Volet 4 et est audité selon les piliers du Volet 5.