Du Helm encore plus puissant avec Helmfile

Exploitez l'approche déclarative de Helmfile pour apporter visibilité et reproductibilité aux états des releases Helm et faciliter le travail en équipe. Familiarisez-vous avec Helmfile et explorez les puissantes fonctionnalités permettant de gérer facilement et en toute sécurité un ensemble de releases Helm.

Du Helm encore plus puissant avec Helmfile
Photo par Elliott Engelmann / Unsplash

Qu'est-ce que Helmfile

Helmfile est un outil qui permet de gérer les charts Helm de manière déclarative. Si vous n'êtes pas familier avec Helm, jetez un œil à ceci.. Les informations nécessaires à la création d'une release (repo, noms de release, charts, versions, valeurs, ...) sont déclarées dans des fichiers d'état. Les déclarations dans les fichiers d'état sont ensuite utilisées pour créer les ressources des releases dans les clusters Kubernetes cibles. Il utilise Helm sous le capot et apporte d'autres fonctionnalités intéressantes supplémentaires.

Avantages de Helmfile

  • Une approche déclarative qui apporte une meilleure expérience et une sensation as code :
    • un moyen simple de gérer un groupe de releases Helm .
    • possibilité d'utiliser un système de contrôle de version comme Git pour stocker les états des releases et suivre les modifications, ce qui augmente la visibilité, la reproductibilité et facilite le travail en équipe
  • Gestion des environnements intégrés (dev, staging, prod...) pour le déploiement des applications
  • Meilleure expérience de gestion des releases et un historique de releases propre (s'il n'y a pas de changement, une nouvelle version ne sera pas créée... utilise le plugin Helm-diff pour obtenir les différences de modifications lors des déploiements)
  • Gestion des secrets grace au plugin Helm-secrets permettant le chiffrement des valeurs secrètes
  • Possibilité de traiter les fichiers de valeurs comme des modèles/templates Go (.gotmpl vs .yaml) :
  • et plus encore

Comment fonctionne Helmfile

Helmfile utilise une approche déclarative pour gérer les releases Helm. Les releases et les configurations sont déclarées dans le fichier « helmfile.yaml » et utilisent les directives de configuration répertoriées ici.

Les états des releases peuvent également être déclarés dans plusieurs fichiers « .yaml » à l'intérieur d'un répertoire « helmfile.d ». Helmfile recherche ce répertoire au cas où le fichier helmfile.yaml n'existerait pas. Les fichiers helmfile.d/*.yaml sont considérés comme des fichiers helmfile.yaml indépendants et traités par ordre alphabétique. L'ordre de traitement de ces fichiers peut également être contrôlé en les préfixant par un numéro à deux chiffres ('00-database.yaml' traité avant '01-webserver.yaml').

À l'intérieur des fichiers d'état, nous pouvons définir une liste de releases (nom, chart, espace de nom, version, valeurs, chemins des fichiers de valeurs...), les dépôts requis pour les charts, les paramètres de configuration de Helm par release ou globalement (limite d'historique des releases, attente, délais d'attente, contexte kubernetes, création automatique d'espace de noms...) et les paramètres des environnements Helmfile (pour déclarer plusieurs environnements de déploiement d'applications et les fichiers de valeurs correspondants).

Une fois les états souhaités définis, les commandes « helmfile apply » ou « helmfile sync » peuvent être utilisées pour reproduire cet état dans les clusters Kubernetes cibles (assurez-vous que les versions déclarées sont créées avec les configurations appropriées). La première commande crée/met à jour les releases uniquement lorsqu'il existe des différences entre les fichiers d'état et ce qui est réellement déployé, tandis que la seconde déploie toujours les releases déclarées dans les fichiers d'état (crée de nouvelles révisions).

Installation de Helmfile

  • Les assets des versions de Helmfile se trouvent ici
  • Pour installer Helmfile sur Linux, procédez comme suit :
$ helmfile_version=0.167.1 # choose version
$ linux_arch=amd64 # choose OS arch

# Download Helmfile binary
$ wget https://github.com/helmfile/helmfile/releases/download/v${helmfile_version}/helmfile_${helmfile_version}_linux_${linux_arch}.tar.gz

# Install Helmfile binary
$ mkdir helmfile && tar xzvf helmfile_${helmfile_version}_linux_${linux_arch}.tar.gz -C helmfile
$ sudo mv helmfile/helmfile /usr/local/bin
$ sudo chmod +x /usr/local/bin/helmfile

