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 f
- 0
- Installs
- —
- Rating
- —
- Success rate
- 1
- Files scanned
Security scan
Scan passedNo risky patterns were found in the scanned files.
Content sha256 f00af6be9ec884b0… — run codexguild_scan_skills after installing to verify your local copy.
Static analysis is a first line of defense, not a guarantee. Read the source
SKILL.md
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>:
Multiple matches → show the candidates and ask which one.curl -s "https://grafana.com/api/plugins?filter=infinity" \ | jq -r '.items[] | "\(.slug)\t\(.name)"' # → yesoreyeram-infinity-datasource Infinity
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.json
ID=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.json
ID=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: false
Terraform → <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 misconfigured
Or 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
1- SKILL.md
ec16f1bed810.9 KB
Agent reviews
0No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.
More from grafana/skills8
Cut Grafana Cloud Metrics cost by shrinking active-series count with Adaptive Metrics aggregation rules — auto-recommendations from query history, custom exact/regex rules, label-drop config, unused-metric detection, and Alloy remote_write fallback. Use when investigating a high Mimir/Grafana Cloud
Manage Grafana Cloud accounts — organizations, stacks, RBAC roles and assignments, SSO/SAML/OAuth/GitHub auth, service accounts for CI/CD, user invites, team membership, and API-driven provisioning. Creates stacks via the Cloud API, mints service-account tokens, applies role assignments, configures
Use when the user asks to "write a validator", "add validation", "implement admission control", "write a mutating webhook", "add a mutation handler", "validate incoming resources", "implement admission logic", "add admission webhooks", "write ingress validation", or asks how to validate or mutate re
Configure Grafana Alerting, Incident Response Management (IRM), and SLOs end-to-end — provisions Grafana-managed and data-source-managed alert rules, contact points (Slack/PagerDuty/email/webhook), notification policies with hierarchical matchers, silences, mute timings, on-call schedules and escala
Build a unified telemetry pipeline with Grafana Alloy — one OpenTelemetry-compatible binary that collects metrics, logs, traces, and profiles and ships to Grafana Cloud / Prometheus / Loki / Tempo / Pyroscope. Covers the Alloy config language (blocks, `sys.env`, component refs), `prometheus.scrape`
Get RED metrics + service maps + frontend RUM + AI/LLM monitoring out of Grafana Cloud — Application Observability (`traces_spanmetrics_*` from OTel traces, p50/p95/p99 latency, exemplar-to-trace, traces-to-logs / profiles), Frontend Observability with the Faro Web SDK (Core Web Vitals, session repl
Use when starting any grafana-app-sdk work — scaffolding a Grafana app, initializing a Grafana App Platform app, picking a deployment mode (standalone operator / grafana/apps / frontend-only), wiring app-specific config, or onboarding to the SDK. Covers `grafana-app-sdk` CLI install, `project init`
Connect AI coding agents (Claude Code, Cursor, VS Code, OpenAI Codex) to Grafana Cloud via the `mcp-grafana` Model Context Protocol server. Installs the server with `go install`, generates a Grafana service-account token, wires `~/.claude/settings.json` or `~/.cursor/mcp.json` with the `command` + `
Related devops skillsscan passed
Deploy tRPC on WinterCG-compliant edge runtimes with fetchRequestHandler() from @trpc/server/adapters/fetch. Supports Cloudflare Workers, Deno Deploy, Vercel Edge Runtime, Astro, Remix, SolidStart. FetchCreateContextFnOptions provides req (Request) and resHeaders (Headers) for context creation. The
Automates CI/CD pipeline setup. Use when setting up or modifying build and deployment pipelines. Use when you need to automate quality gates, configure test runners in CI, or establish deployment strategies.
Deployment workflows, CI/CD pipeline patterns, Docker containerization, health checks, rollback strategies, and production readiness checklists for web applications. Use when setting up CI/CD, containerizing an app, or checking production readiness before a release.
Deploys and manages full-stack web applications (Next.js, Angular) with Server-Side Rendering (SSR) using Firebase App Hosting. Use when deploying Next.js/Angular apps, configuring apphosting.yaml or firebase.json apphosting blocks, managing secrets, setting up GitHub CI/CD, or configuring Blaze bil
Use when creating new skills, editing existing skills, or verifying skills work before deployment
Troubleshoots and debugs AWS Clean Rooms collaboration issues related to IAM roles, S3 bucket policies, KMS keys, Lake Formation permissions, and CloudWatch logging for custom ML model training and inference jobs. Use when a customer reports permission failures, access errors, or log publishing issu