Retour aux articles
4 min de lecture

Arrêtez de scripter vos déploiements Helm, utilisez Helmfile

Gérer plusieurs releases Helm devient vite le chaos. Helmfile résout ça avec une config déclarative et de vrais environnements.

KubernetesDevOpsHelm

Helm seul ne scale pas au-delà de trois releases. Vous finissez avec des scripts bash qui appellent helm upgrade, des fichiers values partout, et aucune vision claire de ce qui tourne où

Helmfile résout ce problème. C’est une couche déclarative au-dessus de Helm qui gère plusieurs releases sur différents environnements. Pensez Terraform pour les charts Helm

Le Problème avec Helm Pur

Gérer la production ressemble à ça:

helm upgrade --install prometheus prometheus-community/prometheus \
  -f values/prod/prometheus.yaml \
  -f values/prod/secrets.yaml \
  --set server.retention=30d

helm upgrade --install grafana grafana/grafana \
  -f values/prod/grafana.yaml \
  --set adminPassword=$GRAFANA_PASSWORD

# ... 15 releases de plus

Vous scriptez tout ça. Puis vous avez besoin du staging. Puis du dev. Rapidement vous maintenez des scripts shell qui divergent entre environnements et cassent lors des rollbacks

Ce que Helmfile Fait Vraiment

Un seul fichier définit tout:

repositories:
  - name: prometheus-community
    url: https://prometheus-community.github.io/helm-charts

releases:
  - name: prometheus
    namespace: monitoring
    chart: prometheus-community/prometheus
    values:
      - values/prometheus.yaml
      - values/{{ .Environment.Name }}/prometheus.yaml
    set:
      - name: server.retention
        value: 30d

  - name: grafana
    namespace: monitoring
    chart: grafana/grafana
    values:
      - values/grafana.yaml
    secrets:
      - values/{{ .Environment.Name }}/secrets.yaml

Lancez helmfile sync et tout se déploie. Idempotent, prévisible, versionné

Des Environnements qui Fonctionnent

Définissez une fois, déployez partout:

environments:
  dev:
    values:
      - environments/dev/values.yaml
  staging:
    values:
      - environments/staging/values.yaml
  prod:
    values:
      - environments/prod/values.yaml

releases:
  - name: api
    chart: ./charts/api
    values:
      - values/api.yaml
      - values/{{ .Environment.Name }}/api.yaml

Déploiement sur staging:

helmfile -e staging sync

La même commande marche pour dev et prod. Pas de logique conditionnelle dans les scripts, pas de copie de fichiers

Les Secrets Sans Prise de Tête

Helmfile s’intègre avec helm-secrets via SOPS:

releases:
  - name: app
    chart: ./charts/app
    secrets:
      - secrets://environments/{{ .Environment.Name }}/secrets.yaml

Chiffrez les secrets avec SOPS, committez-les. Helmfile déchiffre au déploiement. Pas de mots de passe en clair dans git, pas de gestion manuelle des clés

Le setup prend cinq minutes:

# Installez SOPS et age
brew install sops age

# Générez une clé
age-keygen -o key.txt

# Configurez SOPS
cat > .sops.yaml <<EOF
creation_rules:
  - path_regex: secrets/.*\.yaml$
    age: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
EOF

# Chiffrez un fichier
sops -e secrets/prod/secrets.yaml > secrets/prod/secrets.enc.yaml

Gestion des Dépendances

Certaines releases en nécessitent d’autres d’abord:

releases:
  - name: cert-manager
    namespace: cert-manager
    chart: jetstack/cert-manager

  - name: ingress-nginx
    namespace: ingress
    chart: ingress-nginx/ingress-nginx
    needs:
      - cert-manager

  - name: api
    namespace: default
    chart: ./charts/api
    needs:
      - ingress-nginx

Helmfile déploie dans l’ordre. Cert-manager d’abord, puis ingress, puis les apps. Gère les échecs correctement, s’arrête si cert-manager échoue

Diff Avant Déploiement

Ne déployez jamais en aveugle:

helmfile diff

