npx skills add ...
npx skills add grafana/skills --skill datasources-provisioning
Generate a copy-paste Grafana data source provisioning file (YAML or Terraform) for any plugin from its standardized settings schema on the plugins CDN. Use when the user wants to provision or configure a data source as code — e.g. "provision infinity", "datasource yaml for clickhouse", "terraform for the github datasource" — even when they only name the plugin and not the word "provisioning".
npx skills add grafana/skills --skill datasources-provisioning
Ask this before anything else (skip only if the user already made it clear):
Provisioning needs the canonical plugin id (<org>-<name>-datasource), not the short name a user might say.
-datasource or -app)? Use as-is: yesoreyeram-infinity-datasource.infinity, clickhouse)? Search the catalog API with filter=<keyword>:
The snippets below use Infinity (yesoreyeram-infinity-datasource) as the worked example — substitute the id resolved here (and the version from step 3) in every command and output.
Never hardcode a version — the CDN path is version-pinned and a stale version 404s.
This file conforms to the dsconfig schema spec — the source of truth for how to interpret it. Don't re-derive field semantics from memory (valueType alone spans string, number, boolean, array, object, map, any); consult the spec when a field isn't a plain scalar:
dsconfig.json): https://raw.githubusercontent.com/grafana/dsconfig/refs/heads/main/dsconfig/schema.jsonWhat you need from each field to provision: key (the provisioning key), valueType, target (root | jsonData | secureJsonData), and validations (honor allowedValues for selectors like auth_method). Orientation example (schemaVersion: "v1"):
Select only the fields relevant to what the user asked for (chosen auth method + connection), not all of them. Each field's description tells you which auth method it belongs to.
For ready-made example configs, fetch v0alpha1.json:
Worked examples live under settingsExamples.examples, an object keyed by scenario (e.g. apiKey, oauth2ClientCredentials). Each entry has a summary/description (the scenario) and a value holding the jsonData/secureJsonData payload to lift straight into the file:
If schema/dsconfig.json 404s (older plugins):
NOTE: grafana-oss skill is available in
grafana-coreplugin and also available as a standalone skill from the https://github.com/grafana/skills repository
targettarget | YAML | Terraform (grafana_data_source) |
|---|---|---|
root | top-level key on the datasource (url, basicAuth, basicAuthUser) | top-level argument (url) / inside json_data_encoded |
jsonData | under jsonData: | key inside json_data_encoded = jsonencode({ … }) |
secureJsonData | under secureJsonData: as ${ENV_VAR} | key inside secure_json_data_encoded = jsonencode({ … }) via a sensitive variable |
Use each field's valueType for the scalar (string quoted in YAML, boolean→true/false, number bare). Never inline a real secret. Nested objects (oauth2, aws) and arrays (allowedHosts, scopes) map directly.
Always set access (root target) and default it to proxy — queries route through the Grafana server (the secure default); only use direct (browser → data source) if the user explicitly asks for it. In Terraform the argument is access_mode.
Now ask: YAML or Terraform? Same fields, different output file and syntax. Don't assume: "provision X" may mean either; skip the question only if the user already named a format ("terraform for X"). YAML file provisioning is the native, zero-dependency path; Terraform needs the official grafana/grafana provider.
| Choice | Produces |
|---|---|
| YAML config file | provisioning/datasources/<name>.yaml |
| Terraform | <name>.tf (grafana_data_source resource) |
<name> is just the file's basename — cosmetic, since both loaders read every file in the directory regardless of name. Default it to the plugin name.
YAML → provisioning/datasources/<name>.yaml:
Terraform → <name>.tf:
grafana_data_source is from the grafana/grafana provider — the authoritative reference for argument names (access_mode, json_data_encoded, secure_json_data_encoded). This file is only the resource; the user supplies the required_providers + provider "grafana" block and credentials.
Present the complete file in a single code block for the user to copy and paste into their environment — note where it goes:
provisioning/datasources/<name>.yaml (apply on Grafana start or a provisioning reload).terraform apply.Optionally, tell them how to confirm it worked once applied:
Or verify in the UI: visit <https://grafana.example.com>/connections/datasources/edit/<uid> and click Test.
To codify a data source already configured in a running instance, read its config through the Grafana MCP server (grafana/mcp-grafana).
Precondition: the Grafana MCP server is connected with its Datasources toolset enabled (it holds the instance credentials). If it isn't available, do not support this path — never ask the user to paste a Grafana token into chat. Fall back to the from-scratch Workflow instead.
list_datasources to browse, then get_datasource (by uid or name) for the full config.type, uid, url, access, basicAuth, basicAuthUser, and the full jsonData object. Copy them as-is.secureJsonFields map lists which secret keys are set (e.g. {"apiKeyValue": true}) without their values. Emit an ${ENV_VAR} placeholder in secureJsonData for each key it reports true.target placement, then continue at step 6 (map) and step 7 (emit) as normal.