Overview
Grafana is the open-source (AGPL-3.0) dashboarding and alerting front end for time-series and SQL data. This template deploys Grafana OSS as a stateless app tier backed by a highly available PostgreSQL app database — every dashboard, user, alert rule, and saved datasource lives in that database, so the Grafana workload itself holds no state and can run multiple replicas. This template exists to visualize data you own: the catalog’s Prometheus, Thanos, and Grafana Mimir installs, your own SQL databases, and external systems. It is not an observability stack in itself — it ships no collectors, no exporters, and no data.This template ships zero dashboards and zero datasources. A fresh install has an empty dashboard list and an empty datasource list — you connect your own datasources (in the UI or as code) and build or import your own dashboards. Control Plane’s console already provides built-in workload-metrics dashboards for every workload; this template is for the data those dashboards do not cover.
Architecture
- Grafana — A stateless standard workload serving the UI and HTTP API on port
3000. Thereplicasknob controls how many instances run; all replicas share the same PostgreSQL app database. - PostgreSQL (HA, default) — The postgres-highly-available template as a subchart: 3× Patroni PostgreSQL, 3× etcd, and a HAProxy leader-routing endpoint Grafana connects through.
- PostgreSQL (dev/lightweight, optional) — The single-instance postgres template instead, for lighter non-HA deployments.
- Redis Sentinel (optional) — The redis template as a subchart in Sentinel mode. Grafana’s alerting HA uses it to coordinate alert evaluation across replicas, so exactly one notification is sent per alert. Required when
replicasis 2 or more. - Hardened defaults — User signup, anonymous access, and upstream telemetry are all disabled. When public access is on, Grafana’s
root_urlis derived automatically from the canonical endpoint.
What Gets Created
- Standard Grafana Workload —
replicasstateless instances serving the UI and API on port3000. - Database Workloads — HA mode: a stateful Patroni PostgreSQL workload, a stateful etcd workload, and a standard HAProxy leader-routing workload. Single mode: one stateful PostgreSQL workload.
- Redis Workloads (optional) — A Redis workload and a Sentinel workload (3 replicas each by default) when
redis.enabledis true. - Volume Sets — The database subchart’s persistent volumes (10 GiB per replica by default), plus the etcd volumes in HA mode. Grafana itself has none.
- Secrets — A dictionary secret holding the admin bootstrap credentials and the datasource-encryption key, the database credentials created by the subchart, and — only when
datasources.definitionsis set — an opaque secret holding the rendered datasource provisioning file. - Identity & Policy — A least-privilege policy granting the Grafana identity
revealon exactly the secrets it uses, including any prerequisite datasource-credential or SMTP secrets you name. - Cron Backup Workload (optional) — When database backups are enabled.
This template does not create a GVC. You must deploy it into an existing GVC.
Prerequisites
A default install has no prerequisites. Three optional features each need a secret or a bucket created before you install:
Install the template using your preferred method:
UI
Browse, install, and manage templates visually
CLI
Manage templates from your terminal
Terraform
Declare templates in your Terraform configurations
Pulumi
Declare templates in your Pulumi programs
Choosing a Database Mode
Exactly one of the two database modes must be enabled — the chart enforces this at render and fails the install with a clear message otherwise.
In HA mode the full stack converges in roughly 6 minutes on a fresh install: etcd comes up first, then the PostgreSQL cluster and its HAProxy endpoint, then Grafana runs its schema migrations. Single mode is faster.
Configuration
The defaultvalues.yaml for this template:
Grafana Instance
image— The Grafana OSS container image.replicas— Number of Grafana instances.1is a single instance;2or more forms an HA tier over the shared app database and requiresredis.enabled: true— see High Availability.resources— CPU and memory for the Grafana container.admin.user/admin.password— The initial admin login, applied on first boot only. Changing them after install does not modify the existing account — change the password inside Grafana instead. The defaultadmin/adminlogin does not work; the values you set are what apply.admin.secretKey— The key Grafana uses to encrypt datasource credentials at rest in the app database. Set it once before installing and never rotate it: every saved datasource secret is encrypted with it, and a changed key makes them undecryptable.
GF_USERS_ALLOW_SIGN_UP), anonymous access, and upstream analytics/update checks are disabled by the template and are not configurable.
Access
publicAccess.enabled— Serve the UI and API on the canonical*.cpln.appHTTPS endpoint (default). Everything behind the endpoint is gated by Grafana’s own login, and Grafana’sroot_urlis set to that endpoint automatically. Set tofalsefor an internal-only instance — external requests are then refused at the edge while in-GVC callers still reach it perinternalAccess.internalAccess.type— Internal firewall scope of the Grafana workload:
Firewall changes applied by an upgrade take up to about 30 seconds to propagate.
App Database
Enable exactly one ofpostgresHA (production, default) or postgres (dev/lightweight) — see Choosing a Database Mode. In both modes, change the database password before installing (postgresHA.postgres.password / postgres.config.password). Grafana is wired to the active database automatically: the HAProxy leader endpoint in HA mode, or the single instance directly in dev mode. In HA mode postgresHA.proxy.enabled must stay true — that HAProxy endpoint is Grafana’s stable database address, and disabling it is rejected at render.
High Availability
Grafana holds no local state, so scaling the app tier is a matter of raisingreplicas. Alert evaluation is the one thing that must be coordinated: without coordination every replica would evaluate the same rule and send its own notification.
- Coordination uses Grafana’s Redis-Sentinel alerting HA mode — the Sentinel workload deployed by the
redissubchart, not gossip-based peer clustering. Each replica registers itself under its own peer name, and exactly one notification is delivered per firing alert. - The chart refuses to render
replicas >= 2withoutredis.enabled: true. - Redis and Sentinel ship without authentication — the same-GVC internal firewall is the boundary. Enabling Redis or Sentinel auth is rejected at render in this version.
- Multi-replica behavior verified in testing: a full rolling restart and a killed replica both served every request without a single non-200 response, and a killed replica was replaced in about 98 seconds.
SMTP
Grafana sends alert notification emails through the SMTP server you configure. Leavesmtp.enabled: false if you use webhook, chat, or other contact points instead.
smtp.passwordSecretName is required whenever smtp.user is set. The password stays in the opaque secret — it never passes through Helm values — and the chart grants the Grafana identity reveal on exactly that secret.
Provisioning Datasources
You can add datasources in the UI at any time.datasources.definitions additionally lets you declare them as code: each entry is a standard Grafana datasource provisioning entry, rendered verbatim into a provisioning file that the workload mounts at startup.
Provisioned datasources are read-only in the Grafana UI. To change one, change the value and upgrade the release.
Datasource Credentials
Credentials for provisioned datasources never go into Helm values. Put them in a dictionary secret you create before installing, list the secret underdatasources.credentialSecrets, and reference each key as $KEY in the provisioning entry. Every listed key is exposed to the container as an environment variable, Grafana interpolates it when it loads the provisioning file, and the chart grants the workload reveal on exactly that secret.
1
Create the dictionary secret
Create a dictionary secret — for example
my-grafana-ds-credentials with the key PG_PASSWORD — before installing.2
List it under credentialSecrets
Add the secret name and the keys you want exposed to
datasources.credentialSecrets.3
Reference the key in the definition
Use
$PG_PASSWORD wherever the credential belongs in the provisioning entry.$PG_PASSWORD placeholder — the value stays in the secret.
Control Plane Metrics as a Datasource
Control Plane’s own metrics store is Prometheus-compatible and holds more than the console’s built-in dashboards display, including custom metrics your workloads expose, cost-relevant series such asegress, cross_zone_traffic, and volume_set_*, and cron and stability counters. Adding it as a datasource complements the built-in workload dashboards rather than replacing them — reach for it when you need custom application metrics, cost views, alerting you own and route yourself, or a single pane that mixes platform metrics with your other datasources.
Follow the centralized metrics management guide for the endpoint details, then wire the token in as a datasource credential:
1
Create a service account with readMetrics
Create a service account granted the
readMetrics permission on the org and generate a key for it.2
Store the key in a dictionary secret
Put the key in a dictionary secret — for example under the key
CPLN_METRICS_TOKEN — and list the secret under datasources.credentialSecrets.3
Add the datasource definition
Point a
prometheus-type datasource at https://metrics.cpln.io/metrics/org/YOUR_ORG and send the token as an Authorization header.Connecting
Health and readiness are served at
/api/health, which reports the Grafana version and the app-database status:
Backing Up
Database backups are optional and disabled by default. They cover the app database — the dashboards, users, alert rules, and saved datasources that make up your Grafana instance. Enable them withpostgresHA.backup.enabled or postgres.backup.enabled (matching your database mode), and complete the storage setup for your provider before installing. The values below are shown under backup.* — set them within the enabled database block.
- AWS S3
- Google Cloud Storage
- S3-compatible (MinIO, R2, Wasabi)
1
Create a bucket
Create an S3 bucket. Set
backup.aws.bucket and backup.aws.region to match.2
Set up a Cloud Account
If you do not have one, create a Cloud Account for your AWS account. Set
backup.aws.cloudAccountName to its name.3
Create a bucket-scoped IAM policy
Create an AWS IAM policy with the JSON below (replace
YOUR_BUCKET), then set backup.aws.policyName to the policy’s name:backup.mode selects logical (scheduled pg_dump via a cron workload) or wal-g (continuous WAL archiving). The single-instance mode takes scheduled logical dumps.
Important Notes
- Change
admin.password,admin.secretKey, and the database password before installing. The admin login applies on first boot only, andadmin.secretKeyis effectively write-once — rotating it makes every stored datasource credential undecryptable. - This template ships no dashboards and no datasources. It is the pane for data you own; Control Plane’s console already provides built-in workload-metrics dashboards, so there is no reason to recreate those here.
- Scaling requires Redis — set
replicas >= 2together withredis.enabled: true. The chart refuses to render multi-replica without it, because Sentinel-coordinated alerting is what keeps one firing alert from producing one notification per replica. - Dashboards, users, and alert rules live in the app database and survive Grafana restarts, redeployments, and replica replacement. Uninstall deletes the database volume sets — enable backups if the data matters.
- Prerequisite secrets you create are not owned by the release — datasource-credential and SMTP secrets survive
helm uninstalland must be deleted manually if you no longer need them. - With
publicAccess.enabled: false, Grafana’sroot_urlis not derived from a canonical endpoint, so absolute links in alert emails from an internal-only instance point at localhost. Keep public access on if you rely on links in email notifications. - Grafana Live push updates are per-instance in multi-replica mode; dashboard auto-refresh and alerting are unaffected.
- This template ships Grafana OSS only — Enterprise features such as fine-grained RBAC, reporting, and query caching are not available.
External References
Grafana Documentation
Official Grafana documentation
Provisioning Datasources
Reference for the datasource provisioning entries used by this template
Alerting High Availability
How Grafana coordinates alert evaluation across replicas
Configuration Reference
Every Grafana setting and its environment-variable name
Grafana HTTP API
Manage dashboards, datasources, and alert rules programmatically
Grafana Template
View the source files, default values, and chart definition