Montre exactement ce qui change. Même workflow que Terraform. J’ai attrapé une typo en production comme ça qui aurait cassé l’authentification

# Revoyez les changements
helmfile diff

# Appliquez si OK
helmfile apply

La commande apply montre le diff puis demande confirmation. Utilisez sync pour les pipelines CI/CD

Du Templating Quand Nécessaire

Les templates Go fonctionnent sur tout le fichier:

{{ $domain := .Values.domain }}

releases:
  - name: api
    chart: ./charts/api
    set:
      - name: ingress.host
        value: api.{{ $domain }}

  - name: web
    chart: ./charts/web
    set:
      - name: ingress.host
        value: {{ $domain }}

Les valeurs viennent des fichiers d’environnement:

# environments/prod/values.yaml
domain: example.com
replicas: 5
# environments/dev/values.yaml
domain: dev.example.com
replicas: 1

Structure Terrain

Voici ce qui marche après avoir géré 50+ releases:

helmfile.yaml           # Fichier principal
environments/
  dev/
    values.yaml
    secrets.yaml
  staging/
    values.yaml
    secrets.yaml
  prod/
    values.yaml
    secrets.yaml
values/
  prometheus.yaml       # Config partagée
  grafana.yaml
  api.yaml
charts/                 # Charts locaux
  api/
  worker/

Gardez la config partagée dans values/, les trucs spécifiques aux environnements dans environments/, les charts locaux dans charts/ et les externes référencés depuis les repos

Commandes que Vous Utiliserez

# Déployez tout
helmfile sync

# Déployez une release
helmfile -l name=prometheus sync

# Montrez ce qui changerait
helmfile diff

# Apply interactif
helmfile apply

# Mettez à jour les charts
helmfile deps

# Détruisez tout
helmfile destroy

Le sélecteur de labels (-l) est crucial. Déployez juste la stack monitoring:

helmfile -l tier=monitoring sync

Ajoutez des labels dans helmfile.yaml:

releases:
  - name: prometheus
    labels:
      tier: monitoring
    chart: prometheus-community/prometheus

Stratégie de Migration

Ne réécrivez pas tout. Bougez une release à la fois:

  1. Prenez une release simple (monitoring, pas l’app centrale)
  2. Ajoutez-la à helmfile.yaml
  3. Lancez helmfile diff, devrait ne montrer aucun changement
  4. Supprimez l’ancienne commande helm
  5. Répétez

J’ai migré 30 releases en deux semaines. Chacune prenait 10 minutes. Zero downtime

Quand Ne Pas Utiliser Helmfile

Passez votre chemin si:

  • Vous avez moins de 3 releases
  • Pas d’environnements multiples
  • Les charts Helm sont simples et ne changent jamais

Passez aussi si vous êtes déjà sur ArgoCD ou Flux. Ceux-là gèrent les mêmes problèmes différemment. Helmfile c’est quand vous voulez des déploiements explicites en ligne de commande, pas du GitOps

Problèmes Courants

Précédence des values: Les fichiers plus tardifs écrasent les précédents. Mettez les values spécifiques aux environnements en dernier:

values:
  - values/base.yaml              # Écrasé par
  - values/{{ .Environment.Name }}/values.yaml

Gestion d’état: Helmfile track les releases dans l’état de Helm. Si vous faites manuellement helm delete sur quelque chose, Helmfile ne le sait pas. Utilisez helmfile delete à la place

Diffs lents: Avec 20+ releases, helmfile diff prend du temps. Utilisez les labels pour cibler des sous-ensembles:

helmfile -l app=api diff

Le Résultat

Je maintenais un script bash de 200 lignes qui cassait sur les erreurs, divergeait entre environnements, et rendait les déploiements stressants. Maintenant je lance une commande qui gère tout. Le diff montre les changements avant qu’ils arrivent. Les secrets restent chiffrés dans git. Les nouveaux développeurs sont opérationnels en une heure

Moins de temps à gérer les déploiements signifie plus de temps à construire des fonctionnalités

La réalité est souvent plus nuancée. Moi, la nuance ça m'ennuie. Je préfère la clarté.

Commentaires