Aller au contenu
Helm et GitOps

Helm et GitOps

300 Concevoir ⏱ 1 h 20 helmargocdkubernetesoci

À la fin, vous saurez

  • Expliquer ce qu'Argo CD fait d'un chart Helm, et ce qui disparaît faute de release Helm
  • Écrire une Application dont la source est un chart OCI, avec des valeurs d'environnement venues de Git
  • Comparer le modèle d'Argo CD (rendu) à celui de Flux (release Helm réelle) et choisir selon le besoin
  • Promouvoir une version de chart de la recette à la production et automatiser les propositions de mise à jour
  • Diagnostiquer une dérive sans helm get manifest, et adopter une release Helm existante sans interruption

Prérequis

Testé avec argocd 3.5 flux 2.x helm 3.16.3 (poste), 4 (dans Argo CD 3.5) kubernetes 1.36 , vérifié le 5 octobre 2026

Pourquoi

Jusqu'ici, ce cours a traité Helm comme un outil de ligne de commande : on installe, on met à jour, on revient en arrière. Chez Lyneko, personne ne lance helm upgrade en production. Les applications sont déployées par Argo CD, qui lit l'état voulu dans Git et aligne le cluster dessus (GitOps avec Argo CD). La question de cette leçon est : que devient Helm dans ce modèle ?

La réponse surprend ceux qui connaissent bien Helm : presque tout ce qui fait la gestion de release disparaît. Argo CD ne fait pas helm install. Il se sert de Helm comme d'un moteur de modèles : il rend le chart en manifestes, et les applique lui-même. Il n'y a ni secret de release, ni historique Helm, ni helm rollback, et helm list ne montre rien. Les hooks sont traduits, les tests ignorés, et certaines fonctions de modèle (lookup) ne voient plus ce que vous croyiez.

Ce n'est pas un défaut. Le point de GitOps est que Git est l'historique et que l'agent réconcilie : une seconde comptabilité (celle de Helm) ferait doublon, et deux outils qui croient posséder les mêmes objets se disputent. Mais il faut savoir ce qu'on perd, pour ne pas le chercher, et ce que le chart doit respecter pour bien se comporter sous Argo CD.

La leçon couvre l'écriture de l'Application, la promotion d'une version entre environnements, la mise à jour automatique, le diagnostic de la dérive et l'adoption d'une release existante. Elle se termine par une liste de contrôle pour un chart destiné à GitOps. Le fil rouge est le chart signalements publié dans le registre OCI de Lyneko (leçon 9), et déployé sur le cluster Kapsule lyneko-apps. Les commandes qui parlent à un cluster ou à un registre sont décrites d'après la documentation ; seules les sorties de helm template ont été produites localement.

Les concepts

Argo CD rend, il n'installe pas

Pour une Application dont la source est un chart, le repo-server d'Argo CD :

  1. récupère le chart (depuis Git, un dépôt HTTP ou un registre OCI) et ses dépendances ;
  2. exécute l'équivalent de helm template avec le nom de release, l'espace de noms et les valeurs de l'Application ;
  3. renvoie la liste des manifestes au contrôleur, qui les compare à l'état du cluster et les applique (synchronisation).

Il n'y a pas de release Helm : aucun secret sh.helm.release.v1.* n'est créé, helm list ne montre rien, helm history et helm rollback n'ont rien à lire. Le « retour arrière » est un revert dans Git. Les objets du cluster sont suivis par Argo CD, par l'annotation argocd.argoproj.io/tracking-id, pas par Helm (GitOps avec Argo CD, leçon 3).

Ce qui change pour les modèles

Un chart rendu par helm template se comporte différemment d'un chart installé. Les différences se voient sur un chart d'essai qui affiche les objets .Release et .Capabilities et tente un lookup :

$ helm template signalements r -n recette
...
data:
  install: "true"
  upgrade: "false"
  revision: "1"
  service: "Helm"
  namespace: "recette"
  kube: "v1.31.0"
  existant: "vide"
  nombre: "E1s9uV"

