Tu as installé ArgoCD, tu as déployé ta première Application CRD. Maintenant on passe aux choses sérieuses : sync policies fines, orchestration avec les waves, déploiement multi-cluster, et ApplicationSet pour gérer des dizaines d’apps sans copier-coller. C’est ce qui sépare un PoC d’un ArgoCD production-ready.
Sync Policies : contrôler le quand et le comment
La sync policy détermine comment ArgoCD réagit quand Git et le cluster divergent. Trois modes existent : manual (tu cliques), automated (ArgoCD sync tout seul), et automated+prune (il supprime aussi les ressources orphelines).
🔥 En production, le combo automated + selfHeal + prune est le standard. Le self-heal corrige tout drift manuel en quelques secondes — plus personne ne peut faire de kubectl edit sauvage sans que ça soit écrasé.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-production
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/org/gitops-repo.git
targetRevision: main
path: environments/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
- PruneLast=true
- PrunePropagationPolicy=foreground
- RespectIgnoreDifferences=true
Ignore Differences
Certains champs sont gérés par Kubernetes lui-même (replicas via HPA, clusterIP). Sans ignoreDifferences, ArgoCD les détecte comme du drift et boucle en sync infini.
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # Géré par HPA
- group: ""
kind: Service
jqPathExpressions:
- .spec.clusterIP # Auto-assigné par K8s
💡 Utilise jqPathExpressions plutôt que jsonPointers pour les cas complexes — la syntaxe jq est plus puissante et lisible.
Sync Waves et Hooks : orchestrer le déploiement
Un déploiement réel n’est pas un kubectl apply en vrac. La base de données doit exister avant la migration, la migration avant l’app, l’app avant l’ingress. Les sync waves ordonnent tout ça via une simple annotation.
# Wave -1 : Namespace (en premier)
apiVersion: v1
kind: Namespace
metadata:
name: production
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
# Wave 0 : ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
annotations:
argocd.argoproj.io/sync-wave: "0"
data:
DATABASE_URL: "postgres://db:5432/app"
---
# Wave 1 : Migration Job (hook PreSync)
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
annotations:
argocd.argoproj.io/sync-wave: "1"
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
template:
spec:
containers:
- name: migrate
image: ghcr.io/org/myapp:latest
command: ["./migrate", "up"]
restartPolicy: Never
---
# Wave 2 : Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: ghcr.io/org/myapp:latest
Les hooks complètent les waves. PreSync exécute un job avant le sync (migration, health check). PostSync lance les smoke tests après. SyncFail notifie Slack si ça casse. Chaque hook est un Job Kubernetes classique avec une annotation en plus.
⚠️ Oublie pas hook-delete-policy: BeforeHookCreation — sans ça, le Job précédent bloque le nouveau sync parce que Kubernetes refuse de créer un Job avec le même nom.
Multi-cluster : un ArgoCD pour les gouverner tous
ArgoCD gère nativement plusieurs clusters depuis une seule instance. Tu enregistres les clusters distants, et chaque Application pointe vers son destination.server.
# Ajouter un cluster distant
argocd cluster add production-eu \
--kubeconfig ~/.kube/production-eu.yaml \
--name production-eu
# Vérifier les clusters enregistrés
argocd cluster list
# SERVER NAME STATUS
# https://kubernetes.default.svc in-cluster Successful
# https://k8s.eu.company.com production-eu Successful
# https://k8s.us.company.com production-us Successful
🎯 L’architecture recommandée : un management cluster dédié qui héberge ArgoCD et pilote tous les clusters applicatifs. Ça isole le plan de contrôle GitOps du workload.
En pratique, ArgoCD stocke les credentials de chaque cluster dans un Secret Kubernetes du namespace argocd. Le app-controller se connecte ensuite à chaque cluster pour réconcilier. Attention à la latence réseau et aux firewalls — le management cluster doit pouvoir atteindre l’API server de chaque cluster cible.
ApplicationSet : scaler sans copier-coller
Quand tu gères 5 apps sur 3 clusters, ça fait 15 Applications à maintenir. À la main, c’est ingérable. L’ApplicationSet génère automatiquement des Applications à partir de templates et de générateurs.
Git Directory Generator
Le plus courant : une Application par dossier dans le repo.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: all-apps
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/org/gitops-repo.git
revision: main
directories:
- path: apps/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/org/gitops-repo.git
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Tu ajoutes un dossier apps/new-service/ dans Git → ArgoCD crée automatiquement l’Application correspondante. Tu supprimes le dossier → l’Application disparaît.
Matrix Generator : le produit cartésien
Le Matrix combine deux générateurs. Clusters × Apps = déploiement automatique de chaque app sur chaque cluster.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: multi-cluster-apps
namespace: argocd
spec:
generators:
- matrix:
generators:
- clusters:
selector:
matchLabels:
env: production
- git:
repoURL: https://github.com/org/gitops-repo.git
revision: main
directories:
- path: apps/*
template:
metadata:
name: '{{name}}-{{path.basename}}'
spec:
project: production
source:
repoURL: https://github.com/org/gitops-repo.git
targetRevision: main
path: '{{path}}'
destination:
server: '{{server}}'
namespace: '{{path.basename}}'
💡 Le Pull Request Generator est aussi très puissant : il crée un environnement preview éphémère pour chaque PR labelisée. La PR est mergée ou fermée → l’environnement est automatiquement détruit.
Cas entreprise : workflow production complet
Une fintech avec 20 microservices sur 3 clusters (EU, US, staging). Avant ArgoCD avancé : chaque équipe avait ses propres scripts de déploiement, pas de visibilité centralisée, du drift partout.
Leur setup après migration :
- 1 ApplicationSet Matrix : 20 apps × 3 clusters = 60 Applications générées automatiquement
- Sync waves : namespace → secrets (External Secrets) → DB → migration → app → ingress
- Sync windows : déploiements bloqués entre 22h et 6h, et le weekend sur les clusters prod
- PostSync hooks : smoke tests automatiques après chaque déploiement
- SyncFail hooks : notification Slack + PagerDuty si un sync échoue
Résultat : le temps de déploiement est passé de 45 minutes (scripts custom) à 3 minutes (push Git → sync automatique). Le nombre d’incidents liés au drift a chuté de 80%.
Pièges classiques et résumé
⚠️ Le app-controller OOM — Avec 100+ Applications, le app-controller consomme beaucoup de RAM. Augmente ses resources limits et active le sharding : --application-controller-shard répartit la charge sur plusieurs replicas.
⚠️ Le prune qui supprime trop — Un fichier YAML supprimé par erreur du repo = ressource supprimée en prod. Solution : active PruneLast et configure des sync windows qui imposent un délai. Utilise aussi argocd app sync --dry-run pour prévisualiser.
⚠️ Les secrets dans Git — ArgoCD ne résout pas le problème des secrets. Utilise External Secrets Operator (récupère depuis Vault/AWS SM), Sealed Secrets (chiffrement asymétrique), ou SOPS avec age/KMS. Jamais de secret en clair dans le repo.
🔥 Le webhook plutôt que le polling — Par défaut, ArgoCD poll Git toutes les 3 minutes. Configure un webhook GitHub/GitLab pour un sync quasi-instantané : https://argocd.company.com/api/webhook avec un shared secret.
🎯 Les sync policies (automated, prune, selfHeal) sont le cœur d’ArgoCD — elles garantissent que le cluster reflète Git en permanence.
Les sync waves ordonnent les déploiements complexes. Les hooks (PreSync, PostSync, SyncFail) ajoutent de la logique autour du sync.
Le multi-cluster est natif : une instance ArgoCD pilote tous tes clusters depuis un management cluster dédié.
L’ApplicationSet est indispensable pour scaler. Git Generator pour les dossiers, Matrix Generator pour le produit clusters × apps, PR Generator pour les environnements preview.
En production, combine tout : ApplicationSet + sync waves + sync windows + hooks + ignoreDifferences. C’est la recette d’un GitOps robuste et maintenable.
🖥️ Pratique sur ton propre serveur
Pour suivre GitOps & ArgoCD en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSérie : GitOps & ArgoCD
4 / 6Sur cette page
Articles liés
GitOps : principes et architecture
Les fondamentaux du GitOps : définition, avantages, push vs pull model et architecture de référence pour tes déploiements Kubernetes.
Workflow GitOps et comparaison des outils
Le workflow GitOps complet étape par étape, comparaison ArgoCD vs FluxCD vs Jenkins X, patterns avancés et anti-patterns à éviter.
ArgoCD : installation et Application CRD
Architecture ArgoCD, installation production-ready avec Helm, Application CRD et AppProject pour l'isolation et le RBAC.