Aller au contenu
English
English
Conteneurs & Orchestration medium

Dépendances Helm : subcharts, umbrella charts et composition

70 min de lecture

logo helm

Réponse directe : helm dependency update télécharge les sous-charts déclarés dans Chart.yaml vers charts/ et génère un Chart.lock pour verrouiller les versions exactes. Le chart parent passe des values aux subcharts via des clés nommées (ex: backend.replicaCount), et global.* est automatiquement propagé à tous les sous-charts.

Ce guide vous montre comment composer des applications complexes en assemblant plusieurs charts Helm : subcharts locaux, dépendances externes et umbrella charts, tout en gardant une configuration cohérente et reproductible.

Avant de commencer, assurez-vous d'avoir :

  • Un cluster Kubernetes fonctionnel, kind pour cette formation
  • kubectl configuré et un namespace de test
  • Helm v4.3 installé, la version sur laquelle ce guide est mesuré
  • Connaissance des modules précédents : templates, values, fonctions
SectionConceptDurée
Déclarer des dépendancesChart.yaml dependencies, repositories10 min
Télécharger et verrouillerhelm dependency update/build, Chart.lock8 min
Subcharts et valuesClés nommées, global.*, import-values12 min
Conditions et tagsActiver/désactiver des sous-charts8 min
Umbrella chartArchitecture multi-tiers complète10 min
Pièges et maintenanceConflits de noms, mises à jour7 min

Un chart Helm peut dépendre d'autres charts, locaux ou distants. Ces dépendances sont déclarées dans le fichier Chart.yaml sous la clé dependencies.

L'exemple ci-dessous mélange volontairement les deux origines possibles, un sous-chart local et un chart public, parce que c'est la configuration réelle de la plupart des umbrella charts : votre code applicatif à côté de briques d'infrastructure que vous ne maintenez pas. Notez que l'ordre des entrées dans dependencies n'a aucune influence sur l'ordre de déploiement : Helm rend tous les manifestes puis les applique en une passe, triés par type de ressource.

Créez un chart umbrella avec des dépendances mixtes :

Chart.yaml
apiVersion: v2
name: mon-stack
description: Chart umbrella pour démo composition
type: application
version: 1.0.0
appVersion: "1.0.0"
dependencies:
# Dépendance locale (sous-chart dans charts/)
- name: backend
version: "0.1.0"
repository: "file://charts/backend"
# Dépendance externe (repository Helm)
- name: kube-state-metrics
version: "5.27.0"
repository: "https://prometheus-community.github.io/helm-charts"
condition: monitoring.enabled # Activation conditionnelle
alias: metrics # Renommer dans les templates

Le champ repository détermine d'où Helm va chercher le chart, et ce choix engage votre chaîne de livraison. file:// garde le sous-chart dans votre dépôt Git : il évolue au même rythme que le parent et ne demande aucune infrastructure. Les trois autres formes visent un artefact publié ailleurs, donc versionné indépendamment, ce qui suppose que ce dépôt reste accessible au moment du déploiement. Sur un cluster sans accès Internet, seule la forme file:// fonctionne sans miroir interne.

TypeSyntaxe repositoryUsage
Localfile://charts/nomSous-chart développé avec le parent
HTTPShttps://example.com/chartsRepository Helm classique
OCIoci://ghcr.io/org/chartsRegistry OCI (Helm 3.8+)
Alias@monrepoRéférence un repo ajouté via helm repo add

Une dépendance externe en HTTPS suppose que le dépôt soit connu de votre poste, sans quoi helm dependency update échoue sur une URL qu'il ne sait pas résoudre. L'ajout se fait une fois, et se refait à l'identique sur chaque machine et dans chaque chaîne d'intégration :

Fenêtre de terminal
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

Trois champs sont obligatoires, les quatre autres résolvent des problèmes précis que vous rencontrerez tôt ou tard. condition et tags répondent à la même question, activer ou non le sous-chart, mais avec des granularités différentes. alias est indispensable dans un seul cas : inclure deux fois le même chart dans un umbrella, par exemple deux instances de PostgreSQL. Le champ version accepte les opérateurs SemVer, et c'est lui qui décide de la stabilité de vos déploiements.

ChampObligatoireDescription
name✅Nom du chart à inclure
version✅Version ou range SemVer (^1.2.0, ~1.2.0, >=1.0.0)
repository✅URL ou chemin du chart
condition❌Chemin values pour activer/désactiver (ex: db.enabled)
tags❌Liste de tags pour activation groupée
alias❌Renommer le chart (utile si même chart plusieurs fois)
import-values❌Importer des values du sous-chart vers le parent

Helm propose deux commandes pour gérer les dépendances : update et build.

Cette commande résout les dépendances depuis Chart.yaml, télécharge les charts dans charts/, et génère un fichier Chart.lock :

Fenêtre de terminal
helm dependency update mon-stack/

Sortie typique :

Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "prometheus-community" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 2 charts
Downloading kube-state-metrics from repo https://prometheus-community.github.io/helm-charts
Deleting outdated charts

Ce qui se passe :

  1. Helm met à jour les indexes des dépôts déclarés
  2. Résout les versions selon les contraintes (5.27.0, ^1.0.0, etc.)
  3. Télécharge les .tgz dans charts/
  4. Génère Chart.lock avec les versions exactes retenues

Regarder le dossier charts/ après la commande apprend une chose qui surprend souvent : les deux types de dépendances n'y laissent pas la même trace. Le point à retenir pour votre .gitignore est que seuls les .tgz sont reconstructibles depuis Chart.lock ; le dossier backend/ est du code source qui vous appartient et doit rester versionné.

Fenêtre de terminal
ls -la mon-stack/charts/
total 32
drwxrwxr-x 3 bob bob 4096 févr. 1 19:09 .
drwxrwxr-x 4 bob bob 4096 févr. 1 19:09 ..
drwxrwxr-x 3 bob bob 4096 févr. 1 19:08 backend
-rw-rw-r-- 1 bob bob 751 févr. 1 19:09 backend-0.1.0.tgz
-rw-r--r-- 1 bob bob 14235 févr. 1 19:09 kube-state-metrics-5.27.0.tgz

