Grafana Provisioning

Provisioning lets you configure Grafana entirely through files instead of clicking through the UI. Data sources, dashboards, alert rules, and notification policies are defined in YAML or JSON files on disk. When Grafana starts, it reads these files and applies the configuration automatically. This is the foundation of infrastructure-as-code for your monitoring setup.

The Restaurant Franchise Analogy

A franchise restaurant chain does not rely on each branch manager to memorise the recipes and setup procedures. A central manual documents everything: how the kitchen is arranged, what equipment goes where, and exactly how each dish is prepared. Every new branch opens identically because staff follow the same manual. Grafana provisioning works the same way — your files are the manual, and every new Grafana instance reads them to configure itself identically.

Without provisioning:                 With provisioning:
  Install Grafana                       Install Grafana
  Log in to UI                          Copy provisioning files
  Click: Add data source                Restart Grafana
  Click: Configure Prometheus            ↓
  Click: Save                         Everything configured automatically
  Click: Import dashboard              ↓
  Click: Configure alerts             100 identical Grafana instances
  (repeat for every instance)         deployed in minutes

Provisioning Directory Structure

The default provisioning directory is /etc/grafana/provisioning/. Each subdirectory handles one type of configuration.

/etc/grafana/provisioning/
├── datasources/
│   └── prometheus.yaml
├── dashboards/
│   └── dashboard-provider.yaml
├── alerting/
│   ├── rules.yaml
│   └── notifications.yaml
└── plugins/
    └── plugins.yaml

You can change the base path in /etc/grafana/grafana.ini:

[paths]
provisioning = /etc/grafana/provisioning

Provisioning Data Sources

Create a YAML file in the datasources/ directory. Grafana reads all YAML files in this directory on startup (and on live reload).

# /etc/grafana/provisioning/datasources/prometheus.yaml

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    url: http://prometheus:9090
    access: proxy
    isDefault: true
    editable: false
    jsonData:
      scrapeInterval: 15s
      httpMethod: POST

  - name: Loki
    type: loki
    url: http://loki:3100
    access: proxy
    editable: false
    jsonData:
      derivedFields:
        - name: TraceID
          matcherRegex: "traceID=(\\w+)"
          url: "$${__value.raw}"
          datasourceUid: tempo

editable: false

Setting editable: false prevents users from modifying or deleting the provisioned data source through the UI. This is important in production — you want data sources managed through version-controlled files, not by users clicking around in the settings.

deleteDatasources

Add a deleteDatasources block to remove data sources that no longer appear in the provisioning files:

deleteDatasources:
  - name: Old MySQL
    orgId: 1

Provisioning Dashboards

Dashboard provisioning has two steps: configure a dashboard provider (which tells Grafana where to find dashboard JSON files), and place the dashboard JSON files in that location.

Step 1 – Dashboard Provider Configuration

# /etc/grafana/provisioning/dashboards/dashboard-provider.yaml

apiVersion: 1

providers:
  - name: Default
    type: file
    updateIntervalSeconds: 30
    options:
      path: /var/lib/grafana/dashboards
      foldersFromFilesStructure: true

The updateIntervalSeconds: 30 setting tells Grafana to check the directory every 30 seconds for new or changed JSON files. Any dashboard JSON file added to the directory appears in Grafana automatically within 30 seconds — no manual import needed.

The foldersFromFilesStructure: true setting maps subdirectory names to Grafana folder names:

/var/lib/grafana/dashboards/
├── infrastructure/
│   ├── server-health.json   → Grafana folder: "infrastructure"
│   └── network.json
└── business/
    └── sales-metrics.json   → Grafana folder: "business"

Step 2 – Place Dashboard JSON Files

Export your dashboards from the Grafana UI (Share → Export → Download JSON) and place the JSON files in the directory you configured. Grafana loads them automatically.

Provisioned Dashboards Are Read-Only in the UI

Users can view provisioned dashboards but cannot save changes to them through the UI. To modify a provisioned dashboard, edit the JSON file on disk — Grafana detects the change within the updateIntervalSeconds interval and applies it. This enforces the GitOps workflow where all changes go through version control.

Provisioning Alert Rules

Define alert rules in YAML files in the alerting/ directory.

# /etc/grafana/provisioning/alerting/rules.yaml

apiVersion: 1

groups:
  - orgId: 1
    name: Infrastructure Alerts
    folder: Alerts
    interval: 1m
    rules:
      - uid: cpu-high-alert
        title: High CPU Usage
        condition: C
        data:
          - refId: A
            datasourceUid: prometheus
            model:
              expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100)
              intervalMs: 1000
              maxDataPoints: 43200
          - refId: C
            datasourceUid: "-100"
            model:
              type: threshold
              conditions:
                - evaluator:
                    params: [90]
                    type: gt
                  reducer:
                    type: last
        noDataState: NoData
        execErrState: Error
        for: 5m
        annotations:
          summary: CPU usage above 90% on {{ $labels.instance }}
        labels:
          severity: critical

Provisioning Contact Points and Notification Policies

# /etc/grafana/provisioning/alerting/notifications.yaml

apiVersion: 1

contactPoints:
  - orgId: 1
    name: Ops Slack
    receivers:
      - uid: ops-slack-receiver
        type: slack
        settings:
          url: https://hooks.slack.com/services/T.../B.../...
          channel: "#alerts"

policies:
  - orgId: 1
    receiver: Ops Slack
    group_by: [alertname, instance]
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 4h
    routes:
      - receiver: Ops Slack
        matchers:
          - severity = critical

Grafana Provisioning with Docker Compose

Docker Compose is the most common way to deploy a fully provisioned Grafana stack. Mount the provisioning directory and dashboard files as volumes.

# docker-compose.yml

services:
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - ./provisioning:/etc/grafana/provisioning
      - ./dashboards:/var/lib/grafana/dashboards
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=secret
      - GF_AUTH_ANONYMOUS_ENABLED=false

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

Run docker compose up -d and the entire monitoring stack — Grafana pre-loaded with data sources, dashboards, and alerts — starts in one command. New team members get a fully working setup in minutes by cloning the Git repository and running the same command.

Live Reload

Grafana watches provisioning files for changes. Data source changes apply immediately on file save. Dashboard JSON files apply within the configured interval. Alert rules and notification policies apply after a short delay. You do not need to restart Grafana for most provisioning changes to take effect.

Leave a Comment

Your email address will not be published. Required fields are marked *