Table des matières :
- Le duo GitHub Actions + Argo CD : CI et CD qui arrêtent de se marcher dessus
- Prérequis et design du repo : la partie que tout le monde zappe (et regrette)
- Étape CI avec GitHub Actions : build, tests, scan, SBOM, signature
- Étape GitOps : mettre à jour les manifests et laisser Argo CD déployer (sans SSH sauvage)
- Multi-environnements, promotion et rollback : du “ça passe en prod” au “on dort la nuit”
- Durcir la pipeline CI/CD Kubernetes : supply chain, RBAC, policies et (un peu) de paranoïa utile
- Exploitation : une CD rapide ne remplace pas le MCO/MCS (désolé)
Vous voulez une pipeline CI/CD Kubernetes propre, reproductible, auditée… et surtout sans le fameux « je me connecte en prod pour appliquer un patch rapide » (aka la future post‑mortem). Le combo GitHub Actions (CI) + Argo CD (CD en GitOps) est aujourd’hui l’un des chemins les plus pragmatiques : la CI fabrique des artefacts, la CD réconcilie l’état désiré depuis Git.
Dans cet article, on déroule une mise en place étape par étape, avec des choix techniques qui tiennent la route pour des équipes qui livrent vraiment (e‑commerce, APIs, back‑offices) et qui ont compris que “ça marche sur mon laptop” n’est pas une stratégie de production.
Le duo GitHub Actions + Argo CD : CI et CD qui arrêtent de se marcher dessus
Dans une pipeline CI/CD Kubernetes, il faut arrêter de mélanger les responsabilités. La CI (Continuous Integration) compile, teste, build, scanne, signe. La CD (Continuous Delivery/Deployment) déploie. Le déploiement “depuis la CI” via un kubectl apply avec un kubeconfig en secret GitHub, c’est pratique… jusqu’au jour où vous devez expliquer à l’audit pourquoi un token cluster-admin traînait dans un runner.
Argo CD formalise le modèle GitOps : le cluster est géré par reconcilation d’un état désiré versionné. La définition officielle est claire : “Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.” (Documentation Argo CD : https://argo-cd.readthedocs.io/en/stable/). Concrètement, Argo CD observe un repo Git et applique automatiquement les manifests (Helm, Kustomize, YAML) sur le cluster, en continu.
Le terme GitOps n’est pas une mode marketing sortie d’un chapeau : Weaveworks (qui a popularisé le concept) le décrit comme une manière d’implémenter le continuous deployment pour des applications cloud‑native, en s’appuyant sur Git comme source de vérité (Weaveworks GitOps : https://www.weave.works/technologies/gitops/). Traduction opérationnelle : Git devient la source de vérité, et Kubernetes exécute une boucle de contrôle (comme ses contrôleurs natifs) pour converger vers cet état. Résultat : des déploiements traçables, des rollbacks par revert, et des environnements cohérents.
Un repère simple pour éviter les erreurs de design :
CI = produire des preuves + un artefact immuable (image taggée, SBOM, signature, attestation).
CD = converger vers un état déclaré (manifests versionnés, politiques appliquées, audit trail).
Accès cluster = “pull” par Argo CD, pas “push” depuis un runner CI.
Dans la pratique (et c’est là que ça devient concret), ça évite 3 problèmes récurrents :
1) des secrets “trop puissants” disséminés ;
2) une prod impossible à reconstruire ;
3) des déploiements sans traçabilité (“qui a appliqué quoi, quand, et pourquoi ?”).
Prérequis et design du repo : la partie que tout le monde zappe (et regrette)
Avant d’écrire une ligne de YAML GitHub Actions, fixez les prérequis : un cluster Kubernetes (managé ou non), un registry (GHCR, ECR, GCR/Artifact Registry, Harbor…), une stratégie de noms d’images, et une gestion DNS/Ingress propre. Si votre prod repose sur du stockage persistant, prévoyez vos classes CSI/PVC dès maintenant, pas après avoir cassé un StatefulSet : le sujet est vaste, et on a déjà détaillé les implications RWO/RWX, Ceph/Longhorn, etc. dans Stockage distribué Kubernetes : PVC/CSI, RWO-RWX, Ceph et Longhorn.
Checklist “avant de commencer” (simple, mais ça évite des semaines de bricolage) :
Registry accessible depuis votre cluster (egress, DNS, auth OK)
Politique de tagging (au minimum
sha+ éventuellementsemver)Namespace(s) par environnement + conventions (labels, quotas)
Ingress Controller + certificats (ACME/Let’s Encrypt ou PKI interne)
Observabilité de base (logs + métriques) disponible dès le premier déploiement
Stratégie secrets compatible GitOps (SOPS/External Secrets)
Côté repositories, deux patterns dominent :
1 repo (monorepo) : code applicatif + manifests. Simple au départ, mais attention aux droits d’écriture (la CI modifie Git, Argo lit Git).
2 repos :
app-repopour le code,gitops-repopour les manifests/environnements. C’est le plus sain : l’artefact (image) vit dans le registry, et l’état désiré vit dans le repo GitOps.
Pour décider vite, voici une lecture “terrain” :
| Pattern | Avantages | Inconvénients | Quand l’utiliser |
|---|---|---|---|
| 1 repo | Démarrage rapide, moins de friction | Couplage CI ↔ CD, droits d’écriture plus sensibles | POC, petite équipe, faible exigence de gouvernance |
| 2 repos | Gouvernance claire, séparation des droits, audit facilité | Un peu plus de workflow (PR inter-repo) | Environnements multiples, production critique, exigences sécurité/compliance |
Un layout efficace pour Kustomize ressemble à ça :
gitops-repo/
apps/myapp/
base/
deployment.yaml
service.yaml
kustomization.yaml
overlays/
dev/
staging/
prod/
Petit détail qui change tout : dans base/, gardez ce qui est commun et stable (labels, ports, service account, PDB, probes). Dans overlays/*, ne surchargez que les différences (replicas, ressources, endpoints externes, feature flags).
Dernier point (et pas le moins drôle) : les secrets. Stocker des secrets Kubernetes “en clair” dans Git, c’est une manière élégante de se faire du mal. Utilisez un modèle GitOps compatible : SOPS + KMS (AWS/GCP/Azure) ou External Secrets Operator. Et pour la CI, préférez l’authentification OIDC plutôt que des clés longue durée quand c’est possible (ex : cloud providers, registre). La sécurité n’est pas une option cosmétique : elle fait partie du design, comme on le rappelle dans DevSecOps-as-a-service : intégrer la sécurité au pipeline CI/CD.
Exemple de piège courant en équipe : “on chiffre les secrets plus tard”. En réalité, dès qu’un repo GitOps est cloné sur un laptop, indexé, ou partagé avec un prestataire, vous avez multiplié les surfaces de fuite. SOPS ou External Secrets évitent précisément ce scénario.
Étape CI avec GitHub Actions : build, tests, scan, SBOM, signature
GitHub Actions est très bon pour industrialiser la CI tant que vous évitez deux pièges classiques : 1) des workflows copiés/collés sans compréhension, 2) des runners qui ont plus de privilèges que votre SRE. La doc officielle pose les bases : https://docs.github.com/actions. Dans une pipeline CI/CD Kubernetes moderne, votre CI doit produire un artefact immuable (image taggée par SHA) et des preuves (SBOM, signature) plutôt qu’un zip anonyme “v2-final-final”.
Voici une version compacte mais réaliste d’un workflow CI : build multi-arch (facultatif), cache, tests, scan, push. (Exemple sur GHCR, ajustez le registry.)
name: ci
on:
push:
branches: [ main ]
permissions:
contents: read
packages: write
id-token: write
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/org/myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Scan image (Trivy)
uses: aquasecurity/[email protected]
with:
image-ref: ghcr.io/org/myapp:${{ github.sha }}
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
À enrichir (sans transformer le pipeline en sapin de Noël), les étapes CI qui ont le meilleur ROI :
Tests : au minimum unitaires + un smoke test (ou une intégration légère). Sans ça, vous automatisez juste l’échec.
Validation Kubernetes “shift-left” : valider vos manifests avant même qu’Argo les voie (schémas, politiques). Des outils comme
kubeconform/kubevalouconftest(OPA) permettent de bloquer un YAML invalide avant qu’il ne devienne un incident.SBOM (Software Bill of Materials) via Syft/Grype ou les features natives de certains registries. Une SBOM sérieuse aide à répondre en minutes à “sommes‑nous impactés par CVE‑XXXX ?” au lieu de “on va grepper des containers au hasard”.
Signature d’image (Sigstore Cosign) avec OIDC pour éviter des clés privées qui traînent. Cosign : https://docs.sigstore.dev/cosign/ ; et si vous voulez cadrer la supply chain : SLSA https://slsa.dev/.
Une manière simple de garder une CI lisible : produisez 3 sorties “auditables” par build :
1) une image :sha (immuable),
2) une SBOM attachée à l’image (ou publiée en artifact),
3) une signature / attestation (Cosign).
Et côté tagging : gardez le sha comme vérité, et éventuellement un tag “humain” (v1.8.2) qui pointe vers le même digest. Le sha traverse les environnements ; le semver sert à la lecture et au support.
Oui, ça ajoute des étapes. Non, ce n’est pas “du luxe” : c’est le minimum pour ne pas transformer votre CI/CD en distributeur automatique de vulnérabilités.
Étape GitOps : mettre à jour les manifests et laisser Argo CD déployer (sans SSH sauvage)
Une fois l’image poussée (ghcr.io/org/myapp:<sha>), le déploiement se fait en mettant à jour le repo GitOps (ou une branche env) avec la nouvelle référence d’image. Avec Kustomize, l’automatisation est triviale : kustomize edit set image myapp=.... Le point clé : vous ne déployez pas depuis GitHub Actions, vous déclarez un nouvel état désiré dans Git, puis Argo CD le réconcilie.
En pratique, la CI fait souvent :
checkout du
gitops-repomise à jour du tag d’image dans
overlays/dev(ou via un fichiervalues.yamlHelm)commit signé + PR
merge après validations (tests, approbation, policy)
Le PR devient votre artefact de gouvernance : review, historique, rollback simple. Et si quelqu’un “hotfix” le cluster à la main, Argo CD le verra comme drift et le corrigera (si selfHeal est activé). Vous gagnez une propriété rare : le cluster cesse d’être un animal sauvage impossible à reproduire.
Deux variantes courantes (choisissez selon votre contexte, pas selon la mode) :
PR obligatoire pour tout (y compris dev) : plus de gouvernance, plus de friction — utile quand vous avez beaucoup de contributeurs.
Auto-merge en dev, PR + approbation en prod : très bon compromis. GitHub permet de protéger
mainou des branchesprod/*via règles de protection et environnements “Production” avec reviewers obligatoires.
Côté Argo CD, l’installation standard passe par Helm (docs : https://argo-cd.readthedocs.io/en/stable/getting_started/). Ensuite, vous déclarez une Application (ou mieux : des ApplicationSet si multi‑apps). Exemple minimaliste :
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/gitops-repo.git
targetRevision: main
path: apps/myapp/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: myapp
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Le sarcasme du jour : si vous activez prune: true sans comprendre votre repo, vous découvrirez la joie de “ça marche, et maintenant ça supprime des ressources”. Faites-le, mais avec des conventions strictes, des AppProjects/RBAC, et des protections de branches.
Astuce très “prod” : avant de mettre prune partout, commencez par :
activer Argo CD en mode observateur (sync manuel) sur un env non critique,
stabiliser les conventions de manifests (noms, labels, ownership),
puis activer l’automatisation progressivement (dev → staging → prod).
Multi-environnements, promotion et rollback : du “ça passe en prod” au “on dort la nuit”
Le multi‑env n’est pas un répertoire prod/ copié-collé de staging/ (sinon vous faites du “multi‑catastrophe”). Avec Kustomize, vous partagez un base/ commun et vous ne surchargez que ce qui varie : replicas, HPA, ressources, URLs, secrets externes, etc. Avec Helm, même idée via des values-*.yaml. La règle : une seule manière de déployer, plusieurs paramètres.
La promotion devrait être un changement Git explicite : même image SHA promue de dev → staging → prod. Le gain est énorme : vous arrêtez de reconstruire une image “équivalente” (qui ne l’est jamais) et vous suivez un artefact identique qui traverse les environnements. Si vous voulez que “ce qui a été testé” soit “ce qui est en prod”, c’est littéralement la définition.
Mini-schéma de promotion (très efficace en équipe) :
devse met à jour automatiquement surmain(feedback rapide)stagingse met à jour via PR “promotion” (validation produit/QA)prodse met à jour via PR dédiée + approbation + fenêtre de déploiement si nécessaire
Pour les stratégies avancées, Argo CD s’intègre très bien avec Argo Rollouts (canary/blue‑green) : https://argo-rollouts.readthedocs.io/. Dans un contexte e‑commerce, un canary à 5% avec analysis sur erreurs 5xx, p95 latency et taux de checkout est souvent plus rentable qu’un big‑bang à midi. Branchez vos métriques sur Prometheus (et oui, il faut le faire proprement) : Prometheus monitoring : quickstart en 5 minutes et mise en production et, si vous voulez corréler traces/logs/métriques sans réinventer la roue, OpenTelemetry : unifier métriques, traces et logs pour l’observabilité.
Le rollback, enfin, redevient civilisé : un git revert du commit de déploiement, Argo CD resynchronise, fin de l’histoire. C’est plus fiable que kubectl rollout undo parce que l’état désiré reste cohérent avec Git. Oui, ça implique de respecter Git comme source de vérité. Non, “j’ai patché un ConfigMap à la main” n’est pas une excuse recevable.
Point d’attention “réel” : un revert est rapide… si votre app sait redémarrer proprement. Des readinessProbe et startupProbe bien calibrées font une énorme différence (doc Kubernetes : https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/). Une probe trop agressive peut transformer un rollback en boucle de crash.
Durcir la pipeline CI/CD Kubernetes : supply chain, RBAC, policies et (un peu) de paranoïa utile
Sécuriser une pipeline CI/CD Kubernetes, c’est d’abord réduire la surface d’attaque. Dans GitHub Actions : permissions minimales (permissions:), secrets au strict nécessaire, runners dédiés pour workloads sensibles, et OIDC partout où c’est supporté. Dans Kubernetes : Argo CD n’a pas besoin d’être cluster-admin par défaut. Utilisez AppProject, namespaces dédiés, et des comptes de service restreints. Le “ça ira” finit toujours en “on a eu un incident”.
Concrètement, une base “least privilege” pour Argo CD, c’est :
un
AppProjectqui limite les namespaces et les types de ressources autorisés,une segmentation par équipes (prod séparée, ou projets séparés),
et des droits en lecture seule pour la majorité des utilisateurs (l’UI Argo sert aussi d’outil d’audit).
Ensuite, ajoutez des garde‑fous policy-as-code : Kyverno (https://kyverno.io/) ou OPA Gatekeeper (https://open-policy-agent.github.io/gatekeeper/). Exemple de règles utiles : interdire les images :latest, imposer runAsNonRoot, exiger des requests/limits, bloquer les privileges escalation, vérifier la présence d’une signature Cosign avant admission (policies Sigstore). C’est la différence entre “on espère que les devs font bien” et “le cluster refuse ce qui est dangereux”.
Un bon compromis pour ne pas bloquer toute l’équipe dès J1 :
mode audit d’abord (observer les violations),
puis enforcement sur un petit set de règles à très fort impact (pas de
latest, pas de privileged pods, requests/limits obligatoires),puis extension progressive (signatures, provenance, restrictions réseau).
Enfin, n’oubliez pas l’environnement d’exposition : WAF, rate limiting, DDoS, règles L7. Une CD parfaite ne sert à rien si votre appli se fait pilonner et que votre edge est permissif “par simplicité”. Si vous êtes sur Cloudflare, vous pouvez compléter avec des règles WAF sur-mesure : Cloudflare Custom Rules : créer et gérer des règles WAF personnalisées et, pour la menace volumétrique, garder un œil sur le paysage 2026 : Protection DDoS cloud 2026 : comparatif des 12 meilleures solutions.
Exploitation : une CD rapide ne remplace pas le MCO/MCS (désolé)
Automatiser le déploiement ne vous dispense pas de l’exploitation. Une pipeline CI/CD Kubernetes sérieuse inclut des signaux de prod : SLI/SLO, alerting, erreurs applicatives, saturation CPU/mémoire, latence réseau, erreurs Ingress, saturation base de données. Les “déploiements verts” qui masquent une latence p95 qui explose, c’est juste une manière polie de dégrader l’expérience client.
Côté coûts et fiabilité, les détails comptent : requests/limits correctement dimensionnés (sinon le scheduler joue à la roulette), HPA sur des métriques pertinentes, PDB (PodDisruptionBudget) pour éviter les évictions en chaîne, et des probes (startupProbe/readinessProbe) réalistes. Sur des stacks e‑commerce, l’observabilité côté navigateur peut aussi compléter la vue serveur : Real User Monitoring : RUM vs monitoring synthétique pour la performance web.
Un scénario classique (et très coûteux) : la pipeline déploie vite, mais l’équipe n’a pas de seuils d’alerte sur la saturation DB ou sur les timeouts upstream. Résultat : le “déploiement s’est bien passé” côté Argo CD, mais le taux d’erreur grimpe côté clients. Le GitOps ne remplace pas le pilotage de prod ; il le rend simplement plus contrôlable.
Si vous voulez industrialiser tout ça au niveau organisationnel (process, durcissement, runbooks, astreinte, patching), c’est exactement le périmètre du Maintien en Conditions Opérationnelles / Sécurité : MCO/MCS et des chantiers DevOps structurés : DevOps : création et optimisation d’infrastructures d’hébergement. Et si votre plateforme vise la très haute dispo (pas “99% sur un PowerPoint”), regardez aussi l’option Hébergement d’infrastructures THD (Très Haute Disponibilité). Pour discuter d’une implémentation GitOps réaliste (et pas une démo), vous pouvez passer par la page Contacter Les Vikings.