Configuration as Code (Provisioning)
Relevant source files
The following files were used as context for generating this wiki page:
- pkg/services/provisioning/provisioning.go
- conf/provisioning/dashboards/sample.yaml
- contribute/backend/recommended-practices.md
- contribute/architecture/k8s-inspired-backend-arch.md
- pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v0alpha1.json
- pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v1beta1.json
Configuration as Code (Provisioning) is a system within Grafana that allows users to define and manage resources—such as dashboards, data sources, and alert notifiers—using configuration files or declarative APIs rather than manual UI interactions. The primary goal is to ensure that every feature requiring state can be configured via files, enabling version control, reproducibility, and automated deployment workflows.
Sources: contribute/backend/recommended-practices.md:118-120, contribute/architecture/k8s-inspired-backend-arch.md:1-10
Architecture and Design
Grafana is transitioning from a traditional file-based provisioning system to a Kubernetes-inspired, resource-oriented model. This transition moves resources from opaque blobs stored in specific tables to structured objects accessible via Resource APIs (/apis/...).
Provisioning Service Core
The ProvisioningService is the central component responsible for coordinating the provisioning of different resource types. It provides methods to trigger the provisioning process for dashboards, data sources, and other configurable entities.
The diagram above represents the high-level flow of the ProvisioningService during the application lifecycle.
Sources: pkg/services/provisioning/provisioning.go:10-30
Resource APIs and Unified Storage
Modern provisioning utilizes a declarative state model where users define the "desired state" of resources. Grafana then aligns the system's current state with this declaration.
- Unified Storage: An internal abstraction layer that handles resource persistence in the configured SQL database (PostgreSQL, MySQL, or SQLite) while providing a Kubernetes-like interface (
Get,Create,Watch). - Resource Versioning: Every resource modification updates a
resourceVersioncounter, used for optimistic concurrency control and efficientWatchoperations.
Sources: contribute/architecture/k8s-inspired-backend-arch.md:20-35, contribute/architecture/k8s-inspired-backend-arch.md:65-80
File-Based Provisioning
Traditional provisioning relies on YAML configuration files located in the conf/provisioning directory. These files define "providers" that scan specific paths for resource definitions (e.g., JSON dashboard models).
Dashboard Provisioning Configuration
Dashboards are provisioned using providers that define where JSON files are located and how they should be handled in the database.
| Field | Type | Description |
|---|---|---|
name | string | Unique name for the dashboard provider. |
type | string | Type of provider, typically file. |
allowUiUpdates | boolean | If true, UI changes are allowed but may be overwritten by the file on restart. |
options.path | string | The directory path where JSON dashboard files are stored. |
options.foldersFromFiles | boolean | If true, folder structures are mirrored based on the file system. |
Sources: conf/provisioning/dashboards/sample.yaml:7-35
Modern Resource Provisioning APIs
The modern provisioning system introduces the provisioning.grafana.app API group, which manages connections to external Git providers and synchronizes resources into Grafana organizations (namespaces).
API Components
- Connection: Defines authentication and connection details for external providers like GitHub, GitLab, or Bitbucket.
- Repository: Configures specific repositories, branches, and paths to be monitored for Grafana resource files.
- Job: Represents an execution instance of a synchronization task (e.g., pulling files from Git, pushing changes, or migrating history).
The sequence shows how the modern API coordinates with external Git providers to synchronize resource state.
Sources: pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v0alpha1.json:500-1500, contribute/architecture/k8s-inspired-backend-arch.md:100-120
Connection Types
The system supports multiple git provider types for fetching configuration as code.
| Provider | Key Configuration Elements |
|---|---|
| GitHub | appID, installationID, privateKey |
| GitLab | clientID, url, token |
| Bitbucket | clientID, url, tokenUser |
Sources: pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v0alpha1.json:1000-1200
Migration and Coexistence
Grafana supports the coexistence of legacy and modern provisioning styles. The migration path follows a structured lifecycle from Alpha to GA.
- Alpha (
v1alpha1): Initial schema definition using CUE and basic handlers interacting with legacy storage. - Beta (
v1beta1): Stable API with a deprecation policy; the resource becomes the source of truth under feature flags. - GA (
v1): Strong stability guarantees; legacy API endpoints are deprecated.
Sources: contribute/architecture/k8s-inspired-backend-arch.md:180-210, pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v1beta1.json
Summary
Provisioning in Grafana provides a robust mechanism for Configuration as Code, evolving from static file-based shims to a dynamic, declarative API model inspired by Kubernetes. By utilizing the provisioning.grafana.app APIs, organizations can automate the management of dashboards, connections, and repositories, ensuring that the platform's state is versioned, auditable, and easily reproducible across environments.