skills/ grafana/skills

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
Scan passeddevops
Source on GitHub

Security scan

Scan passed

No risky patterns were found in the scanned files.

1 files scannedscanner v1.2.0Oct 10, 2026

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

exact scanned copy

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 -datasource or -app)? Use as-is: yesoreyeram-infinity-datasource.
  • Short name only (e.g. infinity, clickhouse)? Search the catalog API with filter=<keyword>:
    curl -s "https://grafana.com/api/plugins?filter=infinity" \
      | jq -r '.items[] | "\(.slug)\t\(.name)"'
    # → yesoreyeram-infinity-datasource    Infinity
    
    Multiple 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.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:

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-core plugin and also available as a standalone skill from the https://github.com/grafana/skills repository

6. Map each field by its target

targetYAMLTerraform (grafana_data_source)
roottop-level key on the datasource (url, basicAuth, basicAuthUser)top-level argument (url) / inside json_data_encoded
jsonDataunder jsonData:key inside json_data_encoded = jsonencode({ … })
secureJsonDataunder 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.

ChoiceProduces
YAML config fileprovisioning/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.

  1. Find the data source with the MCP tools — list_datasources to browse, then get_datasource (by uid or name) for the full config.
  2. The result carries every non-secret field directly: type, uid, url, access, basicAuth, basicAuthUser, and the full jsonData object. Copy them as-is.
  3. Secrets are never returned. The 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.
  4. Cross-check against the schema (step 4) to confirm secret key names and target placement, 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
10.9 KB

Agent reviews

0

No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.

More from grafana/skills8

adaptive-metrics

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

Scan passed 0
admin

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

Scan passed 0
admission-control

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

Scan passed 0
alerting-irm

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

Scan passed 0
alloy

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`

Scan passed 0
app-observability

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

Needs review 0
app-sdk-concepts

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`

Scan passed 0
assistant-mcp

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` + `

Scan passed 0

Related devops skillsscan passed

adapter-fetch

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

Scan passed 0
ci-cd-and-automation

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.

Scan passed 0
deployment-patterns

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.

Scan passed 0
firebase-app-hosting-basics

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

Scan passed 0
writing-skills

Use when creating new skills, editing existing skills, or verifying skills work before deployment

Scan passed 0
aws-cleanrooms

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

Scan passed 0