# Verify
$ helmfile version
  • Helmfile nécessite le plugin Helm-diff pour fonctionner correctement. Procédez comme suit pour l'installer sous Linux :
# Optionally set the version to install a specific one
# Helm-diff releases assets can be found here:
# https://github.com/databus23/helm-diff/releases

$ helm plugin install https://github.com/databus23/helm-diff [--version $plugin_version] 
Downloading https://github.com/databus23/helm-diff/releases/latest/download/helm-diff-linux-amd64.tgz
Preparing to install into /home/gmkziz/.local/share/helm/plugins/helm-diff
Installed plugin: diff

Gestion des releases Helmfile

Configuration des dépôts de charts des releases

Nous pouvons déclarer un ou plusieurs dépôts de charts nécessaires pour déployer nos applications Kubernetes en utilisant le mot-clé repositories comme suit :

# File: helmfile.yaml

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

Les dépôts déclarés seront ensuite automatiquement ajoutés lors de la création des releases.
Nous pouvons également demander à helmfile d'ajouter immédiatement les dépôts déclarés à l'aide de la commande helmfile repos .

Configuration des environnements des releases

Dans cet exemple de déclaration d'environnements, l'application que nous allons déployer utilise deux environnements : staging et prod. Pour chaque environnement déclaré, nous spécifions le chemin (par rapport au fichier helmfile.yaml) vers le fichier de valeurs d'environnements Helmfile :

# File: helmfile.yaml

environments: 
  staging:
    values:
      - environments/all.yaml
      - environments/staging/grafana.yaml
  prod:
    values:
      - environments/all.yaml
      - environments/prod/grafana.yaml
      
--- # <= this in mandatory between environments declaration configuration
    # and other configuration directives inside the helmfile.yaml file

repositories:
  (...)

La routine shell environments/all.yaml contiendra les paramètres communs aux deux environnements staging et prod et environments/$env/grafana.yaml les paramètres spécifiques à chaque environnement.

Pour un environnement donné, les fichiers de « valeurs d'environnement Helmfile » déclarés seront fusionnés. Si des clés identiques sont présentes dans différents fichiers de « valeurs d'environnement Helmfile », la paire clé/valeur du dernier fichier déclaré remplacera les autres. Voici un exemple :

# File: environments/all.yaml
grafana:
  customReplicaSetting: 1
  otherSetting1: 1
  
# File: environments/staging/grafana.yaml
grafana:
  customReplicaSetting: 2
  otherSetting2: 2
  
# Then, final value for 'grafana.customReplicaSetting' will be '2' 
# (from the latest declared environment values file). 
# Both 'grafana.otherSetting1' and 'grafana.otherSetting2' will be 
# available as environment values (merged from the two files)
grafana:
  customReplicaSetting: 2
  otherSetting1: 1
  otherSetting2: 2

Les « valeurs d'environnement Helmfile » ne sont pas des valeurs Charts. Ce sont des valeurs personnalisées, définies par l'utilisateur, qui peuvent ensuite être utilisées comme variables d'entrée dans des fichiers de valeurs de Charts (.gotmpl). Elles seront disponibles dans l'objet .Values . Voici un exemple :

# File: values.yaml.gotmpl
# A Helmfile Templated Grafana Chart values file. 
# Default Charts values taken from here: 
# https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml 

rbac:
  create: false

# Here we set the Chart 'replicas' value to the value of the
# 'grafana.customReplicaSetting' Helmfile environment value
# sourced from the environments/$env/grafana.yaml file
replicas: {{ .Values.grafana.customReplicaSetting }} 

Lors du déploiement des releases, la commande helmfile permet de choisir l'environnement de déploiement cible (staging ou prod). Helmfile est ainsi en mesure de trouver les valeurs d'environnement Helmfile appropriées.

Avec cette configuration, nous pouvons utiliser les mêmes template de valeurs de Charts pour nos versions dans tous les environnements et exploiter les fonctionnalités des environnements Helmfile pour injecter des configurations spécifiques aux environnements. Nous verrons cela en détail après, continuez la lecture.

Configuration des releases

# File: helmfile.yaml

environments:
  (...)
  
---

repositories:
 (...)
 
