ADR 013 — GitOps avec ArgoCD : pull-based vs push-based (2026-06-11)
Statut
Accepté (2026-06-11). Issue #72.
Contexte
Le déploiement sur EKS était push-based : le job deploy de la CI faisait
kubectl apply -k k8s/base/ directement sur le cluster (manuel, DEPLOY=true).
Limites de cette approche :
- Pas de source de vérité unique : l'état réel du cluster pouvait diverger de
Git sans que rien ne le détecte (drift). Un
kubectl editmanuel n'était jamais réconcilié. - Credentials cluster dans la CI : le runner détient un accès
kubectlau cluster (kubeconfig généré viaaws eks update-kubeconfig). Surface d'attaque élargie (le runner self-hosted est déjà un SPOF, cf. #35). - Déploiement impératif :
kubectl applyne supprime pas les ressources retirées dek8s/base/(pas de prune natif), l'état dérive au fil des releases. - GitOps était annoncé dans le README depuis le Sprint 3 (« GitLab Agent for Kubernetes ») mais jamais livré.
Décision 1 — ArgoCD plutôt que GitLab Agent
Le plan initial (README Sprint 3) prévoyait le GitLab Agent for Kubernetes. On retient ArgoCD à la place :
| Critère | ArgoCD | GitLab Agent |
|---|---|---|
| Adoption marché | Standard de facto CNCF (incubating→graduated) | Spécifique GitLab |
| UI | Riche (arbre de ressources, diff, sync, health) | Limitée |
| Visibilité entretiens | Forte (compétence demandée) | Faible |
| Découplage du forge | Agnostique (lit n'importe quel repo Git) | Couplé GitLab |
| Multi-cluster / app-of-apps | Natif | Moins mature |
La visibilité en entretien et la portabilité (même outil sur EKS, homelab, platform) priment. Déviation assumée par rapport au README initial.
Décision 2 — Pull-based avec write-back CI
Le flux devient pull-based : ArgoCD réconcilie le cluster depuis Git, la CI n'accède plus au cluster.
1. commit applicatif sur develop
2. pipeline : build image :SHA → scan → promote (inchangé)
3. job update-image-tag : kustomize edit set image fastapi=$IMAGE_SHA
→ commit "ci: bump ... [skip ci]" → push sur develop
4. ArgoCD détecte le commit → sync → rollout
Le tag d'image est désormais commité dans k8s/base/kustomization.yaml
(champ images:), versionné dans Git. ArgoCD déploie exactement ce que contient
Git : Git devient la source de vérité unique.
Le job deploy (kubectl apply) est supprimé. La CI ne détient plus de
kubeconfig, ne fait plus d'accès cluster au déploiement.
Décision 3 — App-of-apps
L'installation et la configuration ArgoCD sont posées par le bootstrap Ansible
(MR !145, #72). Un root Application (apps) surveille
k8s/platform/argocd-apps/ et gère les Application CRs qui s'y trouvent (dont
fastapi → k8s/base/). Ajouter une future Application (observabilité #74) =
déposer un fichier dans ce répertoire, ArgoCD le découvre. Pattern app-of-apps.
automated.prune: true + selfHeal: true : ArgoCD supprime ce qui disparaît de
Git (résout le manque de prune du kubectl apply) et corrige tout drift manuel.
Le piège de la boucle CI
Le job update-image-tag pousse un commit sur develop. Sans précaution, ce
commit relancerait un pipeline, qui re-bumperait, qui re-pousserait → boucle
infinie. Le message de commit contient [skip ci] : GitLab n'instancie alors
aucun pipeline pour ce commit. La chaîne s'arrête après un seul write-back.
Conséquences
- Token de push : le job pousse sur
develop(branche protégée). Nécessite un Project Access Token (rôle Maintainer, scopewrite_repository) en variable CI masquéeGITLAB_PUSH_TOKEN, autorisé en push sur la règle de protection dedevelop. LeCI_JOB_TOKENpar défaut ne peut pas pousser. - Infra down : si le cluster est éteint (éphémère), le write-back écrit quand
même le tag dans Git. Au prochain
aws-start, ArgoCD réconcilie le dernier tag présent dans Git. Git reste la source de vérité, la convergence est différée. - Deux commits par release : le commit applicatif + le commit de bump
[skip ci]. Fonctionnement nominal du write-back GitOps. - Teardown : les Applications ArgoCD doivent être supprimées en premier (le
selfHealrecréerait l'HTTPRoute, donc l'ELB → orphelin bloquantterraform destroy, classe INC-016). Géré dansteardown.yml(MR !145).
Évolution possible
- Image Updater ArgoCD : automatiserait le bump de tag sans job CI (ArgoCD scrute l'ECR). Écarté pour l'instant : le write-back CI garde la trace du tag dans Git (auditabilité) et évite de donner à ArgoCD un accès ECR.
- Sync waves / hooks : ordonnancement fin des ressources si besoin (migrations Alembic avant rollout). Pas nécessaire au périmètre actuel.
Date : 2026-06-11 Sprint : 4 Issue : #72