Chaque ligne a une conséquence :

  • .Release.IsInstall est toujours vrai, IsUpgrade toujours faux, Revision vaut 1, quel que soit l'historique. Un modèle qui se comporte différemment à l'installation et à la mise à jour (génère un mot de passe seulement la première fois, par exemple) se comporte donc toujours comme à l'installation.
  • .Capabilities.KubeVersion n'est pas celle de votre cluster : sans indication, helm template suppose une version par défaut (ici v1.31.0, celle de la bibliothèque Helm du poste). Un modèle qui choisit une apiVersion selon les capacités peut donc rendre autre chose que ce que le cluster accepte. On corrige avec --kube-version, et Argo CD fournit la version du cluster cible au rendu : testez en local avec la même valeur.
  • lookup renvoie toujours vide : helm template ne contacte pas le cluster, la fonction ne trouve rien. Un chart qui s'appuie sur lookup (pour réutiliser un secret existant, par exemple) ne fait pas ce que vous croyez sous Argo CD.
  • Les valeurs aléatoires changent à chaque rendu. Deux appels successifs donnent E1s9uV, puis une autre valeur. Argo CD rend à chaque comparaison : un modèle qui utilise randAlphaNum rend l'application perpétuellement OutOfSync, comme le dit la leçon 5 du cours GitOps.

Un chart écrit pour GitOps est donc déterministe : le même contenu et les mêmes valeurs donnent exactement les mêmes manifestes, sans dépendre du cluster ni du hasard. Les mots de passe ne se génèrent pas dans un modèle : ils viennent d'un coffre, par un ExternalSecret, comme dans Signalements.

Où mettre les valeurs