releases:
  - name: grafana # The name of the release
    chart: grafana/grafana # repository/chart for using charts from locally added repositories
                           # or helmfile.yaml relative path to a local chart directory
    namespace: grafana-{{ .Environment.Name }} # Namespace where the release will be created
                                               # Will be dynamically suffixed with the target 
                                               # Helmfile environment name (staging or prod) 
                                               # thanks to the built-in Helmfile .Environment 
                                               # object, containing the name of the environment  
    createNamespace: true # automatically creates the release namespace inside the target 
                          # Kubernetes cluster, if it does not exist
    labels: # could be used to select only this release when using the helmfile command, 
            # with the --selector or -l flags followed by app=grafana
      app: grafana
    version: 8.4.5 # The version of the Chart
    # values next is a list containing either Charts values files paths
    # (absolute or relative to this current helmfile.yaml file), indicating
    # the files containing the user-defined values to use or inline values 
    # (see commented rbac.create below). 
    # {{ `{{ .Release.Name }}` }} will be replaced by grafana
    values:   
      - config/releases/{{ `{{ .Release.Name }}` }}/values.yaml.gotmpl
    # - rbac:
    #     create: false
   # The set config next can also be used to set values. It is equivalent to the 
   # Helmfile/helm '--set rbac.create=false' in command line
   #set:
   #  name: rbac.create
   #  value: false

Les valeurs spécifiées à l'aide de la directive de configuration « values » sont ajoutées à des fichiers temporaires et injectées à l'aide de l'option « --values » la commande Helm. Les valeurs spécifiées à l'aide de la directive de configuration « set » sont injectées à l'aide de l'option « --set name=value ».

Le templating Go est également disponible pour définir des valeurs dans les fichiers de valeurs configurés ou via les directives de configuration « values » et « set » directement. Configurer les valeurs (values) directement dans ce fichier est idéal pour définir quelques unes assez rapidement. Préférez utiliser des fichiers de valeurs lorsque vous avez un tas de valeurs à définir.

Le chemin du fichier de valeurs configuré dans l'exemple de configuration ci-dessus, au travers de l'objet natif helmfile '.Release.Name', peut être réutilisé pour d'autres release ajoutées dans le fichier de configuration helmfile.yaml. De cette façon, pour chaque release que nous configurons, nous devons simplement créer le fichier config/releases/$release_name/values.yaml.gotmpl pour configurer les valeurs et ajouter les chemins de fichiers correspondants pour les « valeurs d'environnement Helmfile » dans la section de configuration « environnements » :

# File: helmfile.yaml

environments: 
  staging:
    values:
      - environments/all.yaml
      - environments/staging/grafana.yaml
      - environments/staging/vmcluster.yaml # <= added for the vmcluster release
  prod:
    values:
      - environments/all.yaml
      - environments/prod/grafana.yaml
      - environments/prod/vmcluster.yaml # <= added for the vmcluster release
---

(...)
  releases:
    - name: grafana
      (...)
      values:
        - config/releases/{{ `{{ .Release.Name }}` }}/values.yaml.gotmpl
      (...)
    - name: vmcluster
      (...)
      values:
        - config/releases/{{ `{{ .Release.Name }}` }}/values.yaml.gotmpl
      (...)

Pour éviter de répéter la même configuration de valeurs pour chaque release, nous pouvons créer un template de configuration, puis le référencer. De cette façon, nous disposons d'un emplacement unique pour configurer les valeurs de toutes les releases. Voici comment procéder :

# File: helmfile.yaml

environments:
  (...)
  
---

repositories:
  (...)
  
# Creating values configuration template
templates:
  values: &values
    values:
      - config/releases/{{ `{{ .Release.Name }}` }}/values.yaml.gotmpl

releases:
  - name: grafana
    chart: grafana/grafana
    namespace: grafana-{{ .Environment.Name }}
    createNamespace: true
    labels:
      app: grafana
    version: 8.4.5
    <<: *values # referencing values configuration template
  - name: prometheus
      (...)
    <<: *values # referencing values configuration template
    (...)

Configuration des paramètres par défaut de Helmfile

Il existe un ensemble de paramètres par défaut qui peuvent être configurés pour Helmfile.
Le paramètre « helmDefaults » du fichier helmfile.yaml peut être utilisé à cet effet. Voici un exemple :

# File: helmfile.yaml

(...)

