Operate Grafana as Code: The Big Picture
What can live in files, what needs an API, and how the pieces fit together.
Click-driven Grafana works until the first time you need a second copy, a rollback, or an answer to “who changed this panel?”. This guide maps out how to run Grafana from files instead, so you know which mechanism to use for which resource before you write any YAML.
Why the UI becomes a problem
When dashboards, data sources, and alerts are created by hand, three things go wrong over time:
- Nothing is reproducible. The state lives in Grafana’s database. Rebuilding an instance means redoing every click.
- Changes are invisible. There’s no review step and no history beyond what Grafana’s own version log keeps.
- Environments drift. Staging and production slowly diverge, and nobody can say how.
The fix is to treat the database as a cache and the repository as the truth. Everything Grafana needs is either provisioned from files at startup or applied by a tool that reads files.
The layers
| Layer | Format | What it controls | Applied by |
|---|---|---|---|
| Server config | grafana.ini and GF_* env vars | Ports, database, auth, SMTP, logging, feature toggles | Grafana at startup |
| Data source provisioning | YAML | Data sources and their credentials | Grafana at startup |
| Dashboard provisioning | YAML provider + JSON files | Dashboards and folders | Grafana, re-scanned on an interval |
| Alerting provisioning | YAML | Alert rules, contact points, policies, mute timings, templates | Grafana at startup |
| Plugin provisioning | YAML | Settings for already-installed plugin apps | Grafana at startup |
| Terraform | HCL | Anything with an API: folders, data sources, dashboards, alerts, teams, service accounts | terraform apply |
| Grafana Operator | Kubernetes custom resources | Instances, folders, dashboards, data sources, alert rules | A controller in the cluster |
| Git Sync | A Repository resource | Dashboards kept in a Git repository, synced both ways | Grafana itself |
Which one should you use?
- One Grafana in a container or VM, a small team: server config plus file provisioning. It has no extra moving parts.
- Kubernetes with GitOps (Flux or Argo CD): the Grafana Helm chart for the instance, with provisioning files as ConfigMaps, or the Grafana Operator if you want each dashboard and data source as its own Kubernetes object.
- Many instances, or Grafana Cloud: Terraform, because it can also create stacks, service accounts, and teams.
- Dashboards authored by many people: Git Sync, or a code library such as the Grafana Foundation SDK that generates the JSON.
These mix well. A common setup is file provisioning for data sources and alerting, plus Git Sync or Terraform for dashboards.
What files can’t do
Some resources have no provisioning file format. Plan for them:
- Users, teams, organizations, and service accounts are created through the API or Terraform (or an identity provider with SSO and role mapping).
- Folder and dashboard permissions are managed through the API, Terraform, or the Operator.
- The first admin password is set only on first run, so changing it later takes a CLI or API call.
The guides on authentication and Terraform cover the workarounds.
Provisioned means locked
Provisioned resources are meant to be owned by files. Data sources can be marked editable: false, dashboards from a provider can reject UI saves, and provisioned alert resources can’t be edited in the UI at all. That’s the point: if someone could change them by hand, Git would stop being the truth. Remember that the UI is still useful for exploring data and drafting a panel, and the authoring workflow in the dashboards guide shows how to bring those drafts back into Git.
A mental model for a change
- Edit a file in the repository (a dashboard JSON, a data source YAML, an alert rule).
- Open a pull request, review the diff, merge.
- The delivery mechanism applies it: a container restart, a dashboard re-scan, a Flux reconcile, or
terraform apply. - Grafana’s own database is updated to match. If something goes wrong, revert the commit.
Where to go next
Run a local Grafana from a compose file (next guide), learn the configuration rules, then add data sources, dashboards, and alerts one at a time. For reference, see the Grafana documentation.
Popular Guides
-
Configure the Grafana Server with grafana.ini and Environment Variables Know where config files live, how overrides are ordered, and how to keep settings in Git. -
Provision Dashboards from JSON Files Load dashboards from disk, map folders from directories, and author them without losing changes. -
Provision Alert Rules, Contact Points, and Notification Policies Define the whole alerting pipeline in YAML so it is reviewed and versioned like code. -
Deploy Grafana on Kubernetes with Helm and Provisioning Values Run Grafana from a Helm chart where data sources, dashboards, and settings all come from values files. -
Reload, Verify, and Troubleshoot Provisioning from the Command Line Find out what Grafana loaded, reload without a restart, and fix the usual provisioning errors.