Aller au contenu
CI/CD & Automatisation medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

ArgoCD — Intégration CI/CD et pipeline GitOps

11 min de lecture

La CI construit et valide. ArgoCD déploie. Ces deux responsabilités ne doivent pas se mélanger. Ce guide vous montre comment câbler votre pipeline CI à ArgoCD en respectant la règle d’or GitOps : la CI ne touche jamais le cluster, elle met à jour Git. Deux méthodes sont couvertes : la mise à jour manuelle du tag d’image dans Git, et l’automatisation complète avec ArgoCD Image Updater.

  • La séparation des rôles : CI (build + push image) vs ArgoCD (déploiement depuis Git)
  • Mettre à jour le tag d’image dans le config-repo depuis un pipeline CI, sans accès cluster
  • Gérer les credentials Git dans la CI (deploy key SSH ou Personal Access Token)
  • Exemples complets GitHub Actions et GitLab CI validés (epinglés par SHA, permissions minimales)
  • Attendre la synchronisation ArgoCD depuis la CI avant de lancer les tests d’intégration
  • ArgoCD Image Updater : automatiser la mise à jour du tag sans script

En architecture GitOps, le cluster n’est visible que depuis Git. Votre pipeline CI n’a donc aucune raison d’avoir un accès direct au cluster. Voici la séparation des rôles :

PhaseResponsableAction
Build & testPipeline CIBuild, tests, lint, scan de sécurité
Publication imagePipeline CIPush de l’image monapp:a1b2c3d dans le registre
Mise à jour de GitPipeline CIModifie le tag dans les manifestes du config-repo
DéploiementArgoCDDétecte le commit, réconcilie le cluster

La CI n’exécute jamais kubectl apply ni helm upgrade. Elle pousse seulement un commit dans le config-repo.

Cette méthode est simple et portable. Le pipeline CI, après avoir buildé et poussé l’image, clone le config-repo, modifie le tag, et pousse un commit.

update-tag.sh
#!/bin/bash
set -euo pipefail
IMAGE_TAG="${1}" # Exemple : sha-a1b2c3d
APP_PATH="${2}" # Exemple : nginx-demo/deployment.yaml
CONFIG_REPO_URL="${3}" # URL SSH du config-repo
# Cloner le config-repo
git clone "${CONFIG_REPO_URL}" config-repo
cd config-repo
# Mettre à jour le tag avec yq (ou sed)
yq -i ".spec.template.spec.containers[0].image = \"nginx:${IMAGE_TAG}\"" \
"${APP_PATH}"
# Pousser le commit
git config user.email "ci-bot@example.com"
git config user.name "CI Bot"
git add "${APP_PATH}"
git commit -m "chore(deploy): update nginx to ${IMAGE_TAG}"
git push origin main

yq est l’outil recommandé pour manipuler du YAML en ligne de commande. Si vous ne pouvez pas l’installer, sed fonctionne aussi pour les cas simples :

Fenêtre de terminal
sed -i "s|image: nginx:.*|image: nginx:${IMAGE_TAG}|" "${APP_PATH}"

Le pipeline CI doit s’authentifier sur le config-repo. Deux méthodes :

MéthodeAvantageInconvénient
Deploy key SSHAccès limité à un seul dépôtGestion des clés dans CI
Personal Access TokenSimple à créerDroit d’accès plus large

Stockez ces credentials dans les secrets de votre CI (GitHub Secrets, GitLab CI/CD Variables), jamais dans le code.

.github/workflows/build-and-deploy.yml
name: Build and Deploy
on:
push:
branches: [main]
permissions:
contents: read # Lecture du code source uniquement
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # Pour pousser l'image sur GHCR
outputs:
image_tag: ${{ steps.meta.outputs.version }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Docker meta
id: meta
uses: docker/metadata-action@902fa8ec7d6ecacf9f59e2d269c9b7f7e1c6a7e4 # v5.7.0
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=sha,prefix=sha-
- name: Login to GHCR
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
update-config-repo:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.CONFIG_REPO_DEPLOY_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan github.com >> ~/.ssh/known_hosts
- name: Install yq
run: |
YQ_VERSION="v4.44.3"
curl -sSLo /usr/local/bin/yq \
"https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64"
chmod +x /usr/local/bin/yq
- name: Update image tag in config-repo
env:
IMAGE_TAG: ${{ needs.build.outputs.image_tag }}
run: |
git clone git@github.com:votre-org/config-repo.git
cd config-repo
yq -i ".spec.template.spec.containers[0].image = \
\"ghcr.io/votre-org/monapp:${IMAGE_TAG}\"" \
nginx-demo/deployment.yaml
git config user.email "gh-actions@example.com"
git config user.name "GitHub Actions"
git add nginx-demo/deployment.yaml
git diff --staged --quiet || \
git commit -m "chore(deploy): update monapp to ${IMAGE_TAG}"
git push origin main

Une fois le commit poussé sur le config-repo, vous pouvez vouloir attendre qu’ArgoCD finisse de déployer avant de passer à la suite (tests d’intégration par exemple). Pour cela, exposez l’API ArgoCD et utilisez le CLI :

Fenêtre de terminal
# Attendre la synchronisation et un état Healthy
argocd app wait nginx-demo \
--health \
--sync \
--timeout 120 \
--server argocd.example.com \
--auth-token "$ARGOCD_TOKEN"

Créez un token ArgoCD dédié pour la CI (voir le guide Sécuriser ArgoCD) avec uniquement les droits get et sync sur les Applications concernées.

Si vous souhaitez aller plus loin et éliminer le script de mise à jour, l’outil ArgoCD Image Updater surveille votre registre de conteneurs et met à jour Git à votre place dès qu’une nouvelle image est publiée.

Fenêtre de terminal
kubectl apply -n argocd \
-f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml

Ajoutez des annotations à votre objet Application :

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-demo
namespace: argocd
annotations:
argocd-image-updater.argoproj.io/image-list: nginx=nginx
argocd-image-updater.argoproj.io/nginx.update-strategy: semver
argocd-image-updater.argoproj.io/nginx.allow-tags: regexp:^1\.27
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/git-branch: main

Avec cette configuration, dès qu’une image nginx:1.27.* plus récente est publiée sur Docker Hub, Image Updater met à jour le fichier de manifestes dans Git. ArgoCD détecte le commit et déploie.

  • La CI ne fait jamais kubectl apply ni helm upgrade. Elle pousse un commit dans le config-repo. ArgoCD doit déployer.
  • Séparez app-repo (code applicatif) et config-repo (manifestes de déploiement) pour des droits d’accès distincts.
  • Stockez les credentials Git dans les secrets CI, jamais dans le code.
  • Utilisez yq pour modifier proprement les YAML plutôt que sed.
  • La commande argocd app wait permet d’attendre la fin du déploiement dans un pipeline.
  • ArgoCD Image Updater automatise la détection de nouvelles images et la mise à jour de Git.
  • Épinglez toujours les GitHub Actions par SHA de commit.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn