Datasources Provisioning
Grafana LabsOfficialPublished by Grafana Labs
- Skill
- Workflow
- Cloud and DevOps
- Apache-2.0
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill automates the creation of Grafana data source provisioning configurations. It retrieves the standardized settings schema for any Grafana plugin from the official CDN to ensure accurate field mapping. Users can generate configuration files either from scratch by specifying a plugin or by converting an existing data source configuration from a running instance via the Grafana MCP server. The output is provided as ready-to-use YAML or Terraform code, following the required structure for data source provisioning.
What it does
- Resolves canonical plugin IDs from short names using the Grafana catalog API.
- Fetches and parses plugin-specific settings schemas to identify required configuration fields.
- Maps configuration fields to YAML or Terraform syntax based on their target (root, jsonData, or secureJsonData).
- Generates provisioning files for Grafana data sources as code.
- Provides placeholders for sensitive data using environment variables.
- Supports codifying existing data source configurations from a running instance.
When to use it
- When you need to provision a new Grafana data source using infrastructure-as-code.
- When you want to convert an existing manual data source configuration into a repeatable provisioning file.
- When you need to determine the correct configuration keys and types for a specific Grafana plugin.
- When you are setting up automated deployments for Grafana instances.
Advantages
- Ensures configuration accuracy by using authoritative plugin schemas.
- Supports both native YAML provisioning and Terraform provider syntax.
- Promotes secure practices by using environment variable placeholders for secrets.
- Reduces manual effort in identifying correct configuration parameters for diverse plugins.
Usage examples
- “provision infinity”
- The agent identifies the Infinity plugin, fetches its schema, and generates a YAML provisioning file with the appropriate fields.
- “terraform for the github datasource”
- The agent retrieves the schema for the GitHub datasource and outputs a Terraform resource block using the grafana_data_source provider.
- “datasource yaml for clickhouse”
- The agent provides a YAML configuration snippet tailored to the Clickhouse plugin's specific settings schema.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/grafana/datasources-provisioning/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip datasources-provisioning.zip -d .agents/skills
Documentation by Grafana Labs
Workflow
1. Ask the starting point: from scratch, or from an existing data source?
Ask this before anything else (skip only if the user already made it clear):
From scratch — the user names a plugin type to provision → continue with step 2.
From an existing data source in a running instance → jump to Convert an existing data source, then return to step 6.
2. Resolve the full plugin id
Provisioning needs the canonical plugin id (<org>-<name>-datasource), not the short name a user might say.
Already canonical (contains
-datasourceor-app)? Use as-is:yesoreyeram-infinity-datasource.Short name only (e.g.
infinity,clickhouse)? Search the catalog API withfilter=<keyword>:curl -s "https://grafana.com/api/plugins?filter=infinity" \ | jq -r '.items[] | "\(.slug)\t\(.name)"' # → yesoreyeram-infinity-datasource InfinityMultiple matches → show the candidates and ask which one.
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.
3. Resolve the latest version
curl -s "https://grafana.com/api/plugins/yesoreyeram-infinity-datasource" | jq -r '.version'Never hardcode a version — the CDN path is version-pinned and a stale version 404s.
4. Fetch the settings schema (primary structured source)
https://plugins-cdn.grafana.net/<PLUGIN_ID>/<VERSION>/public/plugins/<PLUGIN_ID>/schema/dsconfig.jsonID=yesoreyeram-infinity-datasource
VER=$(curl -s "https://grafana.com/api/plugins/$ID" | jq -r '.version')
curl -sf "https://plugins-cdn.grafana.net/$ID/$VER/public/plugins/$ID/schema/dsconfig.json"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:
Prose spec: https://raw.githubusercontent.com/grafana/dsconfig/refs/heads/main/dsconfig/schema.md
Meta-schema (defines the format of every
dsconfig.json): https://raw.githubusercontent.com/grafana/dsconfig/refs/heads/main/dsconfig/schema.json
What 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"):
{
"pluginType": "yesoreyeram-infinity-datasource",
"fields": [
{
"key": "auth_method",
"valueType": "string",
"target": "jsonData",
"validations": [
{
"type": "allowedValues",
"values": [
"none",
"basicAuth",
"apiKey",
"bearerToken",
"oauth2",
"aws",
"azureBlob"
]
}
]
}
]
}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:
https://plugins-cdn.grafana.net/<PLUGIN_ID>/<VERSION>/public/plugins/<PLUGIN_ID>/schema/v0alpha1.jsonID=yesoreyeram-infinity-datasource
VER=$(curl -s "https://grafana.com/api/plugins/$ID" | jq -r '.version')
curl -sf "https://plugins-cdn.grafana.net/$ID/$VER/public/plugins/$ID/schema/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:
# list scenarios, then pull one payload
... | jq -r '.settingsExamples.examples | keys[]'
... | jq '.settingsExamples.examples.apiKey.value'5. Fallback when no schema is published
If schema/dsconfig.json 404s (older plugins):
Last resort: the generic structure in grafana-oss skill (§ Data source provisioning) can also tell the user the field names are best-effort, not plugin-authoritative.
NOTE: grafana-oss skill is available in
grafana-coreplugin and also available as a standalone skill from the https://github.com/grafana/skills repository
6. Map each field by its target
target | 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.
7. Ask the format, then emit the file
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:
apiVersion: 1
datasources:
- name: Infinity # must be unique across the instance — collides even with a different datasource type
type: yesoreyeram-infinity-datasource # = pluginType from the schema
access: proxy # always set; default proxy (route queries through the Grafana server)
uid: infinity-ds # also unique and immutable so dashboards can reference it
jsonData:
auth_method: apiKey # value from validations.allowedValues
apiKeyKey: X-API-Key
apiKeyType: header
allowedHosts:
- https://api.example.com
secureJsonData:
apiKeyValue: ${API_KEY} # env var ref, never a literal secret
editable: falseTerraform → <name>.tf:
variable "api_key" {
type = string
sensitive = true
}
resource "grafana_data_source" "infinity" {
type = "yesoreyeram-infinity-datasource"
name = "Infinity"
uid = "infinity-ds"
access_mode = "proxy" # always set; default proxy (route queries through the Grafana server)
json_data_encoded = jsonencode({
auth_method = "apiKey"
apiKeyKey = "X-API-Key"
apiKeyType = "header"
allowedHosts = ["https://api.example.com"]
})
secure_json_data_encoded = jsonencode({
apiKeyValue = var.api_key
})
}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.
8. Return the file to the user
Present the complete file in a single code block for the user to copy and paste into their environment — note where it goes:
YAML →
provisioning/datasources/<name>.yaml(apply on Grafana start or a provisioning reload).Terraform → their Terraform config, applied with
terraform apply.
Optionally, tell them how to confirm it worked once applied:
curl -s https://grafana.example.com/api/datasources/uid/<uid>/health \
-H "Authorization: Bearer <token>"
# { "status": "OK" } → working
# { "status": "ERROR" } → URL unreachable or auth misconfiguredOr verify in the UI: visit <https://grafana.example.com>/connections/datasources/edit/<uid> and click Test.
Convert an existing data source
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.
Find the data source with the MCP tools —
list_datasourcesto browse, thenget_datasource(byuidorname) for the full config.The result carries every non-secret field directly:
type,uid,url,access,basicAuth,basicAuthUser, and the fulljsonDataobject. Copy them as-is.Secrets are never returned. The
secureJsonFieldsmap lists which secret keys are set (e.g.{"apiKeyValue": true}) without their values. Emit an${ENV_VAR}placeholder insecureJsonDatafor each key it reportstrue.Cross-check against the schema (step 4) to confirm secret key names and
targetplacement, then continue at step 6 (map) and step 7 (emit) as normal.
Related
grafana-oss — generic data source / dashboard provisioning structure and provisioning paths.
Files
- ATTRIBUTION.mdAdded by AutoGineer875 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md10.9 KiB
ATTRIBUTION.md
Attribution
This folder is an unmodified copy of the Agent Skill "datasources-provisioning", distributed by AutoGineer (https://autogineer.com/agent-skills).
Commit: 8fb72a527961f05e708f53d2a0500709e12d7970
Published by: Grafana Labs (https://github.com/grafana)
Publisher: Grafana Labs (https://github.com/grafana)
Licence: Apache License 2.0 (https://spdx.org/licenses/Apache-2.0.html)
Licence evidence: declared in the frontmatter ("license: Apache-2.0")
Retrieved: 2026-11-07
The skill's own files are unmodified copies. AutoGineer is not affiliated with or endorsed by the author or the publisher.
Files added by AutoGineer
ATTRIBUTION.md: this file, written by AutoGineer
LICENSE: copied from LICENSE
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server, Needs network access, Needs an API key
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Grafana Labs
- Publisher
- Grafana Labs (Official)
- Source
- grafana/skills · skills/grafana-datasources/datasources-provisioning · commit 8fb72a5
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Grafana Labs.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download datasources-provisioning.zip