Une Application Helm accepte les valeurs de plusieurs façons, et la documentation d'Argo CD donne leur priorité, de la plus faible à la plus forte :

  1. le values.yaml du chart ;
  2. les valueFiles (si plusieurs, le dernier l'emporte) ;
  3. values, un bloc de texte YAML dans l'Application ;
  4. valuesObject, la même chose en YAML structuré (plus lisible, validé par l'éditeur) ;
  5. parameters, des paires clé-valeur (équivalent de --set), les plus prioritaires.

Chez Lyneko, la règle est : les fichiers de valeurs par environnement vivent dans le dépôt de déploiement, et l'Application les référence. Elle évite de mettre les valeurs dans la définition de l'Application, où elles se mêlent à la configuration d'Argo CD (projet, destination, politique de synchronisation) et se relisent moins bien. parameters est réservé aux surcharges automatiques (un outil qui écrit le tag d'image), jamais aux valeurs d'un humain.

Sources multiples

Quand le chart est dans un registre et les valeurs dans Git, une Application a plusieurs sources. L'une d'elles porte un ref (un nom), que les autres utilisent dans leurs valueFiles sous la forme $nom/chemin. La documentation précise que cette variable résout vers la racine du dépôt référencé. Voici l'Application de Signalements en recette :

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: signalements-recette
  namespace: argocd
spec:
  project: signalements
  sources:
    - repoURL: rg.fr-par.scw.cloud/<espace>/charts
      chart: signalements
      targetRevision: 0.3.0
      helm:
        releaseName: signalements
        valueFiles:
          - $valeurs/environnements/recette/values.yaml
    - repoURL: https://forge.lyneko.example/plateforme/signalements-deploiement.git
      targetRevision: main
      ref: valeurs
  destination:
    server: https://kubernetes.default.svc
    namespace: recette
  syncPolicy:
    automated: {selfHeal: true}
    syncOptions: [CreateNamespace=true]

Quatre points à relever :

  • La première source est un chart OCI : repoURL désigne le dépôt du registre, chart son nom, targetRevision sa version. Pour les charts OCI publics, la documentation d'Argo CD écrit le repoURL sans préfixe oci://. Un registre privé demande en plus un identifiant, déclaré dans Argo CD comme secret de dépôt de type Helm avec OCI activé (voir la documentation sur les dépôts privés).
  • releaseName fixe .Release.Name : sans lui, ce serait le nom de l'Application (signalements-recette) et tous les objets changeraient de nom (leçon 3 du cours GitOps).
  • La seconde source n'apporte aucun manifeste : elle ne sert qu'à fournir $valeurs. Le fichier environnements/recette/values.yaml est relu à chaque commit de main.
  • Quand releaseName diffère du nom de l'Application, Argo CD pose l'étiquette app.kubernetes.io/instance avec le nom de l'Application, ce qui peut entrer en conflit avec un sélecteur qui compte sur le nom de la release : la documentation recommande de configurer application.instanceLabelKey dans ce cas. Les étiquettes de sélection de la leçon 6 sont construites à partir de .Release.Name : elles n'en souffrent pas, à condition que releaseName reste stable.

Flux, en comparaison

Flux CD, l'autre agent GitOps du marché, traite Helm d'une façon opposée. Sa ressource HelmRelease désigne un chart (chart ou chartRef vers une source, par exemple un OCIRepository), des valeurs, et le contrôleur Helm de Flux fait de vrais helm install et helm upgrade, avec le Helm SDK. Il y a donc une vraie release : helm list la montre, les secrets de release existent, les hooks Helm s'exécutent comme Helm l'entend, et helm test fonctionne (activé par .spec.test.enable). Le contrôleur rejoue l'installation quand le chart ou les valeurs changent, selon une politique de remédiation (réessais, retour arrière automatique).

La dérive est surveillée par la détection de dérive de la HelmRelease : un mode warn (alerte seulement) et un mode enabled (alerte et correction, en recréant ou modifiant les ressources), avec des règles d'exclusion en JSON Pointer.

Argo CDFlux (HelmRelease)
Renduhelm templatehelm install / upgrade réels
Release Helm dans le clusternonoui
lookup, .Release.IsUpgradesans effetfonctionnent
Hooks Helmtraduits en hooks Argo CDexécutés par Helm
helm testignorépris en charge
Retour arrièrerevert Gitremédiation de Helm, ou revert Git
Comparaisonétat rendu contre cluster, par ressourcedétection de dérive de la release
Un seul outil pour tout (Helm, Kustomize, manifestes)ouioui, avec des ressources différentes

Le choix se fait sur ce qu'on veut : avec Argo CD, on gagne un modèle unique (tout est rendu puis comparé, Helm n'est qu'un moteur) et une interface qui montre l'état de chaque objet ; avec Flux, on garde la sémantique complète de Helm, au prix d'un second état (la release) à réconcilier avec Git. Lyneko a choisi Argo CD ; la leçon n'oppose pas les deux, elle montre où est la frontière.

En pratique

Contrôler en local ce qu'Argo CD rendra

Avant de pousser, on reproduit le rendu avec les mêmes paramètres : même nom de release, même espace de noms, mêmes fichiers de valeurs, et la version de Kubernetes du cluster cible.

$ helm template signalements chart \
    --namespace recette \
    --kube-version 1.36.4 \
    -f environnements/recette/values.yaml > rendu.yaml

Le rendu doit être identique d'un appel à l'autre : lancez-le deux fois et comparez (diff). Une différence signale un modèle non déterministe, qui rendra l'application perpétuellement désynchronisée (now, randAlphaNum, uuidv4, ou une valeur qui dépend de l'ordre d'une table).

La même Helm doit rendre en local et dans Argo CD : le repo-server d'Argo CD 3.5 embarque Helm 4, quand le poste de la personne qui contribue a peut-être un Helm 3.16. Les deux produisent, pour presque tous les charts, le même résultat ; mais testez avec la version qui déploie, et vérifiez les notes de version à chaque mise à jour d'Argo CD (GitOps avec Argo CD, leçon 10).

Promouvoir une version de chart

Un chart est publié une fois, puis promu : la même version, la même empreinte, passe de la recette à la préproduction puis à la production. Rien n'est reconstruit. Dans le dépôt de déploiement :

environnements/
  recette/        values.yaml      # surcharges de la recette
  preproduction/  values.yaml
  production/     values.yaml
applications/
  signalements-recette.yaml        # targetRevision: 0.3.1
  signalements-preproduction.yaml  # targetRevision: 0.3.0
  signalements-production.yaml     # targetRevision: 0.3.0

Une promotion est un commit qui change une seule ligne, la targetRevision de l'Application de l'environnement suivant. C'est la structure décrite dans Structurer les dépôts et promouvoir. Le flux :

  1. la CI du dépôt de charts publie 0.3.1, la signe, et relève l'empreinte (leçon 9) ;
  2. une demande de fusion modifie signalements-recette.yaml : targetRevision: 0.3.1 ;
  3. la CI du dépôt de déploiement vérifie la signature (cosign verify sur l'artefact visé) et rend le chart avec les valeurs de l'environnement (helm template), puis le relecteur lit la différence de rendu ;
  4. après fusion, Argo CD synchronise la recette, et ses tests (hook PostSync, supervision) valident la version ;
  5. la même opération, un environnement à la fois, jusqu'à la production, avec une approbation humaine devant la production.

Pour que la promotion soit sans ambiguïté, l'empreinte est préférable à l'étiquette comme référence de ce qui est promu : la leçon 9 explique pourquoi. Vérifiez dans la documentation d'Argo CD de votre version si targetRevision accepte une empreinte pour une source OCI Helm ; si ce n'est pas le cas, protégez les étiquettes de version dans le registre, et gardez l'empreinte dans le message de commit et dans le journal de la promotion.

Le tag de l'image de l'application suit un autre chemin : il est dans les valeurs (image.tag) ou, si on le laisse vide, dans appVersion du chart. Fixer le tag dans le fichier de valeurs de chaque environnement donne le contrôle le plus fin (la production peut rester sur 1.2.0 pendant que la recette est en 1.3.0, avec le même chart) ; laisser vide lie l'image à la version du chart, plus simple, moins souple.

Mise à jour automatique avec Renovate

Pour ne pas surveiller à la main la sortie de nouvelles versions de charts, on délègue à Renovate, qui ouvre une demande de fusion quand une version plus récente existe. Son gestionnaire argocd sait lire les Applications d'Argo CD ; d'après sa documentation, il ne cherche aucun fichier par défaut : il faut lui dire où sont les Applications avec managerFilePatterns. Les charts d'un registre OCI passent par la source de données Docker, ceux d'un dépôt HTTP par la source Helm.

{
  "argocd": {
    "managerFilePatterns": ["/^applications/.+\\.yaml$/"]
  },
  "packageRules": [
    {
      "matchManagers": ["argocd"],
      "matchFileNames": ["applications/signalements-production.yaml"],
      "automerge": false
    }
  ]
}

(Configuration indicative : adaptez les noms de règles à votre version de Renovate, dont les options évoluent.) La logique recommandée : mise à jour automatique pour la recette, par demande de fusion fusionnée seule si les contrôles passent ; mise à jour manuelle (une demande de fusion à relire et à approuver) pour la préproduction et la production. Les mises à jour de l'application elle-même (le tag d'image) suivent le même schéma ; le cours GitOps présente aussi Argo CD Image Updater, avec ses réserves.

Renovate ne remplace ni la relecture ni les tests : il propose, la CI contrôle (signature, rendu), un humain approuve la production.

Dérive, et helm get manifest inutile

Avec Helm seul, la question « que contient la release ? » se traite par helm get manifest, helm get values, helm history. Sous Argo CD, rien de cela n'existe. Les équivalents :

QuestionAvec Helm (release)Avec Argo CD
Que veut-on déployer ?helm get manifest <release>argocd app manifests <application>
Quelles valeurs ?helm get values <release>le fichier de valeurs dans Git, et spec.sources[].helm
Qu'est-ce qui diffère du cluster ?greffon helm diffargocd app diff <application>
Qui a changé quoi, quand ?helm history <release>l'historique Git, et argocd app history
Revenir en arrièrehelm rollbackgit revert, puis synchronisation

La dérive (un objet du cluster qui n'est plus conforme à ce que Git décrit) est détectée par Argo CD, qui passe l'application en OutOfSync et, avec selfHeal, la corrige. Il n'y a pas, côté Helm, de notion équivalente : un helm upgrade compare l'ancien manifeste enregistré au nouveau, pas à l'état réel (même si Helm 3 fait une fusion à trois voies qui regarde l'état en direct pour certaines ressources). Un objet modifié à la main que l'ancien manifeste n'avait pas modifié peut donc survivre à un helm upgrade ; sous Argo CD, il est comparé à chaque cycle.

Adopter une release Helm existante

Si Signalements tourne déjà par helm upgrade --install depuis une CI, le passer sous Argo CD est une opération délicate, décrite pas à pas dans GitOps avec Argo CD, leçon 10, avec un incident réel qu'il vaut mieux lire que revivre. Le résumé, pour situer le rôle de Helm :

  1. Écrire l'Application avec le même releaseName, le même espace de noms et les mêmes valeurs que la release existante, pour que les noms d'objets ne changent pas.
  2. La créer sans synchronisation automatique, et vérifier que la différence est vide (argocd app diff). La seule différence acceptable est l'annotation de suivi d'Argo CD.
  3. Synchroniser, puis retirer Helm en supprimant seulement sa comptabilité, les secrets de release (kubectl delete secret -n <espace> -l owner=helm,name=<release>), jamais helm uninstall.
  4. Retirer le déploiement de la CI, qui devient « écrire la nouvelle version dans Git ».

Le piège est de croire qu'une annotation posée à la main sur les objets vivants (helm.sh/resource-policy: keep) protège de helm uninstall : Helm lit l'annotation dans le manifeste enregistré de la release, pas sur les objets, et le désinstallement a supprimé presque tout. Pour qu'elle compte, elle doit être dans le chart et dans une révision déployée. Les étiquettes app.kubernetes.io/managed-by: Helm et les annotations meta.helm.sh/* restent sur les objets après l'adoption, sans effet.

Sous le capot

Les paramètres du rendu côté Argo CD. Le repo-server construit la commande helm template à partir de l'Application : le nom de la release (releaseName), l'espace de noms de destination, les fichiers de valeurs, les paramètres, la version de Kubernetes du cluster cible et la liste des API disponibles (pour que .Capabilities soit juste), et l'option qui inclut les CRD du répertoire crds/. Les hooks du résultat sont lus et traduits (leçon 8). Le résultat est mis en cache par commit et paramètres : un rendu lent (un chart énorme, des dépendances à télécharger) pèse sur le repo-server, pas sur le contrôleur.

Les dépendances. Si le chart est dans Git avec des dépendances, le repo-server les télécharge au rendu, à partir de Chart.yaml et de Chart.lock (leçon 7). Pour un chart publié dans un registre, les dépendances sont déjà dans le paquet (charts/), et le repo-server n'a rien à résoudre : un mode de fonctionnement plus rapide, plus sûr (rien ne dépend d'un site tiers au moment du rendu) et plus reproductible. C'est une raison de plus de publier des charts finis plutôt que de pointer sur un répertoire Git.

Les hooks, encore. Argo CD traduit pre-install et pre-upgrade en PreSync (donc exécutés à chaque synchronisation, la première comprise), post-install et post-upgrade en PostSync, pre-delete en PreDelete, et hook-weight en vague. test et les hooks de retour arrière sont ignorés, et un seul hook Argo CD dans le chart désactive tous les hooks Helm.

Comment la comparaison fonctionne. Argo CD rend le chart, normalise les manifestes, les compare à l'état vivant de chaque objet suivi, et affiche la différence. Les champs que d'autres contrôleurs modifient légitimement (le nombre de répliques d'un autoscaler, des annotations ajoutées par un opérateur) s'excluent par ignoreDifferences (leçon 3 du cours GitOps). Ces exclusions se règlent côté Application, pas côté chart.

Pièges courants

Un modèle non déterministe. randAlphaNum, now, uuidv4 : l'application est perpétuellement OutOfSync, et avec selfHeal elle est réécrite en boucle. Générez ces valeurs hors du chart.

lookup et .Release.IsUpgrade dans un chart GitOps. Ils ne fonctionnent pas comme ils le font avec helm install. Un chart qui en dépend marche en CI (helm upgrade) et se comporte autrement sous Argo CD.

Les valeurs au mauvais endroit. Dans parameters plutôt qu'en fichier : elles écrasent tout le reste, y compris ce que quelqu'un met dans le fichier d'environnement, et la cause d'une valeur « qui ne s'applique pas » devient difficile à trouver. L'ordre de priorité (chart, fichiers, values, valuesObject, parameters) explique la plupart des cas.

releaseName oublié ou modifié. Il change .Release.Name, donc le nom de chaque objet. Changer releaseName d'une application en service recrée tout sous un autre nom, et les anciens objets sont élagués (ou restent, sans prune). Fixez-le au premier jour.

Une source OCI privée sans identifiant. L'Application reste en erreur de comparaison (ComparisonError) avec un message d'authentification : il manque le secret de dépôt de type Helm. Déclarez-le dans Argo CD avant de créer l'Application.

Helm 3 en local, Helm 4 dans Argo CD. Un rendu qui diffère entre les deux : testez avec la version qui déploie. Une mise à jour d'Argo CD qui change la version de Helm est une mise à jour de rendu.

La promotion qui republie. Promouvoir en reconstruisant le chart pour chaque environnement donne trois artefacts différents : on perd le bénéfice de « ce qui a été testé est ce qui part en production ». On promeut une référence à un artefact unique.

Un test helm test attendu. Sous Argo CD, il ne se lance pas. Remplacez-le par un hook PostSync, ou par une vérification de la CI.

Sécurité

Qui peut écrire dans le dépôt de déploiement peut déployer. Le droit de fusionner une modification de targetRevision ou d'un fichier de valeurs est le droit de déployer en production. Protégez les branches, exigez des relectures, et séparez les droits : la CI du dépôt de charts publie, mais ne déploie pas, et le dépôt de déploiement est approuvé par les personnes qui répondent de la production.

Le contrôle de signature a sa place dans la promotion. Argo CD ne vérifie pas, d'après sa documentation, la signature cosign d'un chart OCI : la CI du dépôt de déploiement exécute cosign verify sur l'artefact visé avant de créer le commit de promotion, comme l'explique la leçon 9. Argo CD sait vérifier la signature GnuPG des commits de Git (Source Integrity) : activez-la sur le dépôt de déploiement pour que seul un commit signé par une clé de confiance soit déployé.

Le projet Argo CD limite ce qu'un chart peut faire. Un chart rendu peut produire un ClusterRole, un objet dans un autre espace de noms, une ressource d'un groupe sensible. L'AppProject de l'application déclare les dépôts autorisés, les destinations et les types de ressources permis (GitOps avec Argo CD, leçon 9) : c'est la barrière qui empêche un chart, même signé, de dépasser son périmètre.

Les valeurs ne contiennent pas de secrets. Elles se lisent dans Git, dans l'interface d'Argo CD et dans le cache du repo-server. Les secrets passent par un ExternalSecret (leçon 8 du cours GitOps).

Le repo-server exécute du code de modèle. Les modèles Helm sont un langage : un chart tiers non relu peut y lire des fichiers du chart ou y faire des appels coûteux. Les charts de provenance externe passent par un miroir interne, relu, avant d'être référencés par une Application.

En production

Un chart de plateforme et des charts d'application. Les applications de Lyneko s'appuient sur la bibliothèque lyneko-commons (leçon 7), publiée à part. Une Application référence le chart fini, qui contient déjà la bibliothèque dans charts/ : le repo-server ne télécharge rien d'autre.

Un fichier de valeurs minimal par environnement. Il ne liste que ce qui diffère des défauts du chart : le nombre de répliques, le nom d'hôte, la Gateway, éventuellement le tag d'image. Quand le défaut change dans une nouvelle version du chart, l'environnement qui ne surcharge pas la clé suit ; c'est pourquoi une modification d'un défaut se lit comme un changement de comportement (leçon 6).

Surveiller la synchronisation, pas Helm. Il n'y a pas de release dont surveiller l'état : on surveille les états Synced / Healthy des Applications, et les métriques du contrôleur (leçon 10 du cours GitOps).

Plusieurs clusters. Une même version de chart est promue sur plusieurs clusters avec des fichiers de valeurs distincts, par un ApplicationSet qui génère une Application par environnement (leçons 6 et 7 du cours GitOps). La targetRevision reste le point de contrôle de la promotion.

Le retour arrière. Revenir à 0.3.0 est un revert du commit de promotion. Mais les migrations de données déjà exécutées ne se défont pas (leçon 8) : le revert ramène l'application, pas les données. Concevez les migrations pour qu'elles tolèrent l'ancienne version.

Liste de contrôle d'un chart pour GitOps

  • Le rendu est déterministe : aucun rand*, now, uuidv4, aucune dépendance à lookup ou à .Release.IsUpgrade.
  • Il se rend sans cluster : helm template avec --kube-version et les valeurs de chaque environnement réussit.
  • Les valeurs sont validées par un schéma, et helm lint --strict passe (leçon 6).
  • Les secrets viennent d'un ExternalSecret : aucun secret dans les valeurs ni dans les modèles.
  • Les hooks sont idempotents, compatibles avec une exécution à chaque synchronisation, et leurs dépendances existent avant eux (leçon 8).
  • Pas de helm test indispensable : le test de fumée est un hook PostSync ou une étape de CI.
  • Les dépendances sont dans le paquet publié ; le chart est publié dans un registre OCI, signé, référencé par version stable (par empreinte si possible).
  • Les sélecteurs de Deployment sont stables (étiquettes de sélection indépendantes de la version).
  • Les objets suivent les conventions d'étiquettes (app.kubernetes.io/*), et releaseName est fixé.
  • La compatibilité des valeurs entre versions est documentée, et suit le versionnement sémantique.
  • Le rendu a été testé avec la version de Helm qui déploie (Helm 4 pour Argo CD 3.5).

Exercices

Exercice 1 : où est passée la release

Sur le cluster lyneko-apps, Signalements est déployé par Argo CD depuis plusieurs semaines. Un collègue lance helm list -n recette et helm get manifest signalements -n recette et n'obtient rien. Panique-t-il à raison ? Quelles commandes lui donnent l'information qu'il cherche ?

Solution

Non : Argo CD n'installe pas le chart, il le rend avec helm template et applique les manifestes ; il n'y a donc aucune release Helm, ni secret de release, et helm list est vide par construction. Pour voir ce qui est déployé : argocd app manifests signalements-recette (les manifestes rendus), argocd app diff signalements-recette (l'écart avec le cluster), argocd app get signalements-recette (état, sources, version du chart), et pour l'historique, l'historique Git du dépôt de déploiement. Les valeurs sont dans environnements/recette/values.yaml. Le retour arrière est un revert Git.

Exercice 2 : l'Application perpétuellement désynchronisée

Après l'ajout d'un nouveau modèle au chart, l'Application signalements-recette passe en OutOfSync en permanence, et l'auto-réparation réécrit un Secret toutes les trois minutes. Le modèle contient password: {{ randAlphaNum 24 | b64enc }}. Expliquez, et proposez la correction pour Signalements.

Solution

Argo CD rend le chart à chaque comparaison, et randAlphaNum produit une valeur différente à chaque rendu : l'état voulu change sans arrêt, donc ne correspond jamais au cluster, et selfHeal réécrit l'objet à chaque cycle (ce qui, en plus, changerait le mot de passe en cours d'utilisation). Correction : ne rien générer dans le chart. Le mot de passe est créé une fois dans le coffre (Secret Manager de Scaleway), et le chart ne porte qu'un ExternalSecret qui référence la clé distante, comme le fait déjà Signalements pour DATABASE_URL. On vérifie ensuite avec deux helm template successifs et un diff : la sortie doit être identique.

Exercice 3 : promouvoir proprement

La version 0.3.1 du chart est en recette depuis deux jours. Décrivez les étapes pour la mettre en production, en indiquant qui a le droit de faire quoi et ce qui est vérifié automatiquement à chaque étape.

Solution

(1) Une demande de fusion dans le dépôt de déploiement change la targetRevision de signalements-preproduction.yaml en 0.3.1. La CI vérifie la signature cosign de l'artefact (cosign verify avec l'identité et l'émetteur attendus), rend le chart avec les valeurs de la préproduction, et affiche la différence de rendu. Un relecteur de l'équipe approuve ; la fusion déclenche la synchronisation. (2) Les contrôles de préproduction passent (hook PostSync, supervision). (3) Une seconde demande de fusion change signalements-production.yaml, avec les mêmes contrôles automatiques, plus l'approbation de la personne qui répond de la production, et une branche protégée. À aucun moment le chart n'est republié ni reconstruit : c'est la même version, la même empreinte qui avance. Le retour arrière est le revert du commit de promotion, sous réserve que les migrations soient compatibles avec l'ancienne version.

Récapitulatif

  • Argo CD rend le chart avec helm template et applique les manifestes : pas de release Helm, pas de helm list, helm history ni helm rollback. Le retour arrière est un revert Git, l'historique est celui de Git.
  • Sous ce rendu, .Release.IsInstall est toujours vrai, lookup renvoie vide, .Capabilities suppose une version par défaut (à corriger par --kube-version) et les valeurs aléatoires changent à chaque rendu : un chart GitOps est déterministe.
  • Les valeurs viennent de fichiers dans Git (priorité : chart, valueFiles, values, valuesObject, parameters), avec une Application à sources multiples quand le chart est dans un registre OCI et les valeurs dans un dépôt Git.
  • Flux fait de vrais helm install (release réelle, hooks et tests Helm, détection de dérive) ; Argo CD rend et compare. Les deux sont valables, les différences se mesurent dans ce qui disparaît.
  • Promouvoir, c'est changer une ligne (targetRevision) par environnement, avec vérification de la signature et lecture du rendu avant la fusion. Renovate propose les mises à jour de charts ; la recette peut s'automatiser, la production reste approuvée.
  • Pour diagnostiquer : argocd app manifests, argocd app diff, l'historique Git. Pour adopter une release existante : même releaseName, différence vide, puis suppression des seuls secrets de release.

Pour aller plus loin

Voir ma constellation →

Sources