Grafana Grafana

Secrets in der Grafana-Konfiguration verwalten

Halte Passwörter und Tokens mit Umgebungsvariablen, Dateien und verschlüsselten Manifesten aus Git heraus.

10 min Fortgeschritten

Konfiguration als Code funktioniert nur, wenn das Repository geteilt werden kann, und ein Repository mit Passwörtern kann es nicht. Grafana bietet mehrere Wege, Secrets aus den Dateien herauszuhalten und trotzdem alles deklarativ zu definieren. Diese Anleitung zeigt, wo Secrets auftauchen, wie du sie einspeist und was du mit den Secrets tun kannst, die Grafana selbst speichert.

Wo Secrets auftauchen

  • Servereinstellungen: das Admin-Passwort, das Datenbankpasswort, SMTP-Zugangsdaten, OAuth-Client-Secrets und der secret_key.
  • Datenquellen: Passwörter, Tokens und TLS-Schlüssel in secureJsonData.
  • Contact Points: Webhook-URLs, API-Schlüssel und Routing-Schlüssel in settings.
  • Provisioning für andere Werkzeuge: Terraform, der Operator und Git Sync brauchen jeweils ein API-Token oder eine Git-Zugangsberechtigung.

Methode 1: Umgebungsvariablen

Die einfachste Option. Provisioning-YAML unterstützt $VAR und ${VAR} in Werten, und grafana.ini unterstützt ${VAR} und $__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}

Regeln, die du dir merken solltest:

  • Die Interpolation funktioniert nur bei Werten, nicht bei Schlüsseln.
  • Nutze $$, wenn du ein literales Dollarzeichen brauchst (zum Beispiel in einem Template wie {{ $$labels }}).
  • Sie funktioniert nicht innerhalb von Dashboard-JSON und wird in einigen Alerting-Feldern nicht angewendet: Regel-Annotationen, Query-Modelle, relativeTimeRange, Namen und Intervalle von Mute Timings und Benachrichtigungs-Templates.

Lies die Variablen in Docker Compose aus einer nicht versionierten .env-Datei oder aus dem Secret Store deiner CI. In Kubernetes mappe ein Secret in den Container (siehe unten).

Methode 2: Secrets als Dateien

Grafana liest den Inhalt einer Datei mit $__file{} in eine Einstellung, wobei umgebende Leerzeichen entfernt werden:

[database]
password = $__file{/run/secrets/grafana_db_password}

[security]
secret_key = $__file{/run/secrets/grafana_secret_key}

Das passt zu Docker-Secrets und zu als Dateien gemounteten Kubernetes-Secrets und vermeidet, dass Werte über docker inspect oder Prozessumgebungen durchsickern. Das offizielle Docker-Image akzeptiert außerdem ein Suffix __FILE an GF_*-Variablennamen:

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

Methode 3: Kubernetes-Secrets

Speichere Zugangsdaten in einem Secret und stelle sie als Umgebungsvariablen bereit:

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

Das Grafana-Helm-Chart kann ein bestehendes Secret für den Admin-Benutzer nehmen und weitere für Umgebungsvariablen mounten, was die Kubernetes-Anleitung zeigt. Committe dieses Secret nicht als reines YAML. Verschlüssele es oder erzeuge es aus einem Secret Manager:

  • SOPS mit Flux oder Argo CD: committe grafana-secrets.yaml verschlüsselt und lass den GitOps-Controller es im Cluster entschlüsseln. Die Flux-Reihe in dieser Bibliothek hat eine SOPS-Anleitung.
  • External Secrets Operator oder ein CSI-Treiber: synchronisiere Secrets aus Vault, AWS Secrets Manager oder einem anderen Speicher und committe nur die Referenz.

Der secret_key und gespeicherte Secrets

Grafana verschlüsselt die Secrets, die es in seiner Datenbank speichert (etwa Passwörter von Datenquellen), mit der Einstellung secret_key. Zwei Folgen:

  • Setze ihn explizit und halte ihn über Neustarts, Replikas und Neuaufbauten hinweg gleich. Der Standardwert ist öffentlich, ihn ungesetzt zu lassen schwächt diese Verschlüsselung also.
  • Ändere ihn nicht leichtfertig. Ändert er sich, können vorhandene verschlüsselte Werte nicht entschlüsselt werden. Weil Datenquellen aus Dateien provisioniert werden, stellt erneutes Provisionieren mit dem neuen Schlüssel sie wieder her, aber nur in der UI eingegebene Secrets gehen verloren.

Hinweis zum Admin-Passwort

admin_password wirkt nur, wenn Grafana erstmals seine Datenbank anlegt. Um es später zu ändern, setze es über die CLI im Container oder über die API zurück, oder erstelle die Datenbank neu:

grafana cli admin reset-admin-password 'new-password'

Noch besser: Bringe Leute zu SSO, sodass das lokale Admin-Konto nur ein Break-Glass-Login ist, und speichere sein Passwort in deinem Secret Manager.

Tokens für die Werkzeuge rund um Grafana

  • Terraform und der Operator authentifizieren sich mit einem Service-Account-Token. Erstelle den Service Account mit einer minimalen Rolle, speichere das Token im Secret Store deiner CI oder deines Clusters und rotiere es nach Zeitplan.
  • Git Sync braucht eine Zugangsberechtigung des Git-Anbieters: ein Personal Access Token oder eine Verbindung über eine GitHub App oder OAuth App. Übergib das Token im Block secure der Repository-Ressource, sodass es als Secret gespeichert wird und nicht in der Spec.
  • Die Admin-Provisioning-API akzeptiert nur Basic Authentication mit einem Admin-Benutzer, keine API-Tokens, beschränke also, wer diese Endpunkte erreichen kann.

Checkliste

  • Kein Klartext-Secret in der Git-Historie. Ist eines durchgerutscht, rotiere es, lösche nicht nur den Commit.
  • secret_key explizit gesetzt und in deinem Secret Manager gespeichert.
  • Jede Umgebung hat ihr eigenes Datenbankpasswort, Admin-Passwort und eigene API-Tokens.
  • .env und Secrets-Ordner stehen in .gitignore, und CI scannt Commits auf Secrets.

Beliebte Anleitungen