Ryvn's observability stack (Loki, Grafana, Mimir behind the tenant auth-proxy) as one installation: object storage for Loki and Mimir, a Postgres database for Grafana unless you bring your own, the Loki and Mimir services sized by profile, the auth-proxy at loki.<domain> / mimir.<domain>, and Grafana at grafana.<domain>, with TLS from cert-manager. How the pieces fit together: https://ryvn.ai/docs/observability/logs and https://ryvn.ai/docs/observability/metrics.
provisioningMode selects who the stack serves. hub: every organization of the hub it is installed beside; sign-in through the environment's zitadel installation, organizations and datasources created by that hub's orchestrator, mapped with hubOrgs. dedicated: the single organization owning the installation; the managing hub issues the OAuth client and gateway identity, Grafana organization 1 is provisioned statically and named organizationDisplayName, and grafanaExposure chooses the public or internal ingress.
In dedicated mode, exposure: private disables public access and serves the stack through internal Routes. Optional exposeToTailnet, with tailnetDomain and tailnetHostnamePrefix, adds HTTPS access for humans. Grafana login uses its tailnet hostname; collector URLs, internal Routes and PrivateLink configuration are unchanged by the toggle. Tailscale Operator 1.84.0+ and tailnet HTTPS must already be configured. By default, one shared ingress ProxyGroup runs two replicas for the three endpoints; tailnetProxyGroup can reuse an existing ingress group.
Supported on GCP (GCS + Workload Identity Federation for GKE), AWS (S3 + EKS Pod Identity) and Azure (Blob + Workload Identity). On other providers the buckets and the Grafana database are still created, but Loki, Mimir, the auth-proxy and Grafana are not deployed and the URL outputs are not published. Collectors are deployed separately and reach the stack through the connectionName, lokiIngestUrl and mimirIngestUrl outputs.
This blueprint accepts 28 configurable inputs to customize the installation for your environment.
provisioningModestring`hub`: this stack serves every organization of the hub it is installed beside; sign-in uses the environment's `zitadel` installation and `hubOrgs`; Grafana organizations and datasources are provisioned by that hub's orchestrator. `dedicated`: this stack serves the single organization that owns the installation; the managing hub issues the OAuth client and gateway identity and Grafana is provisioned statically.
domainstringPublic root hostname for the stack, without a scheme. Public endpoints use `loki.`, `mimir.` and `grafana.` under it. Private stacks use the environment internal domain automatically; this input can retain its existing value.
hubUrlstringBase URL of the Ryvn hub API (for example `https://api.<hub-domain>`) the auth-proxy authorizes tenant requests against. Required in `hub` mode, where it is the API of the hub this stack is installed beside. In `dedicated` mode leave it blank to use the managing hub's API; set it only to authorize against a different hub API URL.
connectionNamestringName remote collectors use to address this stack, in either provisioning mode. Leave blank to use `<installation name>-<hosting environment name>`. Must be a valid label value: at most 63 characters of letters, digits, `-`, `_` or `.`, starting and ending with a letter or digit. A generated default that is too long is rejected rather than shortened; set the name explicitly in that case.
exposurestringDedicated stacks only. Public keeps the existing Ingress/Route options. Private disables legacy Ingresses and serves all three services through internal Routes on the environment internal domain. Connected Private Service Consumers resolve these names through their private links. Tailscale does not change collector endpoints.
exposeToTailnetbooleanAvailable only when Stack Exposure is Private. Add Tailscale HTTPS access to Grafana and the authenticated Loki/Mimir gateways for human access. Does not alter internal Routes, collector endpoints or PrivateLink configuration. Grafana login uses its tailnet URL. Requires Tailscale Operator 1.84.0+ with current CRDs and Services write permission, tailnet HTTPS, service advertisement approval (autoApprovers.services), and client access rules. Creates an ingress ProxyGroup with two replicas by default, or reuses the existing ingress group named by tailnetProxyGroup. Use at least two eligible nodes for node-failure resilience. Collectors use the environment's internal gateway and must have network and DNS access to it.
tailnetDomainstringTailnet DNS suffix, for example example.ts.net, without a scheme or trailing dot. Must match the tailnet used by the Kubernetes operator.
tailnetHostnamePrefixstringUnique prefix for the three Tailscale Services and any blueprint-created ProxyGroup, for example hs-lgtm-cp. Creates <prefix>-grafana, <prefix>-loki and <prefix>-mimir. Use at most 53 lowercase letters, digits or hyphens, starting and ending with a letter or digit; these service names must be unused on the tailnet.
tailnetProxyGroupstringExisting ProxyGroup in this cluster with type ingress, managed outside this installation. Leave blank to create a dedicated group with two replicas. When set, LGTM creates only Ingresses and uses the group's existing class, replicas, tags and scheduling. Kubernetes API and egress groups cannot be reused for ingress.
tailnetProxyClassstringExisting ProxyClass to use when creating a group. Ignored when tailnetProxyGroup is set. Set this if your operator relies on custom scheduling or security settings; those settings are not inherited by the generated class. Leave blank to create a class that prefers separate nodes. An existing class should configure replica spreading.
grafanaExposurestringApplies to `dedicated` mode only; in `hub` mode Grafana is always published at `grafana.<domain>` because the `zitadel` installation registers that callback. Ignored when Stack Exposure is Private. Public publishes Grafana at `grafana.<domain>` on the ingress class below. Private publishes it on the `internal-nginx` ingress class under the environment's internal domain, reachable only from inside the network; hub sign-in stays enabled either way.
hubOrgsmapMaps hub (Zitadel) organization ids to Grafana organization ids. Members of a hub organization sign in to Grafana as Editors of the mapped Grafana organization. The Grafana organizations and their Loki/Mimir datasources are created by the hub's orchestrator; look up the ids under Server admin → Organizations. Synthetic example: `"111111111111111111": "2"`.
ingressEnabledbooleanCreate Ingress resources for Loki, Mimir and Grafana. Disabled when Stack Exposure is Private; Tailscale Ingresses are controlled separately.
routesEnabledbooleanPublish Loki, Mimir and Grafana through Ryvn Routes (ryvn-routes) on the managed gateway. When Stack Exposure is Private, internal Routes are always created and public Routes are disabled, independently of Tailscale.
ingressClassNamestringIngressClass that publishes the Loki, Mimir and Grafana hostnames. The default matches the internet-facing ingress-nginx installed by the platform blueprints.
clusterIssuerstringcert-manager ClusterIssuer that signs the TLS certificates for the public hostnames. The default matches the issuer installed by the platform blueprints.
profilestringSizing profile for the Loki, Mimir and Grafana services. Small suits a hub with a handful of workload environments; medium is sized for production hubs.
nodeGroupstringValue of the `ryvn.app/node-group-name` label for LGTM pods, including caches and the managed Grafana database helper (for example `observability`). Leave blank to omit this node selector. Tailscale proxy placement is configured separately through its ProxyClass.
tolerationsstringYAML list of Kubernetes tolerations for LGTM pods and the managed Grafana database helper. Use with Node Group to schedule on a tainted pool. Leave blank to retain chart defaults. Tailscale proxies use their ProxyClass instead.
storageClassNamestringStorage class for the Loki and Mimir persistent volumes (ingester write-ahead logs, compactor and store-gateway scratch, alertmanager state; durable data lives in the buckets). Grafana recommends SSD-backed disks for ingesters. Empty uses the cluster default. Changing it later recreates those volumes.
lokiRetentionDaysnumberDays the Loki compactor keeps log chunks before deleting them.
mimirBlockRetentionDaysnumberDays the Mimir compactor keeps metric blocks before deleting them.
useExternalGrafanaDatabasebooleanPoint Grafana at a Postgres database you manage instead of provisioning a dedicated one with this installation.
grafanaDatabaseUrlstringPostgres connection URL (`postgres://user:password@host:5432/grafana?sslmode=require`) for Grafana when using an external database.
grafanaAdminPasswordstringGenerated once for the built-in Grafana `admin` user and retained across upgrades.
datasourceSecretstringUsed in `dedicated` mode only. Generated once; Grafana's Loki and Mimir datasources present it to the auth-proxy as the Basic auth password of user `grafana`.
organizationDisplayNamestringApplies to `dedicated` mode only. Name shown for Grafana organization 1, applied after every install and upgrade. Leave blank to use the id of the organization that owns this installation.
deletionProtectionbooleanProtects the buckets and the Grafana database from accidental destruction. Disable before tearing down the stack.
This blueprint exposes 11 outputs that other services can reference.
connectionNamestringName remote collectors use to address this stack.
lokiIngestUrlstringBase URL remote collectors push logs to.
mimirIngestUrlstringBase URL remote collectors push metrics to.
lokiUrlstringLoki endpoint behind the auth-proxy. Tailscale does not change this URL. Set it as the platform blueprint's `lokiUrl` input in each workload environment whose collector should ship here.
mimirUrlstringMimir endpoint behind the auth-proxy. Tailscale does not change this URL. Set it as the platform blueprint's `mimirUrl` input in each workload environment whose collector should ship here.
lokiTailnetUrlstringHTTPS tailnet endpoint for loki through the tenant auth-proxy. Existing API credentials are still required.
mimirTailnetUrlstringHTTPS tailnet endpoint for mimir through the tenant auth-proxy. Existing API credentials are still required.
grafanaUrlstringCanonical Grafana URL on the tailnet when exposeToTailnet is enabled, otherwise on the public domain, or on the environment's internal domain when a dedicated stack's Grafana exposure is private. In hub mode it must match the `grafanaUrl` input of the zitadel installation so the OAuth redirect is accepted.
lokiBucketNamestringObject storage bucket holding Loki chunks and ruler state.
mimirBucketNamestringObject storage bucket holding Mimir blocks, ruler and alertmanager state.
grafanaAdminPasswordstringPassword for the built-in Grafana `admin` user.