helmDefaults:
  historyMax: 10         # releases history limit
  wait: false            # wait for k8s resources like pods to be running
  timeout: 300           # wait timeout in seconds
  deleteWait: false      # wait for k8s resources effective deletion
  deleteTimeout: 300     # deletion wait timeout
  skipDeps: false        # skip runnning `helm dep up` and `helm dep build`
  createNamespace: true  # automatically create releases namespaces
  
(...)

Pour tous les paramètres disponibles, recherchez « helmDefaults » dans la configuration helmfile.yaml de référence.

Créer des releases

Fonctions natives Helmfile | Objets natifs Helmfile | Référence Helmfile.yaml

Voici le contenu de la configuration helmfile.yaml que nous avons précédemment créée et expliquée :

# File: helmfile.yaml

environments: 
  staging:
    values:
      - environments/all.yaml
      - environments/staging/grafana.yaml
  prod:
    values:
      - environments/all.yaml
      - environments/prod/grafana.yaml
      
---

helmDefaults:
  historyMax: 10
  wait: false
  timeout: 300
  deleteWait: false
  deleteTimeout: 300
  skipDeps: false
  createNamespace: true

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

templates:
  values: &values
    values:
      - config/releases/{{ `{{ .Release.Name }}` }}/values.yaml.gotmpl

releases:
  - name: grafana
    chart: grafana/grafana
    namespace: grafana-{{ .Environment.Name }}
    labels:
      app: grafana
    version: 8.4.5
    <<: *values

Voici le contenu des fichiers de « valeurs d'environnements Helmfile ​​» :

# File: environments/all.yaml
grafana:
  image:
    repository: grafana/grafana
    tag: 11.1.4

# File: environments/staging/grafana.yaml
grafana:
  replicas: 2

# File: environments/prod/grafana.yaml
grafana:
  replicas: 4

Et le contenu du fichier de valeurs :

# File: config/releases/grafana/values.yaml.gotmpl
# Available Charts values taken from here: 
# https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml

rbac:
  create: false

replicas: {{ .Values.grafana.replicas }}

image:
  repository: {{ .Values.grafana.image.repository }} 
  tag: {{ .Values.grafana.image.tag }}

adminPassword: {{ requiredEnv "GRAFANA_ADMIN_PASSWORD" }} # Set the adminPassword value to 
                                   # the value of the GRAFANA_ADMIN_PASSWORD systems 
                                   # environment variable. The 'requiredEnv' function, 
                                   # unlike 'env', makes that variable required, 
                                   # meaning the release creation will fail if not set

Nous pouvons vérifier si le fichier helmfile.yaml contient des erreurs en utilisant la commande « helmfile lint » comme indiqué ci-dessous :

# To shorten --environment, the -e flag can be used

# When everything is fine:

$ helmfile lint --environment staging
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Fetching grafana/grafana
Linting release=grafana, chart=/tmp/helmfile1932208801/grafana-staging/grafana/grafana/grafana/8.4.5/grafana
==> Linting /tmp/helmfile1932208801/grafana-staging/grafana/grafana/grafana/8.4.5/grafana

1 chart(s) linted, 0 chart(s) failed

# Let's unset the required systems environment variable
# for the Grafana admin password and check again:

$ unset GRAFANA_ADMIN_PASSWORD
$ helmfile lint --environment staging
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Fetching grafana/grafana
in ./helmfile.yaml: failed to render values files "config/releases/grafana/values.yaml.gotmpl": failed to render [config/releases/grafana/values.yaml.gotmpl], because of template: stringTemplate:15:18: executing "stringTemplate" at <requiredEnv "GRAFANA_ADMIN_PASSWORD">: error calling requiredEnv: required env var `GRAFANA_ADMIN_PASSWORD` is not set

Nous pouvons également utiliser la commande « helmfile build » pour restituer le fichier de configuration helmfile.yaml et voir les valeurs rendues pour nos environnements helmfile :

$ helmfile build -e staging
---
#  Source: /home/gmkziz/helmfile/helmfile.yaml

filepath: helmfile.yaml
helmBinary: helm
kustomizeBinary: kustomize
environments:
  prod:
    values:
    - environments/all.yaml
    - environments/prod/grafana.yaml
  staging:
    values:
    - environments/all.yaml
    - environments/staging/grafana.yaml
repositories:
- name: grafana
  url: https://grafana.github.io/helm-charts