Les sous-charts locaux (file://) restent en dossiers ET sont packagés en .tgz. Les dépendances externes arrivent uniquement en .tgz.

Là où Chart.yaml exprime une intention, « une version 5.27.x me convient », Chart.lock enregistre le résultat de la résolution à un instant donné. Deux champs font tout le travail : version, qui fige la version exacte retenue, et digest, une empreinte de la liste des dépendances qui permet à Helm de détecter que Chart.yaml a changé depuis. Le champ generated n'est qu'un horodatage informatif : ne vous en servez pas comme critère de fraîcheur.

Chart.lock (généré automatiquement)
dependencies:
- name: backend
repository: file://charts/backend
version: 0.1.0
- name: kube-state-metrics
repository: https://prometheus-community.github.io/helm-charts
version: 5.27.0
digest: sha256:c7be1e4c41ba5a5a166b995fbf57fd64ef0364100fb37c12a84553e64f4443c3
generated: "2026-02-01T19:09:58.573104083+01:00"

Ce fichier est essentiel : il garantit que toute l'équipe et la CI utilisent les mêmes versions exactes.

Contrairement à update, la commande build utilise Chart.lock au lieu de Chart.yaml pour télécharger les dépendances :

Fenêtre de terminal
# Supprimer les archives téléchargées
rm mon-stack/charts/*.tgz
# Reconstruire depuis le lock
helm dependency build mon-stack/

Sortie :

Saving 2 charts
Downloading kube-state-metrics from repo https://prometheus-community.github.io/helm-charts
Deleting outdated charts

La distinction est la même qu'entre npm install et npm ci : l'une peut faire évoluer les versions, l'autre reproduit à l'identique. build refuse d'ailleurs de travailler si les deux fichiers ont divergé, avec un message explicite : the lock file (Chart.lock) is out of sync with the dependencies file (Chart.yaml). C'est exactement le comportement voulu en intégration continue, où un Chart.yaml modifié sans helm dependency update doit faire échouer le pipeline plutôt que de résoudre silencieusement une version différente de celle testée.

CommandeUtiliseQuand l'utiliser
helm dependency updateChart.yamlDéveloppement, mise à jour vers nouvelles versions
helm dependency buildChart.lockCI/CD, builds reproductibles

Les deux commandes se répartissent selon qui les exécute, et c'est ce qui garantit la reproductibilité. Le développeur lance helm dependency update, qui résout les versions et réécrit le Chart.lock. Il commite ensuite Chart.yaml et Chart.lock, mais pas le dossier charts/, reconstructible à partir des deux. La chaîne d'intégration, elle, lance helm dependency build, qui relit le verrou sans le modifier et reconstruit donc exactement le même ensemble.

C'est la commande de diagnostic à lancer avant de perdre du temps sur un rendu qui échoue. Elle ne télécharge rien et ne modifie rien : elle compare ce que déclare Chart.yaml avec ce qui se trouve réellement dans charts/. La colonne STATUS répond à elle seule à la question « pourquoi mon helm template se plaint-il d'une dépendance ».

Fenêtre de terminal
helm dependency list mon-stack/
NAME VERSION REPOSITORY STATUS
backend 0.1.0 file://charts/backend ok
kube-state-metrics 5.27.0 https://prometheus-community.github.io/helm-charts ok

Les statuts possibles :

  • ok : Dépendance présente et à jour
  • missing : Non téléchargée (lancer update ou build)
  • unpacked : Dossier présent mais pas de .tgz
  • wrong version : Archive présente, mais sa version ne satisfait pas la contrainte de Chart.yaml
  • misnamed : Archive présente sous un nom de fichier qui ne correspond pas au chart qu'elle contient

La communication entre chart parent et subcharts se fait exclusivement via les values. Helm offre trois mécanismes.

Chaque sous-chart reçoit ses values sous une clé correspondant à son nom (ou alias) :

values.yaml du parent
# Configuration du sous-chart "backend"
backend:
replicaCount: 2
image:
tag: "6.7.1"
# Configuration du sous-chart avec alias "metrics" (kube-state-metrics)
metrics:
prometheusScrape: true
replicas: 1

Dans le sous-chart backend, ces values sont accessibles directement :

charts/backend/templates/deployment.yaml
spec:
replicas: {{ .Values.replicaCount }} # Reçoit 2
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" # tag = 6.7.1

Un sous-chart ne voit qu'une partie de l'arbre de values, et cette limite est ce qui rend la composition prévisible. Il reçoit ses propres defaults, fusionnés avec ce que le parent pousse sous son nom, plus les global. Il n'a jamais accès aux values privées du parent ni à celles d'un sous-chart voisin. Autrement dit, un chart écrit pour vivre seul continue de fonctionner à l'identique une fois embarqué : rien de nouveau n'apparaît dans ses .Values sans que quelqu'un l'y ait mis explicitement.

Les values sous global.* sont automatiquement propagées à tous les sous-charts :

values.yaml du parent
global:
imageRegistry: "my-registry.io"
additionalLabels:
team: platform
cost-center: infra

Dans n'importe quel sous-chart :

Template d'un sous-chart
metadata:
labels:
{{- with .Values.global.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
containers:
- image: "{{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}"

Résultat du template :

metadata:
labels:
team: platform
cost-center: infra
spec:
containers:
- image: "my-registry.io/ghcr.io/stefanprodan/podinfo:6.7.1"

Ce rendu montre au passage le défaut le plus courant du motif global.imageRegistry : le sous-chart concatène sans condition, si bien qu'une image.repository contenant déjà un registre produit une référence à deux registres et un ImagePullBackOff. Les charts publics sérieux protègent leur template avec {{- if .Values.global.imageRegistry }} ; faites de même sur les vôtres, et ne stockez que le chemin du dépôt dans image.repository.

Pour des cas avancés, vous pouvez importer des values d'un sous-chart vers le parent :

Chart.yaml
dependencies:
- name: database
version: "0.1.0"
repository: "file://charts/database"
import-values:
- child: exports.connection # Chemin dans le sous-chart
parent: dbConnection # Clé dans le parent
charts/database/values.yaml
exports:
connection:
host: postgres.default.svc
port: 5432
database: appdb

Dans un template du parent, vous accédez maintenant à :

data:
DB_HOST: {{ .Values.dbConnection.host | quote }} # "postgres.default.svc"
DB_PORT: {{ .Values.dbConnection.port | quote }} # "5432"

Vous pouvez activer ou désactiver des sous-charts dynamiquement sans les supprimer de Chart.yaml.

Une condition est un chemin values qui doit valoir true ou false :

Chart.yaml
dependencies:
- name: kube-state-metrics
version: "5.27.0"
repository: "https://prometheus-community.github.io/helm-charts"
condition: monitoring.enabled
alias: metrics
values.yaml
monitoring:
enabled: true # Le sous-chart est inclus

Tester la condition :

Fenêtre de terminal
# Avec monitoring activé
helm template mon-stack . --set monitoring.enabled=true 2>&1 | grep -E "^# Source:" | sort -u
mon-stack/charts/backend/templates/deployment.yaml
# Source: mon-stack/charts/backend/templates/service.yaml
# Source: mon-stack/charts/metrics/templates/clusterrolebinding.yaml
# Source: mon-stack/charts/metrics/templates/deployment.yaml
# Source: mon-stack/charts/metrics/templates/role.yaml
# Source: mon-stack/charts/metrics/templates/serviceaccount.yaml
# Source: mon-stack/charts/metrics/templates/service.yaml
Fenêtre de terminal
# Avec monitoring désactivé
helm template mon-stack . --set monitoring.enabled=false 2>&1 | grep -E "^# Source:" | sort -u
mon-stack/charts/backend/templates/deployment.yaml
# Source: mon-stack/charts/backend/templates/service.yaml

Le sous-chart metrics n'est plus rendu quand monitoring.enabled=false.

Les tags permettent de grouper plusieurs sous-charts et de les activer/désactiver ensemble :

Chart.yaml
dependencies:
- name: backend
version: "0.1.0"
repository: "file://charts/backend"
tags:
- backend
- api
- name: frontend
version: "0.1.0"
repository: "file://charts/frontend"
tags:
- frontend
- api
- name: kube-state-metrics
repository: "https://prometheus-community.github.io/helm-charts"
tags:
- monitoring
- observability
values.yaml
tags:
api: true # Active backend ET frontend
monitoring: false # Désactive kube-state-metrics

Quand un sous-chart a à la fois une condition et des tags, la condition a priorité :

conditiontagRésultat
truetrue✅ Inclus
truefalse✅ Inclus (condition prioritaire)
falsetrue❌ Exclu (condition prioritaire)
falsefalse❌ Exclu
non définietrue✅ Inclus
non définiefalse❌ Exclu

Un cas manque volontairement à ce tableau parce qu'il est la source d'erreur la plus fréquente : une condition déclarée dans Chart.yaml mais dont le chemin n'existe pas dans les values. Helm ne la considère alors pas comme fausse, il l'ignore purement et simplement, et le sous-chart est inclus. Autrement dit, oublier monitoring.enabled: false ne désactive rien : cela déploie. Déclarez donc toujours la clé référencée par une condition dans le values.yaml du parent.


Un umbrella chart est un chart qui ne contient (presque) pas de templates propres, il orchestre uniquement des sous-charts pour déployer une stack complète.

Deux détails de cette arborescence méritent votre attention. D'abord, le dossier templates/ du parent est quasi vide : un umbrella qui accumule ses propres manifestes n'en est plus un, il redevient un chart applicatif ordinaire et vous perdez le bénéfice de la composition. Ensuite, charts/ mélange volontairement des dossiers, sous-charts locaux versionnés avec le parent, et des archives, dépendances externes reconstruites par helm dependency build. C'est cette différence de nature qui détermine ce que vous commitez.

  • Répertoiremon-stack/
    • Chart.yaml Dépendances déclarées ici
    • Chart.lock Versions verrouillées
    • values.yaml Configuration globale + overrides subcharts
    • Répertoiretemplates/
    • Répertoirecharts/
      • Répertoirebackend/ Sous-chart local
        • …
      • Répertoiredatabase/ Sous-chart local
        • …
      • kube-state-metrics-5.27.0.tgz Dépendance externe

Voici un umbrella chart pour une application web avec monitoring :

apiVersion: v2
name: mon-stack
description: Stack web complète avec backend, database et monitoring
type: application
version: 1.0.0
appVersion: "1.0.0"
dependencies:
- name: backend
version: "0.1.0"
repository: "file://charts/backend"
tags:
- backend
- name: database
version: "0.1.0"
repository: "file://charts/database"
import-values:
- child: exports.connection
parent: dbConnection
- name: kube-state-metrics
version: "5.27.0"
repository: "https://prometheus-community.github.io/helm-charts"
condition: monitoring.enabled
alias: metrics

helm show chart renvoie le Chart.yaml relu par Helm, avec les clés triées par ordre alphabétique et les nombres normalisés, un appVersion: "1.0.0" ressortant sans ses guillemets. En revanche il n'ajoute rien : un Chart.yaml sans type ressort sans type, le défaut application reste implicite. C'est utile pour deux vérifications : contrôler qu'un alias, une condition ou un import-values a bien été pris en compte, et inspecter un chart empaqueté que vous n'avez pas écrit, en passant un .tgz à la place du dossier.

Fenêtre de terminal
helm show chart mon-stack/
apiVersion: v2
appVersion: 1.0.0
dependencies:
- name: backend
repository: file://charts/backend
tags:
- backend
version: 0.1.0
- import-values:
- child: exports.connection
parent: dbConnection
name: database
repository: file://charts/database
version: 0.1.0
- alias: metrics
condition: monitoring.enabled
name: kube-state-metrics
repository: https://prometheus-community.github.io/helm-charts
version: 5.27.0
description: Stack web complète avec backend, database et monitoring
name: mon-stack
type: application
version: 1.0.0

Quand vous packagez un umbrella chart, toutes les dépendances sont incluses dans l'archive :

Fenêtre de terminal
helm package mon-stack/ -d ./dist/
Successfully packaged chart and saved it to: ./dist/mon-stack-1.0.0.tgz
Fenêtre de terminal
tar tzf ./dist/mon-stack-1.0.0.tgz | head -20
mon-stack/Chart.yaml
mon-stack/Chart.lock
mon-stack/values.yaml
mon-stack/templates/configmap.yaml
mon-stack/charts/backend/Chart.yaml
mon-stack/charts/backend/values.yaml
mon-stack/charts/backend/templates/deployment.yaml
mon-stack/charts/backend/templates/service.yaml
mon-stack/charts/kube-state-metrics/Chart.yaml
mon-stack/charts/kube-state-metrics/values.yaml
mon-stack/charts/kube-state-metrics/templates/...

Les pièges qui suivent ont tous la même origine : deux charts écrits séparément se retrouvent dans le même namespace, et ce qui allait de soi pour chacun devient un conflit. Aucun n'est détecté par helm lint, tous se voient dans le rendu de helm template, à condition de savoir quoi y chercher.

Deux sous-charts peuvent générer des ressources avec le même nom, causant des conflits :

# backend génère : mon-stack-backend-config
# frontend génère aussi : mon-stack-frontend-config
# ✅ OK, noms différents
# Si les deux utilisent {{ .Release.Name }}-config :
# ❌ Conflit : mon-stack-config existe deux fois

Solution : Utilisez le pattern {{ include "chart.fullname" . }} qui inclut le nom du chart :

{{- define "backend.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}

Après modification de Chart.yaml, vous devez re-run helm dependency update :

Fenêtre de terminal
# ❌ Erreur si vous oubliez
helm template mon-stack .
# Error: an error occurred while checking for chart dependencies. You may need to run
# `helm dependency build` to fetch missing dependencies: found in Chart.yaml, but
# missing in charts/ directory: new-dependency
# ✅ Correct
helm dependency update mon-stack/
helm template mon-stack .

Une contrainte de version large ne pose problème que le jour où quelqu'un relance helm dependency update, et c'est précisément pourquoi elle passe inaperçue pendant des mois. Les quatre écritures ci-dessous se lisent de la plus dangereuse à la plus sûre. Retenez la différence entre les deux opérateurs SemVer : le tilde ~ n'autorise que les correctifs, le caret ^ autorise aussi les mineures. Pour une reproductibilité maximale, épinglez la version exacte : Chart.lock protège les autres membres de l'équipe, pas celui qui lance la mise à jour.

dependencies:
# ❌ Dangereux : peut sauter une major
- name: postgres
version: "*"
# ⚠️ Peut inclure des breaking changes mineurs
- name: postgres
version: ">=15.0.0"
# ✅ Recommandé : patch updates seulement
- name: postgres
version: "~15.5.0" # 15.5.x uniquement
# ✅ Recommandé : minor updates
- name: postgres
version: "^15.0.0" # 15.x.x uniquement

Si Chart.lock n'est pas dans le repo Git, chaque développeur peut avoir des versions différentes :

Fenêtre de terminal
# Fichiers à commiter
git add Chart.yaml Chart.lock values.yaml templates/
# Fichiers à ignorer (reconstruits via helm dependency build)
echo "charts/*.tgz" >> .gitignore

Sans condition, un sous-chart est toujours déployé même si non utilisé :

# ❌ Pas de condition : monitoring toujours déployé
- name: prometheus
version: "25.0.0"
repository: "https://prometheus-community.github.io/helm-charts"
# ✅ Avec condition : contrôle explicite
- name: prometheus
version: "25.0.0"
repository: "https://prometheus-community.github.io/helm-charts"
condition: prometheus.enabled

Ce lab est entièrement hors ligne : il valide une composition de charts sans rien déployer. C'est possible parce que les mécanismes de dépendance, d'alias, de condition et de values globales se jouent tous au rendu, pas à l'installation.

Ce lab enchaîne les cinq mécanismes du guide sur un chart minimal, sans rien déployer : helm template suffit à valider la composition, et le kubectl apply --dry-run=client de la dernière étape vérifie seulement que le YAML produit est accepté par l'API. Comptez une dizaine de minutes. Le point de contrôle le plus instructif est le quatrième critère : c'est celui qui prouve que la condition fonctionne, et celui qui échoue si vous avez oublié de déclarer monitoring.enabled.

  1. Créer la structure :

    Fenêtre de terminal
    mkdir -p mon-umbrella/charts/api/templates
  2. Déclarer le sous-chart API (charts/api/Chart.yaml) :

    apiVersion: v2
    name: api
    version: 0.1.0
  3. Ajouter une dépendance externe (Chart.yaml du parent) :

    dependencies:
    - name: api
    version: "0.1.0"
    repository: "file://charts/api"
    - name: kube-state-metrics
    version: "5.27.0"
    repository: "https://prometheus-community.github.io/helm-charts"
    condition: monitoring.enabled
    alias: metrics
  4. Configurer les values avec global.* et overrides :

    global:
    environment: staging
    api:
    replicaCount: 3
    monitoring:
    enabled: true
  5. Télécharger et valider :

    Fenêtre de terminal
    helm dependency update mon-umbrella/
    helm template test mon-umbrella/ | kubectl apply --dry-run=client -f -

Critères de réussite :

  • helm dependency list affiche toutes les dépendances en status ok
  • Chart.lock est généré avec les versions exactes
  • Les values global.* sont accessibles dans les sous-charts
  • --set monitoring.enabled=false exclut kube-state-metrics du rendu
  • Le chart se package avec toutes les dépendances incluses

ConceptCommande / SyntaxeUsage
Déclarerdependencies: dans Chart.yamlLister les sous-charts
Téléchargerhelm dependency updateDéveloppement, nouvelles versions
Reconstruirehelm dependency buildCI/CD, reproductibilité
Listerhelm dependency listVérifier les statuts
Values nomméesbackend.replicaCount: 2Configurer un sous-chart
Global valuesglobal.imageRegistryPropager à tous les sous-charts
Conditioncondition: db.enabledActiver/désactiver un sous-chart
Aliasalias: metricsRenommer un sous-chart

Six questions sur la composition : le refus de dependency build devant un verrou désynchronisé, la propagation de global, et ce que condition et alias permettent.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

5 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn