Provision Data Sources from YAML
Define data sources, credentials, and custom headers in files instead of the UI.
Data sources are the first thing every dashboard and alert rule depends on, so they are the first thing to put in files. Grafana reads YAML from the provisioning/datasources folder at startup, creates the data sources it finds, and updates the ones that already exist.
A basic file
provisioning/datasources/datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
uid: prometheus
type: prometheus
access: proxy
orgId: 1
url: http://prometheus:9090
isDefault: true
editable: false
jsonData:
timeInterval: 15s
You can put one or many data sources in a file, and use several files. Grafana loads everything under the folder.
The fields that matter most:
nameis the display name.uidis the stable identifier that dashboards and alert rules reference. If you leave it out, Grafana generates one, which makes everything that references it fragile. Always set it.typeis the plugin ID, such asprometheus,loki,tempo,postgres, orelasticsearch.access: proxymeans Grafana’s server makes the requests. This is the normal choice and keeps credentials out of browsers.isDefaultmarks the data source new panels start with. Only one should be the default per organization.editable: falseblocks changes in the UI, so the file stays authoritative.jsonDataholds non-secret settings, and the keys depend on the plugin.secureJsonDataholds secrets, which Grafana encrypts in its database.versionis compared on updates. With several Grafana instances sharing a database, an instance only updates a data source when the file’s version is the same or higher than the stored one, so bump it when you change a file.
Credentials without committing them
Provisioning files support environment variable interpolation in values (not in keys) with $VAR or ${VAR}. Write $$ for a literal dollar sign:
apiVersion: 1
datasources:
- name: Postgres
uid: postgres-main
type: postgres
url: $POSTGRES_HOST:5432
user: $POSTGRES_USER
editable: false
jsonData:
database: app
sslmode: require
secureJsonData:
password: $POSTGRES_PASSWORD
Pass POSTGRES_PASSWORD into the container from your secret store (see the secrets guide). The password never appears in the repository, and Grafana stores it encrypted after loading.
Custom HTTP headers
Header names go in jsonData and their values in secureJsonData, numbered together:
datasources:
- name: Mimir
uid: mimir
type: prometheus
access: proxy
url: https://mimir.example.com/prometheus
jsonData:
httpHeaderName1: X-Scope-OrgID
secureJsonData:
httpHeaderValue1: tenant-a
Basic auth and TLS
datasources:
- name: Internal Prometheus
uid: prom-internal
type: prometheus
access: proxy
url: https://prometheus.internal:9090
basicAuth: true
basicAuthUser: grafana
jsonData:
tlsAuthWithCACert: true
secureJsonData:
basicAuthPassword: $PROM_PASSWORD
tlsCACert: $PROM_CA_CERT
Correlate logs, metrics, and traces
Several plugins link data sources to each other by UID, which is another reason to set UIDs by hand. For example, Loki can turn a log field into a link to traces in Tempo:
datasources:
- name: Loki
uid: loki
type: loki
access: proxy
url: http://loki:3100
jsonData:
derivedFields:
- name: TraceID
matcherRegex: 'trace_id=(\w+)'
url: '$${__value.raw}'
datasourceUid: tempo
Plugin-specific jsonData keys vary by version, so confirm them in the data source’s documentation. A quick way to discover them is to configure the data source once in a scratch instance and read the result from the API (GET /api/datasources/uid/<uid>).
Delete and prune
deleteDatasources removes data sources before datasources is processed. Use it when you retire one:
apiVersion: 1
deleteDatasources:
- name: Old Graphite
orgId: 1
To make the folder the full truth, add prune: true (Grafana 11.1 or newer). Provisioned data sources that are no longer in any file, or whose file is deleted, are then removed on the next start:
apiVersion: 1
prune: true
datasources:
- name: Prometheus
uid: prometheus
type: prometheus
url: http://prometheus:9090
Only provisioned data sources are pruned. Ones created by hand in the UI are left alone.
Apply and verify
Data sources are read at startup, so restart Grafana, or call the reload endpoint with admin basic auth:
curl -X POST -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/admin/provisioning/datasources/reload
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/datasources | jq '.[] | {name, uid, type, readOnly}'
Provisioned data sources report readOnly: true. To confirm connectivity without the UI, use the data source health endpoint:
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/datasources/uid/prometheus/health
If a data source didn’t load, check Grafana’s startup log for lines from the provisioning logger, which name the file and the error (usually YAML indentation, an unknown field, or a missing environment variable).
Popular Guides
-
Operate Grafana as Code: The Big Picture What can live in files, what needs an API, and how the pieces fit together. -
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.