Exploitation · CI/CD & déploiement

CI/CD & déploiement

Chaîne de livraison GitOps de bout en bout, opérationnelle en staging : le développeur pousse du code, une image est publiée, et le cluster se met à jour tout seul. Aucune action manuelle sur le serveur.

git push (qa) → GitHub Actions (build + image) → GHCR → write-back GitOps → Argo CD → k3s
Développeur
commit + push sur qa
git push
GitHub Actions
build + test + image (Quarkus/jib ou nginx)
docker push
GHCR
registre d'images :sha
write-back du tag
fga-infrastructure
dossier gitops/ (branche qa)
surveille + sync
Argo CD
réconcilie l'état désiré
applique
k3s
Traefik → fronts & services (TLS auto)
Flux complet — la CI publie, Argo CD tire. La CI ne se connecte jamais au serveur (pas de SSH).

Principes directeurs

  • GitOps : le dépôt Git est la source de vérité. La CI publie une image et écrit un tag ; un opérateur dans le cluster (Argo CD) réconcilie. La CI n'a aucun accès au serveur.
  • Tout est image — services Quarkus et fronts — dans un seul registre : GHCR (ghcr.io/antah-sarl/…).
  • Parité prod : ce qui tourne en staging = ce qui tournera en prod. Seuls les values/secrets par environnement changent (envs/stagingenvs/prod).
  • Immuable & réversible : image taguée par sha-<court> ; rollback = git revert du bump de tag → Argo re-synchronise.
  • Convention de branches : qa = staging (tout pipeline se déclenche sur qa, Argo suit qa) ; main = prod (à venir, overlay envs/prod).

La chaîne CI — une pipeline par dépôt (GitHub Actions)

Chaque dépôt applicatif s'arrête à « image publiée + tag écrit ». Le déclencheur est toujours on: push [qa].

ComposantÉtapesSortie
Service (fga-services)JDK 21 · Gradle build + test · image via jib (pas de Dockerfile) · monorepo filtré par chemin (une image par module changé)GHCR :sha-…
Front webcheckout + sous-module design-system · Dockerfile multi-stage (npm → vite build → nginx) · imageGHCR :sha-…
Doc techniqueimage nginx du site statiqueGHCR :sha-…

Étape finale commune : le write-back. Un job (identité bot sigfga-ci) checkout fga-infrastructure avec un PAT (GITOPS_TOKEN), met à jour le tag d'image dans gitops/apps/<app>/values-staging.yaml, commit et push sur qa. Ce push est ce qui déclenche le déploiement.

Pourquoi un PAT dédié ? Le GITHUB_TOKEN automatique d'un workflow n'a de droits que sur son propre dépôt — il ne peut donc pas écrire dans fga-infrastructure. Le GITOPS_TOKEN (fine-grained, Contents: write) sert uniquement à ce write-back. Pour les fronts, il lit aussi le sous-module privé fga-design-system-ui-web.
Builds ciblés ou en masse. Sur push, seuls les modules changés sont buildés (monorepo filtré par chemin). En manuel (Run workflow) on cible un module précis, ou module: all (tous les services) / all-edges — pratique pour un déploiement de masse, throttlé par max-parallel: 2 (piège GHCR : voir Socle GitOps).

La chaîne CD — GitOps avec Argo CD

  • Argo CD surveille le dossier gitops/envs/staging de fga-infrastructure (branche qa) et réconcilie le cluster vers l'état déclaré.
  • Un ApplicationSet génère une Application par service (et une par front) depuis une simple liste → ajouter un service = une ligne + un fichier de values.
  • Mise à jour d'image : le write-back change le tag dans values-staging.yaml → Argo détecte l'écart et applique un rolling update.
  • Le détail du socle (app-of-apps, sync-waves, operators bootstrappés, secrets) est décrit dans Socle GitOps & bootstrap.

Packaging

  • Services : image produite par Quarkus (quarkus-container-image-jib) — aucun Dockerfile à maintenir. Probes /q/health/live & /ready.
  • Fronts : Dockerfile multi-stage node build → nginx (non-root, port 8080), fallback SPA pour le routing React ; le sous-module design-system est résolu au build.
  • Charts : un chart Helm générique quarkus-service réutilisé par les 20 microservices (un values par service) ; un chart spa-front pour les fronts. Pas 20 jeux de manifests à maintenir.

État déployé — staging

Tout ci-dessous tourne réellement, en HTTPS (certificats Let's Encrypt automatiques via cert-manager), domaine *.fga.antah.dev.

DomaineComposantAccès
Soclek3s + Traefik (ingress), Argo CD, cert-manager, sealed-secretsargocd.fga.antah.dev
DonnéesPostgreSQL (CloudNativePG) — une base par service (Database CR), + keycloak-pginterne
AuthentificationKeycloak + realm agentsauth.fga.antah.dev
Stockage objetMinIO (S3), bucket sigfgas3. / minio.fga.antah.dev
Bus d'événementsKafka KRaft sigfga-kafka (Strimzi)…-kafka-bootstrap:9092
ObservabilitéPrometheus + Grafana (kube-prometheus-stack)grafana.fga.antah.dev
Services métiers15 services + 5 edges/BFF (Quarkus), un par base, derrière un certif TLS partagéapi.fga.antah.dev/api/<service>
FrontsDocumentation · Portail e-services · Back-officedoc-tech. · portail. · admin.fga.antah.dev

Réseau, ingress, TLS

Un seul reverse-proxy : Traefik (fourni par k3s) — point d'entrée unique du cluster, TLS via cert-manager et routage des fronts, du BFF et des APIs. Pas d'API gateway dédié : l'auth JWT est validée par les services eux-mêmes (Quarkus OIDC). On ne réintroduira un gateway que si un catalogue d'APIs managées pour partenaires externes apparaît — et alors dans les deux environnements, pour garder la parité.

Secrets & configuration

ConfigurationConfigMap / values par environnement (URLs, topics, buckets, schémas BD…)
Identifiants BDgénérés par CloudNativePG (secret <cluster>-app), consommés par les services via secretEnv — jamais saisis à la main.
Secrets versionnésSealed Secrets — chiffrés dans gitops/, déchiffrés seulement dans le cluster. Rien en clair, rien dans l'image.
Secrets de bootstrapquelques secrets non versionnés, posés une fois à la main (accès GHCR, MinIO, Grafana) — cf. runbook.

Portabilité vers la prod

Le staging tourne sur un k3s léger. Les mêmes charts et manifests basculent vers l'on-premise (Nutanix) : on duplique envs/staging en envs/prod (autres values/secrets, targetRevision: main), on rejoue le runbook Day-0 (documenté), et c'est tout. Le plus dur — découvrir les pièges du bootstrap — est fait et écrit (voir Socle GitOps & bootstrap).