Skip to content

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 push de 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 le head_pipeline existant 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 push sur 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

  1. resource_group sur 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.

  2. 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.

  3. Alerter sur les pannes silencieuses : PrometheusRule sur l'APIService metrics.k8s.io Unavailable (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 (dont frontend)
  • 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-0 et otel-collector Ă  0 restart depuis le boot (fix #125 confirmĂ©), service graph fastapi → fastapi_db dans le Node Graph Grafana (#117)
  • Exposition : app + api + grafana + argocd en 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.