Grafana Provisioning for DevOps: Documentation First GitOps and CI
Documentation first guide to Grafana provisioning for DevOps engineers. Adopt GitOps and CI validation, design repo layouts, and stop configuration drift.
Grafana provisioning lets you declare data sources, dashboards, and plugins as YAML files so every change ships through version control instead of a UI click. The moment a resource is under provisioning, it becomes the single source of truth, and Grafana blocks UI edits or deletes on it. Your first move: drop manifests into the provisioning/ directory tree and run them through a CI lint step before they ever touch a running Grafana instance.
TL;DR:
- Properly set the
paths.provisioningin Grafana’s config to ensure the correct directory is scanned for YAML manifests, especially in container or Kubernetes deployments.- Always include
prune: truein data source manifests cautiously, as it deletes sources missing from the YAML, risking accidental removal.- Use consistent UIDs for dashboards and keep version numbers up-to-date to prevent overwriting during restarts in high-availability environments.
- Separate development and production provisioning paths, and validate manifests with CI linting to prevent configuration errors before deployment.
- Automate repository management with GitOps practices, staging, and environment-specific paths to maintain reproducibility and avoid drift in large-scale deployments.
Table of Contents
- What Is Grafana Provisioning and Where Do the Files Live?
- How Do You Provision Data Sources With YAML Manifests?
- How Do Dashboard Providers and Folder Mapping Work?
- Can You Provision Plugins and Apps the Same Way?
- File-Based Provisioning vs. Classic Provisioning: What’s the Difference?
- What GitOps Practices Keep Provisioning Manageable at Scale?
- What Do Minimal Manifests and a CI Checklist Look Like?
- Provisioning in Real Operations: What Actually Changes
- Accelerate Your Provisioning Workflow With Ready-Made Assets
- Sources
What Is Grafana Provisioning and Where Do the Files Live?
Grafana reads its provisioning configuration from a path set in grafana.ini (or custom.ini), under the paths.provisioning key. Out of the box, that points to conf/provisioning/ on most installs, but you can repoint it anywhere your deployment pipeline expects it, which matters if you’re baking configs into a container image or mounting a ConfigMap in Kubernetes.
Inside that directory, Grafana expects a fixed structure:
provisioning/datasources/for data source YAML manifestsprovisioning/dashboards/for dashboard provider definitions (and optionally the dashboard JSON itself)provisioning/plugins/for app plugin configuration
Each subfolder can hold multiple YAML files, and Grafana scans all of them at startup and on an interval afterward. If you’re running in a locked-down environment, check permitted_provisioning_paths — it restricts which filesystem locations Grafana is allowed to read from, which trips people up when a mounted volume sits outside the allowed path. For credentials, Grafana supports environment variable expansion inside these files using $VAR or ${VAR} syntax, so you never need to hardcode a token directly into a manifest that lives in Git.
How Do You Provision Data Sources With YAML Manifests?
A data source manifest follows a simple skeleton: an apiVersion, then a datasources: list where each entry defines name, type, url, and access. Anything beyond the basics, custom headers, query timeouts, TLS settings, goes into jsonData. Anything sensitive, API keys, passwords, client certificates, goes into secureJsonData, and the values there should reference environment variables rather than sit in plaintext.
apiVersion: 1
datasources:
- name: Prometheus-Prod
type: prometheus
access: proxy
url: http://prometheus.prod.svc:9090
isDefault: true
jsonData:
timeInterval: "15s"
secureJsonData:
httpHeaderValue1: "$PROM_AUTH_TOKEN"
version: 2
Two fields deserve extra attention. Setting prune: true at the top of the file tells Grafana to delete any provisioned data source that no longer appears in the manifest, which is powerful but unforgiving if someone removes an entry by accident. And the version number on each data source matters more than most teams realize: in a multi-instance or high-availability setup, Grafana uses version numbers to decide which config wins on restart, so an older instance restarting later won’t silently clobber a newer configuration.
Pro Tip: Never commit secureJsonData values directly, even as placeholders. Reference an environment variable every time, and let your secrets manager or CI pipeline inject the real value at deploy time.
How Do Dashboard Providers and Folder Mapping Work?
Dashboard provisioning runs through a separate providers list, and each provider needs a name, a target folder, type: file, and an options.path pointing at the JSON files it should load. From there, three settings shape how dashboards behave once they’re live.
foldersFromFilesStructuretells Grafana to mirror your filesystem’s subfolder layout inside the Grafana UI instead of dumping everything into one flat folder.updateIntervalSecondscontrols how often Grafana rescans the path for changes. The default is 10 seconds, which means most dashboard edits show up without a restart.allowUiUpdatesdecides whether someone can tweak a provisioned dashboard in the UI and have that change persist, or whether Grafana overwrites it back to the file version on the next scan.
A few practical notes worth keeping in mind:
foldersFromFilesStructureis convenient for onboarding new teams fast, but a messy or unplanned filesystem tree turns into a messy Grafana sidebar. Design the hierarchy before you flip the switch.- Every dashboard JSON file should carry a stable UID, not just an auto-generated
id. UIDs survive repository migrations and environment promotions, while numeric IDs do not. - Leave
allowUiUpdates: falsein production once a dashboard is stable. It’s the difference between “the file is the truth” and “someone’s Tuesday-afternoon edit is the truth until the next scan.”
Can You Provision Plugins and Apps the Same Way?
Yes, though it’s a smaller surface area. Drop YAML files into provisioning/plugins/ using an apps: list, where each entry references a plugin by its type identifier and carries its own jsonData block for plugin-specific settings like API endpoints or default org assignments.
- Plugin provisioning enables or configures an already-installed plugin. It doesn’t install the plugin binary itself.
- Use
jsonDatafor non-sensitive plugin settings and the samesecureJsonDatapattern for anything that needs to stay out of source control. - File-based plugin provisioning can’t replicate every action available in the UI. Some plugin-specific configuration screens still require a manual step the first time, so treat this as a starting point rather than full parity.
File-Based Provisioning vs. Classic Provisioning: What’s the Difference?
Grafana introduced on-prem file provisioning in version 12, and it’s easy to confuse with the classic YAML approach described above. On-prem file provisioning covers dashboards only and connects to a repository or local directory that Grafana syncs continuously. It does not touch data sources, and it isn’t available on Grafana Cloud, so it complements classic provisioning rather than replacing it.
- Set
permitted_provisioning_pathsto define exactly which directories or repository connections Grafana can sync from. - You can migrate an existing unmanaged dashboard into the provisioned folder as part of adopting this workflow, rather than rebuilding it from scratch.
- Expect a short synchronization lag between a commit landing and Grafana reflecting it. It’s not instant, so build that into any rollout timing.
What GitOps Practices Keep Provisioning Manageable at Scale?
Treat provisioning changes exactly like application code changes: no direct edits to a running instance, everything through a pull request, everything validated before merge, as explained in What Is User Provisioning? A Guide for IT Teams.
- Design your repository’s directory tree deliberately before turning on
foldersFromFilesStructure— retrofitting folder structure after fifty dashboards exist is painful. - Run a YAML/JSON linter and a schema validation step in CI on every pull request, and fail the merge if a manifest is malformed. A tool like Grafonnet can generate valid dashboard JSON programmatically, which cuts down on hand-edited syntax errors.
- Separate dev and prod provisioning paths, or bake them into separate images, so a bad manifest in staging never has a path to production.
- Assign UIDs deliberately, keep version numbers current on data sources, and stage rollouts through a lower environment before promoting.
Pro Tip: Wire your provisioning repo into the same pipeline you already use for infrastructure changes. A pattern like Argo CD or Flux applying config on merge turns provisioning into the same reviewable, revertible process as everything else in your stack.
What Do Minimal Manifests and a CI Checklist Look Like?
A minimal working setup needs almost nothing beyond the two file types below, plus a validation gate in your pipeline.
apiVersion: 1
datasources:
- name: Loki
type: loki
url: http://loki:3100
access: proxy
apiVersion: 1
providers:
- name: default
folder: Production
type: file
options:
path: /etc/grafana/provisioning/dashboards/prod
updateIntervalSeconds: 30
- Lint every YAML and JSON file with a schema validator before merge.
- Deploy to a staging Grafana instance first and confirm the dashboards render with the correct UID before promoting.
- Keep the official provisioning tutorial open as a working reference while you build out your first repository structure.
Provisioning in Real Operations: What Actually Changes
Provisioning’s real payoff shows up months in, not on day one: environments stop drifting apart, and rebuilding a Grafana instance from scratch becomes a repository checkout instead of a memory exercise. The upfront cost is real. You have to design a repo structure and CI validation before you get any of that benefit, and skipping that step just moves the pain to your first production incident instead of removing it.
Teams that treat provisioning like application code, staged rollouts, gated merges, versioned data sources, get the reproducibility without the surprise deletions. Teams that treat it as a one-time YAML dump usually rediscover prune: true the hard way.
— James
Accelerate Your Provisioning Workflow With Ready-Made Assets
Writing every YAML manifest and CI validation step from scratch works, but it’s slow the first time through. Devopsaitoolkit builds downloadable playbooks, validator scripts, and CI examples specifically for engineers automating Grafana, Prometheus, and Kubernetes infrastructure, so you’re adapting a tested pattern instead of debugging your first schema validator at 2 a.m.

The toolkit’s provisioning-focused resources cover repository layout templates, staged rollout checklists, and lint configurations you can drop straight into an existing pipeline, alongside prompt packs for troubleshooting the config errors that show up once you’re running this at scale. If your team is also managing Linux hosts, check the Linux Admins AI Prompts library for copy-paste diagnostic prompts that pair well with provisioning debugging work. Browse the full catalog on the AI Workflows for Real Cloud Engineers landing page and see which playbook matches your current provisioning setup.
Recommended
- Grafana Dashboards as Code with Grafonnet: A GitOps Workflow
- GitOps for Infrastructure: How Git Becomes Your Control Plane
- GitOps Automation Pipelines with Argo CD and Flux
- Automating Helm Chart Deployments: A DevOps Guide
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.