releases:
- chart: grafana/grafana
  version: 8.4.5
  createNamespace: true
  name: grafana
  namespace: grafana-staging
  labels:
    app: grafana
  values:
  - config/releases/grafana/values.yaml.gotmpl
templates:
  values:
    values:
    - config/releases/{{ .Release.Name }}/values.yaml.gotmpl
renderedvalues: # <= Here are our Helmfile environments rendered values 
  grafana:
    image:
      repository: grafana/grafana
      tag: 11.1.4
    replicas: 2
    
# Let's have a look at the rendered helmfile 
# envrironments values for the production environement
$ helmfile build -e prod
(...)
renderedvalues:
  grafana:
    image:
      repository: grafana/grafana
      tag: 11.1.4
    replicas: 4

Pour restituer/prévisualiser les manifestes des ressources Kubernetes qui seront déployées après la création de la release, nous pouvons utiliser la commande « helmfile template » :

$ helmfile template --environment staging
Templating release=grafana, chart=grafana/grafana
---
# Source: grafana/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
automountServiceAccountToken: false
metadata:
  labels:
    helm.sh/chart: grafana-8.4.5
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "11.1.4"
    app.kubernetes.io/managed-by: Helm
  name: grafana-staging
  namespace: grafana-staging
---
# Source: grafana/templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: grafana
  namespace: grafana-staging
  labels:
    helm.sh/chart: grafana-8.4.5
    app.kubernetes.io/name: grafana
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/version: "11.1.4"
    app.kubernetes.io/managed-by: Helm
type: Opaque
(...)

Pour créer la release, nous pouvons utiliser la commande « helmfile apply » :

# Create staging environment release
$ helmfile apply -e staging
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Comparing release=grafana, chart=grafana/grafana, namespace=grafana-staging
********************

        Release was not present in Helm.  Diff will show entire contents as new.

********************
grafana-staging, grafana, ConfigMap (v1) has been added:
- 
+ # Source: grafana/templates/configmap.yaml
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+   name: grafana
+   namespace: grafana-staging
+   labels:
+     helm.sh/chart: grafana-8.4.5
+     app.kubernetes.io/name: grafana
+     app.kubernetes.io/instance: grafana
+     app.kubernetes.io/version: "11.1.4"
+     app.kubernetes.io/managed-by: Helm
+ data:
+   
+   grafana.ini: |
+     [analytics]
+     check_for_updates = true
+     [grafana_net]
+     url = https://grafana.net
+     [log]
+     mode = console
+     [paths]
+     data = /var/lib/grafana/
+     logs = /var/log/grafana
+     plugins = /var/lib/grafana/plugins
+     provisioning = /etc/grafana/provisioning
+     [server]
+     domain = ''
grafana-staging, grafana, Deployment (apps) has been added:
- 
+ # Source: grafana/templates/deployment.yaml
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+   name: grafana
+   namespace: grafana-staging
+   labels:
+     helm.sh/chart: grafana-8.4.5
+     app.kubernetes.io/name: grafana
+     app.kubernetes.io/instance: grafana
+     app.kubernetes.io/version: "11.1.4"
+     app.kubernetes.io/managed-by: Helm
+ spec:
+   replicas: 2
+   revisionHistoryLimit: 10
+   selector:
+     matchLabels:
+       app.kubernetes.io/name: grafana
+       app.kubernetes.io/instance: grafana
(...)

# Create production environment release
$ helmfile apply -e prod
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Comparing release=grafana, chart=grafana/grafana, namespace=grafana-prod
********************

        Release was not present in Helm.  Diff will show entire contents as new.

********************
grafana-prod, grafana, ConfigMap (v1) has been added:
- 
+ # Source: grafana/templates/configmap.yaml
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+   name: grafana
+   namespace: grafana-prod
+   labels:
+     helm.sh/chart: grafana-8.4.5
+     app.kubernetes.io/name: grafana
+     app.kubernetes.io/instance: grafana
+     app.kubernetes.io/version: "11.1.4"
+     app.kubernetes.io/managed-by: Helm
+ data:
+   
+   grafana.ini: |
+     [analytics]
+     check_for_updates = true
+     [grafana_net]
+     url = https://grafana.net
+     [log]
+     mode = console
+     [paths]
+     data = /var/lib/grafana/
+     logs = /var/log/grafana
+     plugins = /var/lib/grafana/plugins
+     provisioning = /etc/grafana/provisioning
+     [server]
+     domain = ''
grafana-prod, grafana, Deployment (apps) has been added:
- 
+ # Source: grafana/templates/deployment.yaml
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+   name: grafana
+   namespace: grafana-prod
+   labels:
+     helm.sh/chart: grafana-8.4.5
+     app.kubernetes.io/name: grafana
+     app.kubernetes.io/instance: grafana
+     app.kubernetes.io/version: "11.1.4"
+     app.kubernetes.io/managed-by: Helm
+ spec:
+   replicas: 4
+   revisionHistoryLimit: 10
+   selector:
+     matchLabels:
+       app.kubernetes.io/name: grafana
+       app.kubernetes.io/instance: grafana
(...)

Utilisons maintenant « helm » et « kubectl » pour effectuer quelques vérifications. Notez que la commande « helmfile list » affiche uniquement les releases déclarées dans les fichiers d'état, et non les releases réellement déployées, c'est pourquoi nous utiliserons plutôt « helm list ».

$ helm list -n grafana-staging
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
grafana grafana-staging 1               <release_deployment_date>               deployed        grafana-8.4.5   11.1.4     

$ helm list -n grafana-prod
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
grafana grafana-prod    1               <release_deployment_date>               deployed        grafana-8.4.5   11.1.4

$ kubectl get pods -n grafana-staging
NAME                      READY   STATUS    RESTARTS   AGE
grafana-c66968f8f-lvkf9   1/1     Running   0          17m
grafana-c66968f8f-z4bsw   1/1     Running   0          17m

$ kubectl get pods -n grafana-prod
NAME                       READY   STATUS    RESTARTS   AGE
grafana-55f598c747-4tdvr   1/1     Running   0          13m
grafana-55f598c747-86jxc   1/1     Running   0          13m
grafana-55f598c747-msdns   1/1     Running   0          13m
grafana-55f598c747-s89s7   1/1     Running   0          13m

Mise à jour des releases

Modifiez n'importe quelle configuration d'état de Helmfile, le fichier de valeurs d'environnement de Helmfile, les fichiers de valeurs des releases... et réexécutez la commande « helmfile apply » :

# Without modifications, Helmfile does nothing
# The release revision stays the same

$ helmfile apply -e prod
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Comparing release=grafana, chart=grafana/grafana, namespace=grafana-prod

# After updating replicas number from 4 to 5 
# in environments/prod/grafana.yaml

$ helmfile apply -e prod
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Comparing release=grafana, chart=grafana/grafana, namespace=grafana-prod
grafana-prod, grafana, Deployment (apps) has changed:
  # Source: grafana/templates/deployment.yaml
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: grafana
    namespace: grafana-prod
    labels:
      helm.sh/chart: grafana-8.4.5
      app.kubernetes.io/name: grafana
      app.kubernetes.io/instance: grafana
      app.kubernetes.io/version: "11.1.4"
      app.kubernetes.io/managed-by: Helm
  spec:
-   replicas: 4
+   replicas: 5
    revisionHistoryLimit: 10
    selector:
      matchLabels:
        app.kubernetes.io/name: grafana
        app.kubernetes.io/instance: grafana
(...)

$ helm list -n grafana-prod
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
grafana grafana-prod    2               <release_deployment_date>               deployed        grafana-8.4.5   11.1.4

Rollback des releases

Restaurez l'état Helmfile souhaité et exécutez la commande « helmfile apply » ou utilisez la commande « helm rollback » comme indiqué ici.

Suppression des releases

$ helmfile delete grafana -e staging
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Listing releases matching ^grafana$
grafana grafana-staging 1               <release_deployment_date>         deployed        grafana-8.4.5   11.1.4     

Deleting grafana
release "grafana" uninstalled


DELETED RELEASES:
NAME      NAMESPACE         DURATION
grafana   grafana-staging         0s

# Helmfile still shows release from state file

$ helmfile list -e staging
NAME    NAMESPACE       ENABLED INSTALLED       LABELS          CHART           VERSION
grafana grafana-staging true    true            app:grafana     grafana/grafana 8.4.5  

$ helmfile list -n grafana-staging
NAME    NAMESPACE       ENABLED INSTALLED       LABELS          CHART           VERSION
grafana grafana-staging true    true            app:grafana     grafana/grafana 8.4.5  

# Release not shown anymore with Helm
$ helm list -n grafana-staging
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION

Réorganisation de la configuration helmfile.yaml à l'aide de plusieurs fichiers

Fonctions natives Helmfile | Objets natifs Helmfile | Référence Helmfile.yaml

La directive de configuration 'bases' du fichier helmfile.yaml peut être utilisée pour indiquer d'autres fichiers d'état Helmfile qui seront fusionnés avec le fichier helmfile.yaml où cette configuration est définie. Grâce à cette directive de configuration, nous sommes en mesure de segmenter le fichier helmfile.yaml en plusieurs fichiers.

Pour illustrer cela, nous allons segmenter le fichier helmfile.yaml que nous avons utilisé dans la section Créer des releases comme suit:

  • mettre la configuration repositories dans bases/repositories.yaml
  • mettre la configuration environments dans bases/environments.yaml
  • mettre la configuration helmDefaults dans bases/defaults.yaml
  • mettre la configuration templates dans bases/templates.yaml

Voici l'arborescence finale des répertoires :

├── bases
│   ├── defaults.yaml
│   ├── environments.yaml
│   ├── repositories.yaml
│   └── templates.yaml
├── config
│   └── releases
│       └── grafana
│           └── values.yaml.gotmpl
├── environments
│   ├── all.yaml
│   ├── prod
│   │   └── grafana.yaml
│   └── staging
│       └── grafana.yaml
└── helmfile.yaml

Voici le contenu des fichiers « bases » :

# File: bases/defaults.yaml

helmDefaults:
  historyMax: 10
  wait: false
  timeout: 300
  deleteWait: false
  deleteTimeout: 300
  skipDeps: false
  createNamespace: true
  
# File: bases/environments.yaml

environments: 
  staging:
    values:
      - environments/all.yaml
      - environments/staging/grafana.yaml
  prod:
    values:
      - environments/all.yaml
      - environments/prod/grafana.yaml
      
# File: bases/repositories.yaml

repositories:
  - name: grafana
    url: https://grafana.github.io/helm-charts
    
# File: bases/templates.yaml

templates:
  values: &values
    values:
      - config/releases/{{ .Release.Name }}/values.yaml.gotmpl

Voici le contenu du fichier helmfile.yaml utilisant les fichiers d'état du répertoire 'bases'. Les fichiers d'état seront fusionnés dans l'ordre dans lequel ils sont spécifiés :

bases:
  - bases/defaults.yaml
  - bases/repositories.yaml
  - bases/environments.yaml

{{ readFile "bases/templates.yaml" }} # anchor used below doesn't work when 
                                      # 'bases/templates.yaml' is declared
                                      # using 'bases'. That's why we are using
                                      # the 'readFile' function instead

releases:
  - name: grafana
    chart: grafana/grafana
    namespace: grafana-{{ .Environment.Name }}
    labels:
      app: grafana
    version: 8.4.5
    <<: *values  # <= anchor

Test:

# Linting works

$ helmfile lint --environment prod
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Fetching grafana/grafana
Linting release=grafana, chart=/tmp/helmfile3200030168/grafana-prod/grafana/grafana/grafana/8.4.5/grafana
==> Linting /tmp/helmfile3200030168/grafana-prod/grafana/grafana/grafana/8.4.5/grafana

1 chart(s) linted, 0 chart(s) failed

# Deployment also works as before
$ helmfile apply --environment prod
helmfile apply --environment prod
Adding repo grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories

Comparing release=grafana, chart=grafana/grafana, namespace=grafana-prod
********************

        Release was not present in Helm.  Diff will show entire contents as new.

********************
grafana-prod, grafana, ConfigMap (v1) has been added:
- 
+ # Source: grafana/templates/configmap.yaml
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+   name: grafana
+   namespace: grafana-prod
+   labels:
+     helm.sh/chart: grafana-8.4.5
+     app.kubernetes.io/name: grafana
+     app.kubernetes.io/instance: grafana
+     app.kubernetes.io/version: "11.1.4"
+     app.kubernetes.io/managed-by: Helm
+ data:
+   
+   grafana.ini: |
+     [analytics]
+     check_for_updates = true
(...)
Listing releases matching ^grafana$
grafana grafana-prod    1                             <release_creation_date>             deployed        grafana-8.4.5   11.1.4     


UPDATED RELEASES:
NAME      NAMESPACE      CHART             VERSION   DURATION
grafana   grafana-prod   grafana/grafana   8.4.5           2s