on
Managing Dashboards with GitOps: an intro to observability as code
Observability as code treats dashboards, alerts, data-source configs, and other observability artifacts as versioned, reviewable, and automatable code. For teams adopting GitOps, dashboards become declarative assets in a Git repository, synchronized to Grafana or another visualization platform by a continuous delivery system (Argo CD, Flux, or a provider-specific Git sync). The result is reproducible dashboards, audit trails for changes, and safer rollouts of visualization changes across environments. (grafana.com)
This article explains the core ideas, common implementation patterns, and practical gotchas for managing dashboards with GitOps. Examples use Grafana terminology because its “observability as code” features and ecosystem shine for this pattern, but the patterns apply to other dashboarding systems as well. (grafana.com)
Why treat dashboards as code?
- Single source of truth: A repository stores dashboard JSON, folders, and metadata so the canonical version is in Git rather than in a UI.
- Peer review and history: Pull requests and commits make changes auditable and allow reviews of visualization changes.
- Environment promotion: The same dashboard definitions can be promoted from staging to production using branches or separate repos.
- Repeatable provisioning: Automated provisioning prevents manual drift between environments and reduces configuration sprawl.
Grafana Labs has been explicitly building features and workflows for observability-as-code—integrating API-driven provisioning, Git Sync, and resource schemas to make dashboards first-class as-code resources. Recent product work expanded APIs and Terraform resources to support schema-based validation and programmatic generation of dashboards. (grafana.com)
Core concepts (short)
- Dashboard JSON model: Dashboards are stored as JSON objects. Grafana’s newer “v2” model decouples layout from panel configuration, improving readability and allowing programmatic generation. (github.com)
- Provisioning: Grafana supports file-based provisioning (reading JSON files from disk), API-driven provisioning, and a Git Sync mode that pulls dashboard files from a Git repository. (grafana.com)
- GitOps engines: Tools like Argo CD or Flux reconcile a Git repo of Kubernetes manifests (or ConfigMaps with dashboard JSON) into your cluster; a Grafana Operator or mounting provisioned files completes the chain to the running Grafana instance. (grafana.com)
Common GitOps patterns for dashboards
- ConfigMap provisioning (Kubernetes + GitOps)
- Store dashboard JSON files in a Git repo.
- A CI process or GitOps controller (Argo CD/Flux) applies ConfigMaps that contain the JSON to the cluster.
- Grafana reads those ConfigMaps via the provisioning mechanism or via a sidecar that writes them to the filesystem for provisioning.
- Good for small-to-medium setups because it’s simple and Kubernetes-native. (grafana.com)
- Grafana Operator + CRDs (Kubernetes + GitOps)
- The Grafana Operator exposes CRDs (custom resources) for dashboards and other Grafana resources.
- GitOps tools reconcile YAML CRs to the cluster, and the operator pushes those resources into Grafana, keeping the two in sync.
- Scales well and models Grafana resources as Kubernetes-native objects. (grafana.com)
- Git Sync (Grafana built-in)
- Grafana’s Git Sync can pull a repository of dashboard JSON files directly into Grafana; dashboards are provisioned from that folder.
- This removes the need for Kubernetes manifests and works well when teams prefer managing dashboards directly in a repo without an intermediate Operator. (grafana.com)
- Terraform / SDK-driven generation
- For generated or templated dashboards, an SDK or generator (jsonnet, grafonnet, or Grafana’s Foundation SDK) produces JSON that CI commits or pushes to the repo or applies directly via APIs or Terraform provider.
- Useful for reproducible, parameterized dashboards across many teams. (grafana.com)
Minimal repo layout (example)
A simple Git repo layout for a GitOps-driven Grafana provisioning approach:
- dashboards/
- staging/
- app-a.json
- app-b.json
- production/
- app-a.json
- staging/
- provisioning/
- dashboards.yaml # dashboard provider config for Grafana
- README.md
This keeps environment variants and provisioning config explicit and discoverable. Grafana renders README files inline for provisioned folders, which helps teams discover what each folder contains. (grafana.com)
Example: provisioning provider snippet
Grafana’s provisioning allows pointing to a filesystem path where dashboard JSON files live. In a Kubernetes setup that writes files into /var/lib/grafana/provisioning/dashboards, a provider might look like this:
apiVersion: 1
providers:
- name: 'gitops-dashboards'
orgId: 1
folder: 'GitOps'
type: file
options:
path: /var/lib/grafana/provisioning/dashboards/gitops
After provisioning, Grafana watches the filesystem and updates dashboards when JSON files change. The provisioning system strips IDs and manages version handling to avoid accidental overwrites. (grafana.com)
GitOps example: Argo CD + Grafana Operator (conceptual)
- Git repo holds Kubernetes manifests (ConfigMaps or Grafana CRDs) and dashboard JSON.
- Argo CD continuously reconciles the repo to the cluster.
- Grafana Operator detects new Dashboard CRs (or ConfigMaps) and pushes dashboards into Grafana, keeping Grafana and Git in sync.
Grafana documentation provides step-by-step examples for this pattern and sample manifests to check sync status in Argo CD. This flow gives strong reconciliation guarantees and fits well with Kubernetes-native delivery. (grafana.com)
Practical considerations and gotchas
- UID and id fields
- Dashboard JSON contains both id and uid fields. Provisioning usually removes id to let Grafana assign it, while uid is the stable identifier you should set and keep stable across versions. Leaving id in the JSON can cause provisioning conflicts. (grafana.com)
- Editable vs. provisioned state
- Dashboards provisioned from files or CRs are typically treated as non-editable in the UI to prevent drift. Set the dashboard metadata (editable: false) or control UI permissions to make the separation clear. Some teams allow temporary edits locally, but GitOps best practice is to prefer source-controlled changes. (oneuptime.com)
- Deletions and lifecycle
- Decide how deletions are handled: does removing a file from Git delete the dashboard from Grafana, or should the provisioning layer refuse deletes? Many setups support an “allow deletion” toggle; otherwise, orphaned dashboards can persist in the DB. Clear policies and folder-level README documentation help teams avoid surprises. (grafana.com)
- Validation and schema
- Use schema-based validation when possible. Grafana and related SDKs/tools provide validation helpers and Terraform providers that help prevent invalid JSON from reaching production. Programmatic generation (jsonnet, SDK) plus CI linting reduces broken dashboards in the main branch. (grafana.com)
- Secrets and data sources
- Dashboard JSON references data sources by name or UID. Manage data sources separately (provisioned or via provider APIs) to keep dashboards portable. Avoid embedding credentials in dashboard JSON; instead, rely on Grafana’s jsonData or provisioned data-source configs with secure secret injection when necessary. (grafana.com)
Testing and review workflow
Typical teams use pull requests for dashboard changes. Useful checks in CI:
- JSON schema linting to catch structural problems.
- Dry-run provisioning in a staging Grafana instance (or a headless JSON validator) to verify panels render and queries run.
- Automated visual diffs (snapshotting panels as images) for critical dashboards, where small layout regressions are important to catch.
Grafana’s move toward programmatic APIs and Terraform resources makes incorporating validation into CI/CD pipelines easier and more reliable. (grafana.com)
When to choose which pattern
- Start simple: Repo -> ConfigMaps -> Grafana provisioning (via GitOps) is quick to adopt for teams already using Kubernetes and Argo CD/Flux.
- Scale and multi-tenant needs: Grafana Operator + CRDs provides better modeling, multi-team isolation, and clearer lifecycle management.
- Direct repo sync without Kubernetes: Grafana Git Sync is handy when you want a straightforward repo-to-Grafana flow without Kubernetes in the middle. (grafana.com)
Short recipe: what a minimal GitOps dashboard change looks like (conceptual)
- Edit dashboard JSON or the generator template in a feature branch.
- Create a pull request with metadata and a README update describing intent.
- CI runs JSON linting and any tests; reviewers inspect queries and thresholds.
- Merge triggers your GitOps engine; manifests/ConfigMaps/CRDs reconcile to the cluster; Grafana updates the dashboard via provisioning or operator API.
That pipeline replaces manual dashboard edits and gives both traceability and a rollback path through Git history. (grafana.com)
Final notes on maturity and toollandscape
Grafana and the broader observability ecosystem have been investing in “dashboards as code” primitives—APIs, providers, and SDKs—that move the industry toward treating observability artifacts like other infrastructure. Official guidance, tutorials, and new Terraform resources make it easier to validate and distribute dashboards from code. For teams adopting GitOps, the key is to pick a pattern that matches operational scale and the team’s current platform (Kubernetes vs. non-Kubernetes) and to bake validation and review into the CI pipeline. (grafana.com)
Observability as code does more than protect dashboards from accidental edits: it makes dashboards reproducible infrastructure, opens observability to collaboration, and makes visualization changes traceable—core capabilities for reliable, scalable monitoring and SRE practices. (grafana.com)
References (examples)
- Grafana: Observability as Code (overview and tutorials). (grafana.com)
- Grafana: Work with provisioned dashboards in Git Sync. (grafana.com)
- Grafana: Provisioning documentation (file-based provisioning details). (grafana.com)
- Grafana blog: Observability as Code and dashboards-as-code product updates. (grafana.com)
- Grafana docs: Manage dashboards with GitOps using Argo CD + Grafana Operator. (grafana.com)