Skip to main content

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. The replicas knob 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 replicas is 2 or more.
  • Hardened defaults — User signup, anonymous access, and upstream telemetry are all disabled. When public access is on, Grafana’s root_url is derived automatically from the canonical endpoint.

What Gets Created

  • Standard Grafana Workloadreplicas stateless instances serving the UI and API on port 3000.
  • 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.enabled is 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.definitions is set — an opaque secret holding the rendered datasource provisioning file.
  • Identity & Policy — A least-privilege policy granting the Grafana identity reveal on 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:
Change admin.password, admin.secretKey, and the database password before installing — all three ship with change-me placeholder defaults. admin.user and admin.password are applied on first boot only, and admin.secretKey is effectively write-once: it encrypts every datasource credential stored in the database, so rotating it later makes those credentials undecryptable.
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 default values.yaml for this template:

Grafana Instance

  • image — The Grafana OSS container image.
  • replicas — Number of Grafana instances. 1 is a single instance; 2 or more forms an HA tier over the shared app database and requires redis.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 default admin/admin login 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.
Signup (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.app HTTPS endpoint (default). Everything behind the endpoint is gated by Grafana’s own login, and Grafana’s root_url is set to that endpoint automatically. Set to false for an internal-only instance — external requests are then refused at the edge while in-GVC callers still reach it per internalAccess.
  • 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 of postgresHA (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 raising replicas. 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 redis subchart, 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 >= 2 without redis.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. Leave smtp.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.
For catalog services running in the same GVC, use their internal endpoints:

Datasource Credentials

Credentials for provisioned datasources never go into Helm values. Put them in a dictionary secret you create before installing, list the secret under datasources.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_PASSWORDbefore 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.
The provisioning file itself only ever contains the literal $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 as egress, 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.
A workload’s built-in CPLN_TOKEN does not authenticate against the metrics endpoint. Use a service-account key with the readMetrics permission.

Connecting

Health and readiness are served at /api/health, which reports the Grafana version and the app-database status:
The Grafana HTTP API is available on the same endpoint for scripted dashboard, datasource, and alert-rule management.

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 with postgresHA.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.
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:
In HA mode, 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, and admin.secretKey is 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 >= 2 together with redis.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 uninstall and must be deleted manually if you no longer need them.
  • With publicAccess.enabled: false, Grafana’s root_url is 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