Grafana
The Grafana plugin enables formae to manage Grafana instance resources — dashboards, data sources, folders, alerting, teams, and service accounts. Works with both self-hosted Grafana and Grafana Cloud instances.
Repository: formae-plugin-grafana
Installation
git clone https://github.com/platform-engineering-labs/formae-plugin-grafana.git
cd formae-plugin-grafana
make install
This builds the plugin and installs it to ~/.pel/formae/plugins/grafana/. The formae agent discovers installed plugins automatically on startup. Requires Go 1.25+ and Pkl CLI.
Configuration
Target
Configure a Grafana target in your Forma file:
import "@formae/formae.pkl"
import "@grafana/grafana.pkl"
target: formae.Target = new formae.Target {
label = "my-grafana"
namespace = "GRAFANA"
config = new grafana.Config {
url = "https://grafana.example.com"
// orgId = 1 // optional, defaults to token's org
}
}
Credentials
Set the GRAFANA_AUTH environment variable. Credentials are never stored in the target config.
Supported Formats:
| Format | Example |
|---|---|
| Service account token | glsa_xxxxxxxxxxxx |
| API key (legacy) | eyJrIjoi... |
| Basic auth | admin:password |
export GRAFANA_AUTH="glsa_your_service_account_token"
Examples
Examples are available in the plugin repository. Clone the repo and resolve Pkl dependencies before running:
git clone https://github.com/platform-engineering-labs/formae-plugin-grafana.git
cd formae-plugin-grafana
pkl project resolve examples/basic
Available examples:
| Example | Description |
|---|---|
| basic | Folder, data source, and dashboard |
| alerting | Contact points, mute timings, message templates, and notification routing |
| observability | LGTM stack via Docker Compose with Grafana dashboards provisioned through target resolvables |
# Evaluate an example
formae eval examples/basic/main.pkl
# Apply resources
formae apply --mode reconcile --watch examples/basic/main.pkl
Observability example
The observability example demonstrates target resolvables: the Grafana target config resolves its endpoint automatically from a Docker Compose plugin stack running the LGTM (Loki, Grafana, Tempo, Mimir) observability suite.
Requirements:
- formae >= 0.83.0
- Docker Compose plugin
- Docker
Usage:
# The LGTM stack uses default admin credentials
export GRAFANA_AUTH="admin:admin"
formae apply --mode reconcile --watch /opt/pel/formae/examples/formae-plugin-grafana/observability/main.pkl
!!! note After the first apply, the agent may need a restart for all OpenTelemetry metrics to appear in the dashboards. The gRPC OTLP exporter does not reconnect if the collector was unavailable when the plugin started. This will be fixed in a future release.
Supported Resources
Core
| Type | Description | Native ID | Discoverable | Extractable |
|---|---|---|---|---|
| Grafana::Core::Folder | Dashboard folders with nested hierarchy | uid | Yes | Yes |
| Grafana::Core::Dashboard | Dashboard definitions (JSON model) | uid | Yes | Yes |
| Grafana::Core::DataSource | Data source connections (Prometheus, Loki, etc.) | uid | Yes | Yes |
| Grafana::Core::Team | Teams for organizing users and permissions | id | Yes | No |
| Grafana::Core::ServiceAccount | Service accounts for programmatic API access | id | Yes | No |
Alerting
| Type | Description | Native ID | Discoverable | Extractable |
|---|---|---|---|---|
| Grafana::Alerting::AlertRule | Individual alert rules with query conditions | uid | Yes | No |
| Grafana::Alerting::ContactPoint | Notification channels (Slack, email, PagerDuty, etc.) | uid | Yes | No |
| Grafana::Alerting::NotificationPolicy | Alert routing tree (singleton per org) | receiver | Yes | No |
| Grafana::Alerting::MuteTiming | Time windows for suppressing notifications | name | Yes | No |
| Grafana::Alerting::MessageTemplate | Go templates for notification formatting | name | Yes | No |
What's next
- Learn more about resolvables in Res
- See Target resolvables for cross-plugin target configuration
- See the Docker Compose plugin for deploying infrastructure that Grafana targets can resolve from