Skip to content

hndiaye9854/learn_helm-and-helmfile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 

Repository files navigation

TP Pratique : Helm & Helmfile

Objectifs pédagogiques

À la fin de ce TP, tu seras capable de :

  • Comprendre l'écosystème Helm (chart, release, repository, values)
  • Installer, mettre à jour et rollback des releases Helm
  • Créer tes propres charts propres et réutilisables (templates, helpers, hooks, dependencies)
  • Orchestrer plusieurs charts avec Helmfile
  • Gérer plusieurs environnements (dev, staging, prod) sans dupliquer ta config
  • Appliquer les bonnes pratiques DevOps (DRY, secrets, CI/CD-ready)

Scénario fil rouge

Tu es DevOps chez BookStore Inc.. L'équipe te demande de déployer une stack composée de :

Composant Rôle Image
bookstore-frontend UI statique (Nginx) nginx:1.25-alpine
bookstore-api Backend REST (mock) mendhak/http-https-echo:31
postgresql Base de données chart Bitnami
redis Cache chart Bitnami

Le tout sur 3 environnements : dev, staging, prod, chacun avec ses spécificités (nb de réplicas, ressources, mots de passe, ingress, etc.).


Partie 0 : Prérequis et setup (15 min)

Outils à installer

# Vérifier Docker
docker --version

# Installer kind (cluster Kubernetes local) — alternative : minikube ou k3d
# Linux/macOS :
brew install kind  # ou : go install sigs.k8s.io/kind@latest

# Installer kubectl
brew install kubectl

# Installer Helm 3
brew install helm

# Installer Helmfile
brew install helmfile

# Plugin Helm indispensable pour Helmfile
helm plugin install https://github.com/databus23/helm-diff

Créer un cluster local

# Cluster simple
kind create cluster --name tp-helm

# Vérifier
kubectl cluster-info
kubectl get nodes

Préparer ton workspace

mkdir -p ~/tp-helm/{charts,helmfile}
cd ~/tp-helm

PARTIE 1 : Helm : Découverte (45 min)

1.1 Les concepts clés (à bien intégrer avant de coder)

