Keep your dashboards in Git, not in Grafana's own database. A dashboard you build by clicking in the Grafana UI lives only in that one Grafana's database. If the pod moves or is rebuilt, Grafana comes up without that dashboard. Store them in Git as JSON and have Grafana load them on startup instead. Every cluster then gets the same views, changes go through review, and a rebuilt Grafana comes back with all of them. ## The sidecar loads dashboards from ConfigMaps The values in [Set up Grafana](/docs/hetzner/apalla/observability/dashboards/set-up-grafana) run a second container next to Grafana, its sidecar. It watches for ConfigMaps that carry the `grafana_dashboard` label and imports any dashboard JSON inside them. Put a dashboard's JSON in a ConfigMap with that label, and it appears in Grafana: ```yaml title="dashboard-configmap.yaml" apiVersion: v1 kind: ConfigMap metadata: name: cluster-overview-dashboard namespace: monitoring labels: grafana_dashboard: "1" # the label the sidecar watches for annotations: grafana_folder: "Platform" # the Grafana folder this dashboard lands in data: cluster-overview.json: | { "title": "Cluster overview", "panels": [ ... ] } ``` Organize dashboards into folders by setting a `grafana_folder` annotation, so a fleet's dashboards do not land in one flat list. ## Deliver them with GitOps GitOps means your cluster's configuration lives in Git, and a tool applies whatever is there. Commit those ConfigMaps to the repository your cluster syncs from, and Argo CD (or Flux) applies them like any other manifest. See [Set up Argo CD](/docs/hetzner/apalla/clusters/gitops/set-up-argo-cd). Now a dashboard change is a pull request: someone reviews it, it merges, and it rolls out to every cluster the app targets. No one edits a dashboard in production by hand. ## Template per cluster and namespace Template variables let one dashboard serve every cluster and every tenant. A template variable is a dropdown in Grafana that swaps what the panels show. Give a dashboard a `cluster` variable, bound to the external label you set in [Long-term storage and remote-write](/docs/hetzner/apalla/observability/metrics/long-term-storage-and-remote-write), and a `namespace` variable. For an agency, one reviewed set of dashboards then serves the whole fleet, each client seeing their own cluster through the same panels. See [Multi-cluster observability](/docs/hetzner/apalla/observability/multi-cluster/multi-cluster-observability). ## Generate large sets with Grafonnet Hand-written dashboard JSON is verbose and easy to break. For a large set, generate it: Grafonnet (a Jsonnet library) builds dashboards from code, so panels are reusable functions instead of copied JSON. It is worth the setup once you maintain more than a handful of dashboards or template heavily across a fleet.