Un hook Helm (pre-install, post-upgrade, pre-delete) exécute une ressource Kubernetes à un moment précis du cycle de vie d’une release, en dehors du suivi normal que Helm fait de cette release. Cette distinction, invisible tant que tout se passe bien, devient critique le jour où un helm rollback est censé tout annuler et ne le fait pas.

Un hook n’est pas suivi comme le reste de la release

Les ressources normales d’un chart (Deployments, Services) sont suivies par Helm dans le manifeste de la release : helm rollback compare l’état actuel à une révision antérieure et restaure les différences. Une ressource marquée comme hook est traitée différemment : elle s’exécute au moment indiqué, puis Helm cesse de la suivre comme faisant partie de la release courante.

# Ce Job s'exécute avant l'installation,
# mais n'est jamais suivi comme faisant partie de la release
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration
  annotations:
    "helm.sh/hook": pre-install
spec:
  template:
    spec:
      containers:
        - name: migrate
          image: myapp-migrate
      restartPolicy: Never

Pourquoi helm rollback ne rejoue jamais un hook

helm rollback restaure les ressources normales de la release à leur état antérieur, mais ne réexécute aucun hook associé à cette révision antérieure. Une migration de base de données exécutée en pre-install lors du déploiement de la version 2 ne se rejoue pas en sens inverse lors d’un rollback vers la version 1 : le rollback restaure le code applicatif, jamais l’état de la base qu’un hook avait modifié.

# Restaure le Deployment à la version précédente,
# mais ne touche à aucun hook ni à ce qu'il a modifié
helm rollback myapp 3

Ce comportement n’est pas un bug, c’est documenté : les hooks sont conçus pour des actions à sens unique (initialiser une base, envoyer une notification), pas pour des changements réversibles automatiquement. Un rollback qui suppose implicitement qu’une migration de base sera défaite en même temps que le code se trompe systématiquement.

Le piège du hook qui échoue silencieusement en apparence

Par défaut, un hook qui échoue bloque le déploiement (helm install ou upgrade échoue), mais certaines politiques de suppression de hook (helm.sh/hook-delete-policy) peuvent supprimer la ressource même en cas d’échec, laissant peu de traces pour diagnostiquer après coup pourquoi l’installation a échoué.

annotations:
  "helm.sh/hook": pre-install
  # Sans cette politique, le Job en échec reste visible
  # pour diagnostic ; avec, il disparaît après tentative
  "helm.sh/hook-delete-policy": hook-succeeded

Choisir before-hook-creation plutôt que hook-succeeded garde la ressource d’échec visible jusqu’à la prochaine tentative, un choix qui compte concrètement au moment de diagnostiquer un déploiement qui échoue sans message d’erreur exploitable dans les logs Helm eux-mêmes.

Ce que ça implique pour une stratégie de rollback réelle

Un rollback fiable pour une application qui utilise des hooks de migration ne peut pas se contenter de helm rollback seul : la migration de base de données nécessite sa propre stratégie de réversibilité, généralement via le pattern expand/contract qui garde chaque étape de schéma rétrocompatible, indépendamment de ce que Helm suit ou ne suit pas.

À retenir

Un hook Helm s’exécute en dehors du cycle de vie normal de la release, ce qui signifie que helm rollback ne le rejoue jamais, dans un sens ou dans l’autre : les hooks sont conçus pour des actions à sens unique, pas pour des changements automatiquement réversibles. La politique de suppression de hook détermine si une ressource en échec reste visible pour diagnostic ou disparaît silencieusement, un détail à choisir consciemment plutôt que de laisser au défaut. Une stratégie de rollback fiable pour une application avec des hooks de migration doit traiter la réversibilité de la base de données séparément, un des détails qui comptent dès qu’une industrialisation CI/CD s’appuie sur Helm pour des déploiements réellement réversibles.