Sprint 5 Report â Frontend & Polish
PĂ©riode : 2026-06-22 Ă 2026-07-04 Release : merge develop vers main (fin de sprint) Ăquipe : 1 ingĂ©nieur DevOps (Youssef Kadi) Repo : gitlab.com/yk-devops/fastapi-eks-project
Executive Summary
Ă l'entrĂ©e du Sprint 5, la plateforme Ă©tait observable et opĂ©rĂ©e en GitOps (Sprint 4), mais restait une API sans visage : pas d'interface utilisateur, des UIs d'exploitation (ArgoCD, Grafana) accessibles uniquement en interne ou par mot de passe, et un cluster mono-nĆud dont la validation live allait rĂ©vĂ©ler les limites. Ce sprint a livrĂ© quatre chantiers : l'accĂšs plateforme (ArgoCD exposĂ© publiquement, SSO OIDC GitLab sur ArgoCD et Grafana), la capacitĂ© (requests mesurĂ©es, gouvernance LimitRange, split en deux node groups core on-demand / observability Spot, ~-70 % sur la part Spot), le tracing distribuĂ© (auto-instrumentation OpenTelemetry de FastAPI + SQLAlchemy, Tempo + OTel Collector, service graph dans Grafana), et surtout un frontend complet en trois itĂ©rations : V1 vertical slice (SPA React durcie Ă 0 CVE, dĂ©ploiement GitOps, app.devopsyouss.com, CORS strict prouvĂ©), V2 (auth JWT, crĂ©ation de posts, votes, recherche, pagination), V3 (Ă©dition/suppression de ses posts, dĂ©tail inline, footer stack DevOps).
La signature de ce sprint : 55 % du scope est nĂ© en cours de route (11 issues sur 20), presque toujours Ă partir de findings de validation live transformĂ©s en issues tracĂ©es le jour mĂȘme â et livrĂ©es dans le sprint, sans rien reporter en silence.
Quatre URLs vitrines live pour les entretiens : app.devopsyouss.com (nouveau), api.devopsyouss.com, grafana.devopsyouss.com, doc.devopsyouss.com. DerniÚre validation end-to-end from-scratch : 2026-07-04 (bootstrap 22 min, 10/10 Applications ArgoCD Synced/Healthy, V2 et V3 validées en conditions réelles, service graph visible).
Bilan des actions de la rétrospective Sprint 4
Nouveau dans ce rapport : avant de dérouler le sprint, on rend compte des 3 actions que la rétro du Sprint 4 s'était engagée à mener. Une rétro dont personne ne vérifie les actions est un rituel vide.
| Action Sprint 4 | Verdict | Détail |
|---|---|---|
| Lancer le multi-environnements dev/staging/prod | â Non fait â re-cadrage assumĂ© | DĂ©cision explicite du 2026-06-22 : le sprint pivote sur le thĂšme « Frontend & Polish » (la vitrine entretien d'abord). Le multi-env devient un sprint dĂ©diĂ© (Sprint 6), pas un report silencieux. |
| Poursuivre le vuln management (Phase 1 : cron Trivy ECR) | â Fait â et dĂ©passĂ© | Phases 1 et 2 livrĂ©es (scan registry planifiĂ© + Renovate sur les dĂ©pendances), suivies dans le projet transverse vuln management. |
resource_group sur les jobs infra + finaliser le schéma d'architecture |
â ïž MoitiĂ© fait | SchĂ©ma : â
rafraĂźchi en diagram-as-code (#127). resource_group : â non fait, avec rĂ©cidive â la collision schedule teardown / session live s'est reproduite le 2026-06-26. Repart en action n°1 du Sprint 6. |
Stories livrées
AccĂšs plateforme (SSO)
| # | Description | Taille | Statut |
|---|---|---|---|
| #105 | ArgoCD exposé publiquement via le Gateway (argocd.devopsyouss.com), admin password via ESO (ADR 022/023) |
M | Livré |
| #106 | SSO OIDC GitLab sur ArgoCD (Dex) et Grafana (auth.gitlab natif), RBAC par groupe (ADR 024) | L | Livré |
| #111 | Fix SSO : rÎle Grafana via env var, scope Dex read_user corrigé |
S | Livré |
| #113 | ADR 022/023/024 marqués validés live + findings SSO documentés | S | Livré |
Capacité & gouvernance des ressources
| # | Description | Taille | Statut |
|---|---|---|---|
| #112 | Requests/limits mesurés (fini le pifomÚtre), LimitRange par namespace créé au bootstrap (avant les pods), gouvernance validée from-scratch (INC-060, ADR 025) |
L | Livré |
| #114 | Split en 2 node groups : core (on-demand, chemin de trafic) / observability (Spot tainté, ~-70 % de coût), stack obs pinnée dessus (ADR 026) |
L | Livré |
| #115 | metrics-server injoignable sous overlay Cilium â hostNetwork (INC-061, jumeau d'INC-058) ; le HPA fastapi Ă©tait cassĂ© en silence depuis 6 jours |
M | Livré |
Tracing distribué
| # | Description | Taille | Statut |
|---|---|---|---|
| #107 | Auto-instrumentation OpenTelemetry de FastAPI + SQLAlchemy (env-gated, zéro invasif) + egress NetworkPolicy vers le collector | M | Livré |
| #108 | Tempo + OTel Collector déployés via ArgoCD, datasource Grafana tracesToLogsV2 (ADR 027) ; 2 fixes OOM (limite puis ballast Go du chart) |
L | Livré |
| #117 | Service graph : Tempo metrics-generator â remote_write Prometheus â Node Graph Grafana (fastapi â fastapi_db visible live) |
M | Livré |
| #125 | OOM Tempo au boot sous burst de spans : OTEL_PYTHON_EXCLUDED_URLS=healthz,metrics (probes exclues Ă la source) â tempo-0 et otel-collector Ă 0 restart au boot suivant |
M | Livré |
Frontend (V1 â V2 â V3)
| # | Description | Taille | Statut |
|---|---|---|---|
| #109 | SPA React+Vite minimale, image nginx-unprivileged durcie (apk upgrade : 31 CVE â 0), chaĂźne CI dĂ©diĂ©e (kaniko, double gate Trivy, SBOM), repo ECR fastapi-eks/frontend (ADR 028) |
L | Livré |
| #110 | Vertical slice : endpoint public /posts/public + CORS strict, deploy GitOps (ns frontend PSA restricted), HTTPRoute app.devopsyouss.com, promote-by-digest + write-back dĂ©diĂ©s â validĂ©e live (CORS prouvĂ© par test nĂ©gatif evil.com) |
L | Livré |
| #124 | Feed style LinkedIn sur la page publique (CSS/JSX pur, zéro changement back) | S | Livré |
| #128 | V2 : login/register JWT (mĂ©moire + sessionStorage), crĂ©ation de posts, votes (Ă©tat dĂ©duit des codes 201/409), recherche, pagination, dĂ©tail â 3 MR, 100 % sur les endpoints existants |
L | Livré |
| #130 | V3 : édition/suppression de ses posts (l'API fait autorité, 403), détail inline sous le post, footer stack DevOps (logos SVG inline, aucun chargement externe) | M | Livré |
Documentation & maintenance
| # | Description | Taille | Statut |
|---|---|---|---|
| #103 | Backfill des rapports de clÎture Sprint 0/1/2 | M | Livré |
| #104 | Image dĂ©ployĂ©e protĂ©gĂ©e de la lifecycle rule ECR 3 jours : promote-by-digest candidate- â deployed- (ADR 021) |
M | Livré |
| #127 | Schéma d'architecture rafraßchi (frontend, tracing, expo ArgoCD, NLB) en diagram-as-code + texte adjacent réaligné | S | Livré |
| #38 | Knowledge base searchable | XS | Fermée par analyse : l'existant couvre le besoin (recherche full-text MkDocs, dashboard incidents interactif, ADR en nav) ; le classement par technologie reste une amélioration possible, documentée dans l'issue |
Stories non livrées / reportées
| # | Description | Raison | Suite |
|---|---|---|---|
| #116 | Exposer Hubble UI via Gateway + SSO | Née en cours de sprint (2026-06-25), non prioritaire vs frontend ; le port-forward couvre le besoin day-2 | Backlog (triage du 2026-07-04), candidate au cadrage Sprint 6 |
| #126 | topologySpreadConstraints sur le frontend |
NĂ©e d'un finding live (#110) ; sans effet tant que le node group core est mono-nĆud |
Backlog |
| #129 | Rate limiting Envoy | Née du choix assumé « écriture publique » de la V2 (démo) | Backlog |
| #96 | Bump starlette ℠1.3.1 | Toujours bloqué par un tiers (prometheus-fastapi-instrumentator), CVE couvertes par VEX + risk acceptance (#101) |
Backlog (se débloque quand l'upstream bouge) |
Vélocité
Baseline Sprint 4 = 32 Ă©lĂ©ments livrĂ©s. Sprint 5 = 20 Ă©lĂ©ments (dont 1 fermĂ© par analyse), portĂ©s par 44 MR mergĂ©es (!185 â !239).
| Taille | Nb éléments | Description |
|---|---|---|
| XS | 1 | Trivial, moins de 2 heures |
| S | 4 | Simple, demi-journée |
| M | 8 | Moyen, 1 Ă 2 jours |
| L | 7 | Complexe, 3 jours ou plus |
| Total | 20 |
Scope ajoutĂ© en cours de sprint : 11 issues sur 20 (55 %). Cadrage initial du 2026-06-22 = 9 issues (#103â#110 + #38). Le reste est nĂ© pendant le sprint, de deux sources : les findings de validation live (#111 SSO, #112/#114/#115 toute la filiĂšre capacitĂ© dĂ©clenchĂ©e par INC-060, #117 service graph) et les dĂ©cisions produit en cours de route (#124 feed, #125 OOM boot, #127 schĂ©ma, #128 V2, #130 V3). Chaque ajout a Ă©tĂ© tracĂ© en issue avec milestone le jour mĂȘme â le scope a bougĂ©, la discipline non.
Incidents majeurs et résolutions
Le sprint a capitalisĂ© 2 incidents formels (INC-060, INC-061) â moins qu'au Sprint 4 (7), mais denses â plus deux incidents de process CI capitalisĂ©s en quirks.
INC-060 : saturation du nĆud unique â un redĂ©ploiement Grafana fait tomber tout l'ingress (2026-06-23)
Pendant la validation live du SSO, le redĂ©ploiement de Grafana rend les 3 hĂŽtes publics injoignables ~10 min : le nĆud unique t3.medium Ă©tait sur-engagĂ© (limits mĂ©moire cumulĂ©es = 168 % de la capacitĂ©), et le pic de boot de Grafana (prĂ©installation de plugins re-tĂ©lĂ©chargĂ©s Ă chaque dĂ©marrage, storage emptyDir) a fait basculer le nĆud â rafale de liveness failures, dont le plan de donnĂ©es Envoy, backend du NLB. Leçon dans la leçon : la stack d'observabilitĂ©, co-localisĂ©e et sans persistance, a redĂ©marrĂ© avec le nĆud et laissĂ© un trou de donnĂ©es exactement pendant l'incident â la chronologie vivait dans kubectl get events.
Fix en 3 Ă©tages : le dĂ©clencheur (GF_PLUGINS_PREINSTALL_DISABLED), la discipline (requests mesurĂ©es + LimitRange Ă l'admission, donc créé au bootstrap avant les pods), et le vrai fix : le split core / observability (#114) â un pic obs ne peut plus toucher le chemin de trafic, par construction.
Leçon : un nĆud sur-engagĂ© tient jusqu'au premier pic transitoire. Dimensionner sur le pic, isoler les workloads gourmands du chemin critique, et ne pas attendre d'un autoscaler qu'il voie l'overcommit runtime (il ne voit que le Pending).
INC-061 : metrics-server injoignable sous Cilium â le HPA cassĂ© en silence pendant 6 jours (2026-06-24)
kubectl top â Metrics API not available : l'APIService agrĂ©gĂ© metrics.k8s.io est servi par un pod en IP overlay, que le control plane EKS managĂ© ne sait pas router â jumeau exact d'INC-058 (webhooks), transposĂ© aux APIServices, diagnostiquĂ© en minutes grĂące Ă la capitalisation du Sprint 4. L'effet de bord vicieux : le HPA fastapi, privĂ© de mĂ©triques, avait cessĂ© de scaler sans aucune erreur visible depuis la migration Cilium. Fix : hostNetwork + port dĂ©diĂ© (10262). ValidĂ© live : APIService Available=True, HPA avec TARGETS chiffrĂ©es.
Leçon : tout composant que l'API server doit appeler (webhook ou APIService) doit ĂȘtre joignable depuis le VPC. Et une dĂ©pendance qui Ă©choue en silence (HPA sans mĂ©triques) est invisible sans surveillance active â d'oĂč l'action Sprint 6 sur l'alerte APIService.
Incidents de process CI (capitalisés en quirks, pas d'INC formel)
- Pipeline doublé (#128) : un
git pushde branche sans MR ouverte dĂ©clenche dĂ©jĂ un pipeline complet ; redĂ©clencher via l'API aprĂšs crĂ©ation de la MR fait un doublon inutile sur le runner self-hosted. RĂšgle : vĂ©rifier lehead_pipelineexistant avant d'en forcer un. - Course de write-back GitOps (2026-07-03) : 4 MR Renovate mergĂ©es en rafale â 4 write-back en parallĂšle se disputent le
git pushsur develop, un seul gagne (les changements étant cumulatifs, le gagnant portait tout ; les retries des perdants rejouent un push périmé, inutiles). RÚgle codifiée : merger une MR à la fois, en attendant la fin complÚte du pipeline, write-back inclus.
Décisions d'architecture (ADRs)
| ADR | Décision | Résumé |
|---|---|---|
| 021 | Lifecycle ECR deployed vs candidate | Promote-by-digest candidate- â deployed-, l'image en prod Ă©chappe Ă l'expiration 3 jours |
| 022 | ArgoCD admin password via ESO | Secret bcrypt géré par ESO (stratégie Merge), plus de mot de passe généré-perdu |
| 023 | Exposition publique ArgoCD | argocd.devopsyouss.com via le Gateway partagé, TLS wildcard |
| 024 | SSO OIDC GitLab | Un IdP unique (GitLab) pour ArgoCD (Dex) et Grafana, RBAC par groupe, admin local en secours |
| 025 | Gouvernance des ressources | Requests mesurées (pas devinées), LimitRange par namespace créé au bootstrap (l'admission n'agit pas rétroactivement) |
| 026 | Node groups core / observability | Chemin de trafic on-demand, observabilité sur Spot tainté : isolation des pics + ~-70 % de coût |
| 027 | Tracing distribué Tempo + OTel | Auto-instrumentation env-gated, collector central, sampling 100 % assumé (démo), service graph via metrics-generator |
| 028 | Frontend SPA supply chain | 2e workload avec la mĂȘme exigence que le back : image durcie 0 CVE, double gate Trivy, SBOM, promote-by-digest, GitOps |
Rétrospective
Ce qui a bien fonctionné
Le cycle « validation live â finding â issue â livrĂ© dans le sprint ». INC-060 a dĂ©clenchĂ© toute la filiĂšre capacitĂ© (#112/#114/#115), la validation #110 a produit #125/#126, la validation V2 a produit #130 â et presque tout a Ă©tĂ© livrĂ© dans le sprint mĂȘme. La validation live n'est pas une formalitĂ© de fin de chantier : c'est elle qui a gĂ©nĂ©rĂ© la moitiĂ© du scope.
La capitalisation qui paie. INC-061 diagnostiquĂ© en minutes parce que c'est le jumeau d'INC-058, documentĂ© au sprint prĂ©cĂ©dent. C'est la dĂ©monstration concrĂšte de l'intĂ©rĂȘt des fiches incidents : la 2e occurrence d'une classe de problĂšme coĂ»te 10x moins cher.
La discipline MR tenue malgrĂ© le rythme. 44 MR, une Ă la fois (branche â test â merge â nettoyage), milestone et labels dĂšs la crĂ©ation, doc dans chaque MR. Le scope a explosĂ© (+55 %), le process n'a pas craquĂ©.
Le frontend incrĂ©mental sans toucher au back. V1 â V2 â V3 livrĂ©es entiĂšrement sur les endpoints existants (promesse « React uniquement » tenue) : la V2 complĂšte n'a nĂ©cessitĂ© zĂ©ro changement d'API. Les limites assumĂ©es (JWT sessionStorage, Ă©criture publique) sont documentĂ©es en ADR avec leurs issues de suivi (#129).
Ce qui a bloqué ou coûté du temps
PrĂ©voir les bonnes valeurs de requests/limits n'est pas Ă©vident â et ne se devine pas. C'est la leçon transverse de toute la filiĂšre #112 : les valeurs initiales Ă©taient du pifomĂštre (168 % d'overcommit), les valeurs justes n'ont pu venir que de mesures live (et encore : metrics-server Ă©tait cassĂ©, INC-061, il a fallu mesurer via Prometheus). Puis chaque correction a rĂ©vĂ©lĂ© le piĂšge suivant : le LimitRange n'agit qu'Ă l'admission (livrĂ© en GitOps, il arrivait aprĂšs les pods â dĂ©placĂ© au bootstrap), et les requests honnĂȘtes ont fait surgir Insufficient memory (99 % de rĂ©servation, prometheus non planifiable) â rĂ©solu par la capacitĂ© (#114), pas en retruquant les chiffres. MĂȘme l'indicateur est contre-intuitif : la somme des limits monte (168â235 %) quand on borne des pods jusque-lĂ non capĂ©s, tout en rĂ©duisant le risque rĂ©el.
La collision schedule teardown a récidivé (2026-06-26). Le resource_group promis en rétro Sprint 4 n'a pas été fait, et le mur de 21h a de nouveau percuté une session live. Le palliatif (pauser le schedule avant toute session du soir) est une discipline humaine, donc faillible. Deux récidives = priorité n°1 du Sprint 6.
L'horloge du runner ESXi : 4 rĂ©cidives dans le sprint. Pause VM / shutdown ESXi â horloge guest en retard â seuls les jobs AWS Ă©chouent (401 ECR, SignatureDoesNotMatch), symptĂŽme dĂ©routant. Le fix durable a demandĂ© 3 itĂ©rations (chrony makestep â mask systemd-timesyncd â hwclock --hctosys + restart chrony quand la rĂ©fĂ©rence NTP elle-mĂȘme Ă©tait pĂ©rimĂ©e). Leçon : timedatectl et chronyc tracking peuvent tous les deux mentir ; croiser avec le RTC et l'heure rĂ©elle.
Les pannes silencieuses. Le HPA sans mĂ©triques (INC-061) a cessĂ© de fonctionner 6 jours sans une seule erreur. Ce qui ne crie pas n'est pas forcĂ©ment sain â il faut de la surveillance active sur les dĂ©pendances de contrĂŽle (d'oĂč l'action 3).
3 actions concrĂštes pour Sprint 6
-
resource_groupsur les jobs infra start/stop â vĂ©rifiable : deux pipelines infra dĂ©clenchĂ©s simultanĂ©ment se sĂ©rialisent au lieu de se chevaucher. Deux rĂ©cidives de collision, plus d'excuse. -
Cadrer le multi-environnements par un ADR stratégie AVANT tout code (namespaces vs comptes, overlays Kustomize, pipeline de promotion, rÎle de
main) â vĂ©rifiable : ADR mergĂ© en dĂ©but de sprint, avant la premiĂšre MR d'implĂ©mentation. -
Alerter sur les pannes silencieuses : PrometheusRule sur l'APIService
metrics.k8s.ioUnavailable(leçon INC-061) â vĂ©rifiable : alerte reçue sur Slack lors d'un test de panne.
Validation end-to-end
DerniĂšre validation complĂšte from-scratch : 2026-07-04 (bootstrap 22 min, 2 nodes Ready core/observability).
curl https://api.devopsyouss.com/healthz/ready
â {"status":"ok"}
- ArgoCD : 10/10 Applications
Synced/Healthy(dontfrontend) - Frontend V2 : parcours utilisateur complet en conditions réelles sur
app.devopsyouss.com(register â login â crĂ©ation â vote â recherche â pagination â dĂ©tail) - Frontend V3 : Ă©dition/suppression de ses posts + dĂ©tail inline + footer stack validĂ©s live
- Tracing :
tempo-0etotel-collectorĂ 0 restart depuis le boot (fix #125 confirmĂ©), service graphfastapi â fastapi_dbdans le Node Graph Grafana (#117) - Exposition :
app+api+grafana+argocden HTTPS (cert wildcard), SSO GitLab sur ArgoCD et Grafana
Documentation publique : doc.devopsyouss.com
Sprint 5 clÎturé le 2026-07-04. Release mergée dans main en fin de sprint.