Provisioning Grafana dashboards from YAML config as code is a game-changer for managing your observability stack.

Here’s a Grafana setup provisioned directly from a YAML file, demonstrating how it works without needing to touch the UI:

apiVersion: 1
providers:
  - name: 'My Dashboards'
    orgId: 1
    folder: ''
    type: file
    disableDeletion: false
    editable: true
    options:
      folder: '/etc/grafana/provisioning/dashboards'

This providers.yaml file tells Grafana where to look for dashboard definitions. When Grafana starts or reloads its configuration, it scans the specified folder for files that look like dashboard definitions. In this case, it’s looking in /etc/grafana/provisioning/dashboards.

The magic happens when you place actual dashboard YAML files within that directory. For instance, you might have a file named my-app-overview.yaml in that folder with content like this:

apiVersion: 1

providers:
  - name: 'My App Dashboards'
    orgId: 1
    folder: 'My App'
    type: file
    disableDeletion: false
    editable: true
    options:
      folder: '/etc/grafana/provisioning/dashboards'
      # This is where the actual dashboard definition goes
      dashboards:
        - id: null # Grafana will generate an ID
          uid: my-app-overview-uid # A unique identifier for the dashboard
          title: 'My Application Overview'
          tags: ['app', 'overview']
          timezone: 'browser'
          schemaVersion: 16
          version: 0
          refresh: '25s'
          # Panel definitions would go here...
          panels:
            - title: 'HTTP Requests Rate'
              type: 'timeseries'
              datasource:
                type: 'prometheus'
                uid: 'your-prometheus-datasource-uid' # Replace with your actual Prometheus datasource UID
              targets:
                - expr: 'rate(http_requests_total[5m])'
              gridPos:
                x: 0
                y: 0
                w: 12
                h: 8

This my-app-overview.yaml file is a complete dashboard definition. apiVersion: 1 and providers are standard for provisioning. The dashboards array contains the actual dashboard configuration. Notice id: null means Grafana will assign one, while uid: my-app-overview-uid provides a stable, user-defined identifier that’s crucial for updates. The title, tags, timezone, schemaVersion, version, and refresh all configure the dashboard’s basic behavior. The panels array then defines the individual graphs and visualizations, including their title, type, datasource (using its UID), and targets (the queries to run). gridPos dictates its placement on the dashboard.

This approach means your dashboard configurations are version-controlled alongside your application code. When you need to update a dashboard, you modify the YAML file, commit it, and Grafana automatically picks up the changes.

The primary problem this solves is the manual, error-prone process of creating and updating dashboards through the Grafana UI. It ensures consistency across environments and makes dashboards a first-class citizen in your CI/CD pipelines. You can easily spin up new Grafana instances with pre-configured dashboards or roll back changes if a dashboard update causes issues.

To get this working, you’ll need to ensure your Grafana instance is configured to look for provisioning files. This is typically done via environment variables or a grafana.ini configuration file. For example, in grafana.ini:

[paths]
provisioning = /etc/grafana/provisioning

And in your Docker or Kubernetes deployment, you’d mount the provisioning/dashboards directory containing your YAML files.

The most surprising thing about this process is how seamlessly Grafana integrates it. You don’t need to restart Grafana for dashboard provisioning changes to take effect; it watches the directory for new or modified files and applies them dynamically.

This dynamic provisioning is incredibly powerful. You can even use templating engines like Jinja or Helm to generate these dashboard YAML files programmatically based on your infrastructure. Imagine having a dashboard that automatically provisions itself for every new service you deploy, populated with metrics specific to that service’s configuration.

The next concept you’ll likely explore is provisioning datasources themselves using similar YAML files, allowing your entire observability stack to be defined as code.

Want structured learning?

Take the full Grafana course →