Gérer les secrets dans la configuration de Grafana
Gardez mots de passe et jetons hors de Git grâce aux variables d'environnement, aux fichiers et aux manifestes chiffrés.
La configuration as code ne fonctionne que si le dépôt peut être partagé, et un dépôt qui contient des mots de passe ne peut pas l’être. Grafana offre plusieurs moyens de garder les secrets hors des fichiers tout en définissant tout de manière déclarative. Ce guide montre où apparaissent les secrets, comment les injecter, et que faire des secrets que Grafana stocke lui-même.
Où apparaissent les secrets
- Paramètres du serveur : le mot de passe admin, le mot de passe de la base de données, les identifiants SMTP, les secrets clients OAuth et la
secret_key. - Sources de données : mots de passe, jetons et clés TLS dans
secureJsonData. - Points de contact : URL de webhook, clés d’API et clés de routage dans
settings. - Provisionnement pour d’autres outils : Terraform, l’Operator et Git Sync ont chacun besoin d’un jeton d’API ou d’un identifiant Git.
Méthode 1 : variables d’environnement
L’option la plus simple. Le YAML de provisionnement prend en charge $VAR et ${VAR} dans les valeurs, et grafana.ini prend en charge ${VAR} et $__env{VAR} :
# provisioning/datasources/postgres.yaml
datasources:
- name: Postgres
uid: postgres-main
type: postgres
url: $POSTGRES_HOST:5432
secureJsonData:
password: $POSTGRES_PASSWORD
# grafana.ini
[security]
admin_password = ${GF_ADMIN_PASSWORD}
Règles à retenir :
- L’interpolation ne s’applique qu’aux valeurs, pas aux clés.
- Utilisez
$$quand vous avez besoin d’un signe dollar littéral (par exemple dans un modèle comme{{ $$labels }}). - Elle ne fonctionne pas dans le JSON des tableaux de bord, et elle n’est pas appliquée dans certains champs d’alerting : annotations de règles, modèles de requête,
relativeTimeRange, noms et intervalles des mute timings, et modèles de notification.
Dans Docker Compose, lisez les variables depuis un fichier .env non suivi ou depuis le magasin de secrets de votre CI. Dans Kubernetes, associez un Secret au conteneur (voir ci-dessous).
Méthode 2 : secrets sous forme de fichiers
Grafana lit le contenu d’un fichier dans un paramètre avec $__file{}, qui supprime les espaces environnants :
[database]
password = $__file{/run/secrets/grafana_db_password}
[security]
secret_key = $__file{/run/secrets/grafana_secret_key}
Cela convient aux secrets Docker et aux Secrets Kubernetes montés sous forme de fichiers, et évite de divulguer des valeurs via docker inspect ou les environnements de processus. L’image Docker officielle accepte aussi un suffixe __FILE sur les noms de variables GF_* :
services:
grafana:
image: grafana/grafana:13.1.0
environment:
GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/grafana_admin_password
secrets:
- grafana_admin_password
secrets:
grafana_admin_password:
file: ./secrets/grafana_admin_password.txt
Méthode 3 : Secrets Kubernetes
Stockez les identifiants dans un Secret et exposez-les comme variables d’environnement :
apiVersion: v1
kind: Secret
metadata:
name: grafana-secrets
namespace: monitoring
type: Opaque
stringData:
admin-password: change-me
slack-webhook-url: https://hooks.slack.com/services/XXX/YYY/ZZZ
postgres-password: change-me-too
env:
- name: SLACK_WEBHOOK_URL
valueFrom:
secretKeyRef:
name: grafana-secrets
key: slack-webhook-url
Le chart Helm de Grafana peut utiliser un Secret existant pour l’utilisateur admin et en monter d’autres pour les variables d’environnement, comme le montre le guide Kubernetes. Ne commitez pas ce Secret en YAML brut. Chiffrez-le, ou générez-le depuis un gestionnaire de secrets :
- SOPS avec Flux ou Argo CD : commitez
grafana-secrets.yamlchiffré, et laissez le contrôleur GitOps le déchiffrer dans le cluster. La série Flux de cette bibliothèque contient un guide sur SOPS. - External Secrets Operator ou un pilote CSI : synchronisez les secrets depuis Vault, AWS Secrets Manager ou un autre magasin, et ne commitez que la référence.
La secret_key et les secrets stockés
Grafana chiffre les secrets qu’il stocke dans sa base de données (comme les mots de passe des sources de données) avec le paramètre secret_key. Deux conséquences :
- Définissez-la explicitement et gardez-la identique entre les redémarrages, les réplicas et les reconstructions. La valeur par défaut est publique ; la laisser non définie affaiblit donc ce chiffrement.
- Ne la changez pas à la légère. Si elle change, les valeurs chiffrées existantes ne peuvent plus être déchiffrées. Comme les sources de données sont provisionnées depuis des fichiers, les provisionner à nouveau avec la nouvelle clé les restaure, mais les secrets saisis uniquement dans l’interface sont perdus.
Mise en garde sur le mot de passe admin
admin_password ne prend effet que lorsque Grafana crée sa base de données pour la première fois. Pour le changer plus tard, réinitialisez-le via la CLI à l’intérieur du conteneur ou via l’API, ou recréez la base de données :
grafana cli admin reset-admin-password 'new-password'
Mieux encore, orientez les gens vers le SSO afin que le compte admin local ne serve que de connexion de secours (break-glass), et stockez son mot de passe dans votre gestionnaire de secrets.
Jetons pour les outils autour de Grafana
- Terraform et l’Operator s’authentifient avec un jeton de compte de service. Créez le compte de service avec un rôle minimal, stockez le jeton dans le magasin de secrets de votre CI ou de votre cluster, et faites-le tourner selon un calendrier.
- Git Sync a besoin d’un identifiant du fournisseur Git : un jeton d’accès personnel, ou une connexion via GitHub App ou OAuth app. Passez le jeton dans le bloc
securede la ressourceRepository, afin qu’il soit stocké comme secret plutôt que dans la spec. - L’API de provisionnement admin n’accepte que l’authentification basique avec un utilisateur admin, pas les jetons d’API ; limitez donc qui peut atteindre ces endpoints.
Liste de contrôle
- Aucun secret en clair dans l’historique Git. Si l’un s’y est glissé, faites-le tourner, ne vous contentez pas de supprimer le commit.
secret_keydéfinie explicitement et stockée dans votre gestionnaire de secrets.- Chaque environnement a son propre mot de passe de base de données, mot de passe admin et jetons d’API.
- Les dossiers
.envet secrets sont dans.gitignore, et la CI analyse les commits à la recherche de secrets.
Guides populaires
-
Opérer Grafana comme du code : vue d'ensemble Ce qui peut vivre dans des fichiers, ce qui nécessite une API, et comment les pièces s'assemblent. -
Configurer le serveur Grafana avec grafana.ini et les variables d'environnement Sachez où se trouvent les fichiers de configuration, comment les surcharges sont ordonnées et comment garder les paramètres dans Git. -
Provisionner les tableaux de bord depuis des fichiers JSON Chargez les tableaux de bord depuis le disque, associez les dossiers aux répertoires et créez-les sans perdre vos modifications. -
Provisionner les règles d'alerte, les points de contact et les politiques de notification Définissez toute la chaîne d'alerting en YAML pour qu'elle soit relue et versionnée comme du code. -
Déployer Grafana sur Kubernetes avec Helm et des valeurs de provisionnement Exécutez Grafana depuis un chart Helm où sources de données, tableaux de bord et paramètres proviennent tous de fichiers de valeurs. -
Recharger, vérifier et dépanner le provisionnement en ligne de commande Découvrez ce que Grafana a chargé, rechargez sans redémarrer et corrigez les erreurs de provisionnement habituelles.