Concept Définition
Chart Un package Helm = un dossier contenant des templates Kubernetes paramétrables
Release Une instance d'un chart déployée dans un cluster (un chart peut être installé plusieurs fois)
Repository Un serveur HTTP qui héberge des charts (ex : https://charts.bitnami.com/bitnami)
Values Les valeurs de configuration injectées dans les templates
Revision Chaque install/upgrade crée une nouvelle révision (utile pour rollback)

Analogie : un chart est à une release ce qu'une classe est à une instance en programmation orientée objet.

1.2 Installer un chart depuis un repository public

# Ajouter un repo
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Chercher un chart
helm search repo nginx

# Voir les valeurs disponibles d'un chart
helm show values bitnami/nginx > /tmp/nginx-default-values.yaml
less /tmp/nginx-default-values.yaml

# Installer (dry-run d'abord, toujours !)
helm install my-nginx bitnami/nginx --dry-run --debug

# Installation réelle
helm install my-nginx bitnami/nginx \
  --namespace demo --create-namespace \
  --set service.type=ClusterIP \
  --set replicaCount=2

1.3 Cycle de vie d'une release

# Lister les releases
helm list -A

# État détaillé
helm status my-nginx -n demo

# Voir les manifests générés
helm get manifest my-nginx -n demo

# Voir les valeurs utilisées
helm get values my-nginx -n demo

# Mettre à jour
helm upgrade my-nginx bitnami/nginx -n demo --set replicaCount=3

# Historique
helm history my-nginx -n demo

# Rollback à la révision 1
helm rollback my-nginx 1 -n demo

# Désinstaller
helm uninstall my-nginx -n demo

Exercice 1.1

  1. Installe le chart bitnami/redis dans le namespace cache avec :
    • architecture=standalone
    • auth.enabled=false
  2. Vérifie qu'un pod tourne (kubectl get pods -n cache).
  3. Upgrade pour activer la persistence avec master.persistence.size=2Gi.
  4. Affiche l'historique, fais un rollback, puis désinstalle proprement.

Astuce : utilise un fichier values.yaml plutôt que --set dès que tu as plus de 2-3 paramètres. C'est versionnable, lisible, et c'est la pratique pro.

helm install my-redis bitnami/redis -n cache --create-namespace -f my-values.yaml

PARTIE 2 : Créer son premier chart (1h30)

On va créer un chart pour notre API bookstore-api.

2.1 Générer le squelette

cd ~/tp-helm/charts
helm create bookstore-api
tree bookstore-api

Tu obtiens cette structure :

bookstore-api/
├── Chart.yaml          # Métadonnées du chart
├── values.yaml         # Valeurs par défaut
├── charts/             # Dépendances (sous-charts)
├── templates/
│   ├── _helpers.tpl    # Templates réutilisables (helpers)
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── hpa.yaml
│   ├── serviceaccount.yaml
│   ├── NOTES.txt       # Affiché après l'install
│   └── tests/
└── .helmignore

2.2 Customiser Chart.yaml

# bookstore-api/Chart.yaml
apiVersion: v2
name: bookstore-api
description: API REST pour BookStore
type: application
version: 0.1.0          # Version du chart (SemVer)
appVersion: "1.0.0"     # Version de l'application
maintainers:
  - name: Ton Nom
    email: toi@bookstore.com

2.3 Comprendre les templates Go

Helm utilise le template engine de Go + des fonctions Sprig. La syntaxe : {{ ... }}.

Ouvre templates/deployment.yaml généré par helm create et observe ces patterns essentiels :

# Référence aux values
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

# Helpers (définis dans _helpers.tpl)
name: {{ include "bookstore-api.fullname" . }}

# Conditions
{{- if .Values.serviceAccount.create }}
serviceAccountName: {{ include "bookstore-api.serviceAccountName" . }}
{{- end }}

# Boucles
{{- range .Values.env }}
- name: {{ .name }}
  value: {{ .value | quote }}
{{- end }}

# Indentation et nettoyage de whitespaces
{{- with .Values.nodeSelector }}
nodeSelector:
  {{- toYaml . | nindent 8 }}
{{- end }}

Le tiret - dans {{- et -}} supprime les espaces/sauts de ligne. C'est crucial pour produire du YAML valide.

2.4 Adapter values.yaml pour notre API

Remplace le contenu de bookstore-api/values.yaml :

# bookstore-api/values.yaml
replicaCount: 1

image:
  repository: mendhak/http-https-echo
  tag: "31"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 8080
  targetPort: 8080

ingress:
  enabled: false
  className: ""
  hosts:
    - host: api.bookstore.local
      paths:
        - path: /
          pathType: Prefix

env:
  - name: HTTP_PORT
    value: "8080"
  - name: LOG_WITHOUT_NEWLINE
    value: "true"

resources:
  requests:
    cpu: 50m
    memory: 64Mi
  limits:
    cpu: 200m
    memory: 256Mi

# Healthchecks (à brancher dans le deployment)
probes:
  liveness:
    enabled: true
    path: /
    initialDelaySeconds: 10
  readiness:
    enabled: true
    path: /
    initialDelaySeconds: 5

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 5
  targetCPUUtilizationPercentage: 80

serviceAccount:
  create: true
  name: ""

nodeSelector: {}
tolerations: []
affinity: {}

2.5 Adapter le deployment.yaml

Ouvre templates/deployment.yaml et adapte-le pour utiliser notre targetPort et nos env (le squelette généré ne les gère pas tous correctement). Voici la version cible :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "bookstore-api.fullname" . }}
  labels:
    {{- include "bookstore-api.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "bookstore-api.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "bookstore-api.selectorLabels" . | nindent 8 }}
    spec:
      serviceAccountName: {{ include "bookstore-api.serviceAccountName" . }}
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.service.targetPort }}
              protocol: TCP
          {{- if .Values.env }}
          env:
            {{- range .Values.env }}
            - name: {{ .name }}
              value: {{ .value | quote }}
            {{- end }}
          {{- end }}
          {{- if .Values.probes.liveness.enabled }}
          livenessProbe:
            httpGet:
              path: {{ .Values.probes.liveness.path }}
              port: http
            initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
          {{- end }}
          {{- if .Values.probes.readiness.enabled }}
          readinessProbe:
            httpGet:
              path: {{ .Values.probes.readiness.path }}
              port: http
            initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
          {{- end }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}

2.6 Comprendre _helpers.tpl

Ce fichier contient des templates nommés réutilisables. Exemple typique :

{{/* Génère un nom complet pour les ressources */}}
{{- define "bookstore-api.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}

{{/* Labels communs */}}
{{- define "bookstore-api.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version }}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

L'appel se fait avec {{ include "bookstore-api.labels" . }}, le . final passe le contexte courant.

2.7 Tester ton chart

cd ~/tp-helm/charts/bookstore-api

# Linter (vérifie la syntaxe)
helm lint .

# Templating local (sans installer) — ESSENTIEL pour debug
helm template my-api . --debug

# Dry-run sur le cluster
helm install my-api . --namespace bookstore --create-namespace --dry-run --debug

# Install réel
helm install my-api . --namespace bookstore --create-namespace

# Tester
kubectl port-forward -n bookstore svc/my-api-bookstore-api 8080:8080
# Dans un autre terminal :
curl http://localhost:8080

Exercice 2.1 : NOTES.txt

Modifie templates/NOTES.txt pour qu'après installation, l'utilisateur voie une commande kubectl port-forward prête à coller, adaptée au nom de la release.

Exercice 2.2 : Configurabilité

Ajoute dans values.yaml une option podAnnotations (map vide par défaut) et propage-la dans le deployment.yaml sous spec.template.metadata.annotations.

Indice : {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }}.


PARTIE 3 : Helm avancé (1h30)

3.1 Dependencies (sous-charts)

Notre bookstore-api a besoin d'une base PostgreSQL. On va la déclarer comme dépendance.

# bookstore-api/Chart.yaml
dependencies:
  - name: postgresql
    version: "15.x.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
# bookstore-api/values.yaml — ajouter à la fin
postgresql:
  enabled: true
  auth:
    username: bookstore
    password: changeme
    database: bookstore
  primary:
    persistence:
      size: 1Gi
# Récupérer les dépendances
helm dependency update

# Tu vois apparaître charts/postgresql-x.y.z.tgz
ls charts/

# Réinstaller
helm upgrade --install my-api . -n bookstore
kubectl get pods -n bookstore

Notes importantes :

  • Les valeurs d'un sous-chart se mettent sous une clé du nom du sous-chart (postgresql:).
  • condition: postgresql.enabled permet de désactiver la dépendance via --set postgresql.enabled=false.
  • Pour partager une valeur entre charts (ex : la DB), regarde global: et import-values.

3.2 Hooks Helm

Les hooks permettent d'exécuter des actions à des moments précis du lifecycle :

Hook Quand
pre-install / post-install Avant/après création des ressources
pre-upgrade / post-upgrade Avant/après upgrade
pre-delete / post-delete Avant/après uninstall
test Lors d'un helm test

Exemple : un Job qui initialise la base après installation.

# bookstore-api/templates/db-init-job.yaml
{{- if .Values.dbInit.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ include "bookstore-api.fullname" . }}-db-init
  annotations:
    "helm.sh/hook": post-install,post-upgrade
    "helm.sh/hook-weight": "5"
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: init
          image: postgres:15-alpine
          command: ["sh", "-c"]
          args:
            - |
              echo "Init DB pour la release {{ .Release.Name }}"
              sleep 5
              echo "Done"
{{- end }}
# values.yaml
dbInit:
  enabled: true

3.3 Helm tests

Crée un test simple dans templates/tests/test-connection.yaml (généré par helm create, à adapter) :

apiVersion: v1
kind: Pod
metadata:
  name: "{{ include "bookstore-api.fullname" . }}-test"
  annotations:
    "helm.sh/hook": test
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  restartPolicy: Never
  containers:
    - name: curl
      image: curlimages/curl:8
      command: ["curl"]
      args:
        - "{{ include "bookstore-api.fullname" . }}:{{ .Values.service.port }}/"
helm test my-api -n bookstore

3.4 Conditionals et fonctions Sprig utiles

# Valeur par défaut
{{ .Values.image.tag | default .Chart.AppVersion }}

# Quote pour forcer une string (très utile avec les nombres-comme-string)
{{ .Values.port | quote }}

# Required (échoue si manquant)
{{ required "image.repository est obligatoire" .Values.image.repository }}

# Conditionnel ternaire
replicas: {{ ternary 3 1 .Values.production }}

# Génération aléatoire (mots de passe)
password: {{ randAlphaNum 16 }}

# Lookup d'une ressource existante (ex : preserver un secret)
{{- $existing := lookup "v1" "Secret" .Release.Namespace "my-secret" -}}

Exercice 3.1

Crée un second chart bookstore-frontend qui :

  1. Déploie un Nginx servant une page HTML statique (via ConfigMap montée dans le pod).
  2. A une dépendance optionnelle vers redis (chart Bitnami) avec condition: redis.enabled.
  3. Inclut une variable apiUrl dans le values, injectée comme variable d'env dans le pod.
  4. Expose un Service ClusterIP configurable.

Pour la page HTML, utilise templates/configmap.yaml avec :

data:
  index.html: |
    <h1>BookStore - {{ .Release.Name }}</h1>
    <p>API: {{ .Values.apiUrl }}</p>

Et monte la ConfigMap dans /usr/share/nginx/html/.


PARTIE 4 : Helmfile : Introduction (45 min)

4.1 Pourquoi Helmfile ?

Imagine que tu doives installer 5 charts pour dev, 5 pour staging, 5 pour prod. Avec Helm seul :

helm install api ./bookstore-api -f values-dev.yaml -n dev
helm install frontend ./bookstore-frontend -f values-dev.yaml -n dev
helm install monitoring prometheus-community/kube-prometheus-stack -f mon-dev.yaml -n monitoring
# ... répéter pour staging, prod, à chaque modif

C'est non-déclaratif, sujet aux erreurs, et impossible à versionner proprement.

Helmfile = fichier déclaratif qui décrit toutes les releases d'un environnement. Une seule commande helmfile sync reconcilie l'état du cluster avec ton fichier.

Pense à Helmfile comme un docker-compose.yaml pour Helm.

4.2 Premier helmfile.yaml

mkdir -p ~/tp-helm/helmfile
cd ~/tp-helm/helmfile
# helmfile.yaml
repositories:
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: my-redis
    namespace: cache
    chart: bitnami/redis
    version: "20.x.x"
    values:
      - architecture: standalone
        auth:
          enabled: false

  - name: my-postgres
    namespace: db
    chart: bitnami/postgresql
    version: "15.x.x"
    values:
      - auth:
          username: bookstore
          password: changeme
          database: bookstore

4.3 Commandes principales

# Voir le diff (ce qui sera changé) — comme terraform plan
helmfile diff

# Appliquer (install + upgrade ce qui doit l'être)
helmfile apply

# Sync force (install/upgrade systématique)
helmfile sync

# Détruire toutes les releases du fichier
helmfile destroy

# Templater (voir le YAML final, sans appliquer)
helmfile template

# Lister les releases gérées
helmfile list

# Cibler une seule release
helmfile -l name=my-redis apply

apply = diff + sync (uniquement si différences). À privilégier en CI/CD.

Exercice 4.1

Ajoute notre chart local bookstore-api au helmfile.yaml. Indice :

releases:
  - name: bookstore-api
    namespace: bookstore
    chart: ../charts/bookstore-api   # Chemin relatif !
    values:
      - replicaCount: 2

Lance helmfile apply et vérifie que tout se déploie en une commande.


PARTIE 5 : Helmfile multi-environnements (1h30)

C'est là que Helmfile brille vraiment.

5.1 Définir des environnements

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

---  # ⚠️ Important : sépare la config des envs du reste

repositories:
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: bookstore-api
    namespace: bookstore-{{ .Environment.Name }}
    chart: ../charts/bookstore-api
    values:
      - replicaCount: {{ .Values.api.replicaCount }}
      - image:
          tag: {{ .Values.api.imageTag | quote }}
      - resources:
          requests:
            cpu: {{ .Values.api.resources.cpu }}
            memory: {{ .Values.api.resources.memory }}
      - ingress:
          enabled: {{ .Values.api.ingress.enabled }}
          hosts:
            - host: api.{{ .Values.domain }}
              paths:
                - path: /
                  pathType: Prefix
# environments/dev.yaml
domain: dev.bookstore.local
api:
  replicaCount: 1
  imageTag: "31"
  resources:
    cpu: 50m
    memory: 64Mi
  ingress:
    enabled: false
# environments/staging.yaml
domain: staging.bookstore.local
api:
  replicaCount: 2
  imageTag: "31"
  resources:
    cpu: 100m
    memory: 128Mi
  ingress:
    enabled: true
# environments/prod.yaml
domain: bookstore.com
api:
  replicaCount: 4
  imageTag: "31"   # On épingle une version stable en prod
  resources:
    cpu: 500m
    memory: 512Mi
  ingress:
    enabled: true

5.2 Utiliser les environnements

# Sélection de l'env via flag --environment ou -e
helmfile -e dev diff
helmfile -e dev apply

helmfile -e staging apply

helmfile -e prod diff   # Toujours faire un diff avant prod !

5.3 Selectors (déployer un sous-ensemble)

releases:
  - name: bookstore-api
    namespace: bookstore-{{ .Environment.Name }}
    labels:
      tier: backend
      app: bookstore
    chart: ../charts/bookstore-api
    # ...

  - name: bookstore-frontend
    namespace: bookstore-{{ .Environment.Name }}
    labels:
      tier: frontend
      app: bookstore
    chart: ../charts/bookstore-frontend
    # ...
# Ne déployer que le backend
helmfile -e dev -l tier=backend apply

# Ne déployer qu'une release
helmfile -e dev -l name=bookstore-api apply

5.4 Templating avancé : tpl et go-templates

Helmfile supporte les go-templates dans le helmfile.yaml lui-même (différent des templates Helm) :

releases:
  {{- range $service := list "bookstore-api" "bookstore-frontend" }}
  - name: {{ $service }}
    namespace: bookstore-{{ $.Environment.Name }}
    chart: ../charts/{{ $service }}
    values:
      - environments/{{ $.Environment.Name }}/{{ $service }}.yaml
  {{- end }}

Dans Helmfile, on a deux niveaux de templating :

  1. Helmfile lui-même (résolu avant que Helm soit appelé)
  2. Templates Helm dans le chart (résolus par Helm)

Exercice 5.1

  1. Restructure ton projet ainsi :
    ~/tp-helm/
    ├── charts/
    │   ├── bookstore-api/
    │   └── bookstore-frontend/
    └── helmfile/
        ├── helmfile.yaml
        └── environments/
            ├── dev.yaml
            ├── staging.yaml
            └── prod.yaml
    
  2. Configure 3 environnements avec des spécificités réelles :
    • dev : 1 réplica, ressources mini, pas d'ingress, pas de persistence DB.
    • staging : 2 réplicas, ressources moyennes, ingress activé, persistence 1Gi.
    • prod : 3+ réplicas, ressources confortables, ingress + autoscaling, persistence 5Gi.
  3. Vérifie avec helmfile -e <env> template que le YAML généré est correct avant de déployer.

PARTIE 6 : Bonnes pratiques (1h)

6.1 Structure de projet recommandée

mon-projet/
├── charts/                 # Tes charts maison
│   ├── bookstore-api/
│   └── bookstore-frontend/
├── helmfile/
│   ├── helmfile.yaml
│   ├── environments/       # Values par env
│   ├── releases/           # (optionnel) helmfile.yaml par groupe
│   └── secrets/            # Secrets chiffrés (sops)
├── .gitignore              # Ignorer charts/*/charts/, *.lock optionnel
└── README.md

6.2 Gestion des secrets avec helm-secrets + sops

Ne jamais commit de mots de passe en clair. Solution : helm-secrets (plugin Helm) + sops (chiffrement) + KMS / age / GPG.

# Installation
helm plugin install https://github.com/jkroepke/helm-secrets
brew install sops age

# Générer une clé age
age-keygen -o ~/.config/sops/age/keys.txt

# Configurer .sops.yaml dans ton repo
cat > .sops.yaml <<EOF
creation_rules:
  - path_regex: secrets/.*\.yaml$
    age: <ta-public-key-age>
EOF

# Chiffrer un fichier
sops --encrypt secrets/prod.yaml > secrets/prod.enc.yaml

Dans helmfile.yaml :

releases:
  - name: bookstore-api
    chart: ../charts/bookstore-api
    secrets:
      - secrets/{{ .Environment.Name }}.enc.yaml

6.3 Hooks Helmfile

Tu peux exécuter des commandes shell autour des actions :

releases:
  - name: bookstore-api
    chart: ../charts/bookstore-api
    hooks:
      - events: ["prepare"]
        showlogs: true
        command: "echo"
        args: ["Préparation du déploiement de bookstore-api"]
      - events: ["postsync"]
        command: "kubectl"
        args: ["rollout", "status", "deployment/bookstore-api", "-n", "bookstore-{{ `{{ .Environment.Name }}` }}"]

6.4 Intégration CI/CD

Pipeline type (GitLab/GitHub Actions) :

# .github/workflows/deploy.yml (extrait)
- name: Lint charts
  run: |
    for chart in charts/*/; do
      helm lint "$chart"
    done

- name: Helmfile diff (dev)
  run: helmfile -e dev diff --detailed-exitcode
  # Exit 2 = changements détectés (utile pour fail si pas attendu)

- name: Helmfile apply (dev)
  if: github.ref == 'refs/heads/main'
  run: helmfile -e dev apply

6.5 Checklist du chart "production-ready"

  • values.yaml documenté (commentaires sur chaque option)
  • Chart.yaml versionné en SemVer, appVersion à jour
  • Labels standards (app.kubernetes.io/*)
  • Resources (requests + limits) toujours définies
  • Probes (liveness, readiness) configurables
  • securityContext (runAsNonRoot, readOnlyRootFilesystem)
  • NetworkPolicy optionnelle
  • PodDisruptionBudget optionnel
  • Tests Helm (helm test)
  • README.md du chart avec table des values (utiliser helm-docs)
  • CI : helm lint + helm template + kubectl apply --dry-run=server

MINI-PROJET FINAL (à faire en autonomie environ 2 à 3h)

Énoncé

Tu dois livrer le déploiement complet de BookStore sur les 3 environnements, en respectant ces contraintes :

  1. 2 charts maison : bookstore-api et bookstore-frontend (déjà commencés).

  2. 2 charts externes : postgresql et redis (Bitnami), gérés via Helmfile (pas en dependency cette fois — pour pratiquer les deux approches).

  3. 3 environnements avec ces specs :

    dev staging prod
    API replicas 1 2 3
    Frontend replicas 1 2 3
    DB persistence 1Gi 5Gi 20Gi
    Ingress Non Oui Oui
    Resources xs s m
    DB password en clair (dev.yaml) secrets sops secrets sops
  4. Le frontend doit afficher une page HTML qui mentionne dynamiquement l'environnement courant (via une variable d'env injectée).

  5. Une seule commande doit suffire à déployer un environnement complet : helmfile -e <env> apply.

  6. Bonus :

    • Tests Helm sur chaque chart maison.
    • Hook pre-install qui crée le namespace si absent (ou utiliser createNamespace: true).
    • helm-docs pour générer la doc des values automatiquement.

Critères de validation

  • helmfile -e dev apply puis kubectl get all -n bookstore-dev montre tout en Running.
  • helmfile -e prod template génère du YAML valide avec les bonnes valeurs.
  • helmfile -e <env> destroy nettoie tout proprement.
  • Aucune valeur sensible en clair dans Git pour staging/prod.
  • Code organisé, lisible, commenté.

Ressources pour aller plus loin


Nettoyage final

# Supprimer toutes les releases via helmfile
helmfile -e dev destroy
helmfile -e staging destroy
helmfile -e prod destroy

# Détruire le cluster
kind delete cluster --name tp-helm

Récapitulatif des concepts couverts

Notion Partie
Chart, Release, Repository, Values, Revision 1
helm install/upgrade/rollback/uninstall 1
Création de chart, structure 2
Templates Go, helpers, NOTES.txt 2
Dependencies (subcharts) 3
Hooks (pre-install, post-upgrade...) 3
helm test, fonctions Sprig 3
Helmfile basics, commandes principales 4
Multi-environnements, selectors 5
Templating Helmfile (go-templates) 5
Secrets (sops), structure projet, CI/CD 6

À propos

Ce TP a été réalisé par Hamidou NDIAYE dans le cadre d'un apprentissage approfondi de Helm et Helmfile.

Contact :

Signaler un problème ou une amélioration

Vous avez trouvé une erreur, une coquille, ou vous avez une suggestion pour améliorer ce TP ? Toute contribution est la bienvenue !

Plusieurs façons de me faire un retour :

  1. Ouvrir une issue (recommandé) : Signaler un problème

    • Décrivez le problème rencontré
    • Précisez la partie du TP concernée
    • Joignez si possible un message d'erreur ou un screenshot
  2. Proposer une correction directe via une Pull Request :

   git clone https://github.com/hndiaye9854/learn_helm-and-helmfile.git
   git checkout -b fix/ma-correction
   # ... vos modifications ...
   git commit -m "fix: description de la correction"
   git push origin fix/ma-correction
  1. Me contacter directement par email ou LinkedIn pour toute question.

Contribuer

Les contributions qui enrichissent le TP sont particulièrement bienvenues :

  • Ajout d'exercices ou de cas pratiques
  • Corrections de bugs ou de typos
  • Améliorations de la documentation
  • Adaptations pour d'autres outils (k3d, microk8s...)

Licence

Ce TP est partagé librement à des fins éducatives. N'hésitez pas à le réutiliser, le forker et l'adapter à vos besoins.

Bon TP ! N'hésite pas à expérimenter, casser les choses et regarder ce qui se passe, c'est comme ça qu'on apprend le mieux.


Si ce TP vous a été utile, n'hésitez pas à mettre une étoile au repo !

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors