←Marketplace

LGTM Stack

Description

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.

Configuration Inputs

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.

domainstring

Public 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.

hubUrlstring

Base 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.

connectionNamestring

Name 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.

exposurestring

Dedicated 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.

exposeToTailnetboolean

Available 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.

tailnetDomainstring

Tailnet DNS suffix, for example example.ts.net, without a scheme or trailing dot. Must match the tailnet used by the Kubernetes operator.

tailnetHostnamePrefixstring

Unique 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.

tailnetProxyGroupstring

Existing 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.

tailnetProxyClassstring

Existing 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.

grafanaExposurestring

Applies 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.

hubOrgsmap

Maps 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"`.

ingressEnabledboolean

Create Ingress resources for Loki, Mimir and Grafana. Disabled when Stack Exposure is Private; Tailscale Ingresses are controlled separately.

routesEnabledboolean

Publish 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.

ingressClassNamestring

IngressClass that publishes the Loki, Mimir and Grafana hostnames. The default matches the internet-facing ingress-nginx installed by the platform blueprints.

clusterIssuerstring

cert-manager ClusterIssuer that signs the TLS certificates for the public hostnames. The default matches the issuer installed by the platform blueprints.

profilestring

Sizing profile for the Loki, Mimir and Grafana services. Small suits a hub with a handful of workload environments; medium is sized for production hubs.

nodeGroupstring

Value 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.

tolerationsstring

YAML 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.

storageClassNamestring

Storage 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.

lokiRetentionDaysnumber

Days the Loki compactor keeps log chunks before deleting them.

mimirBlockRetentionDaysnumber

Days the Mimir compactor keeps metric blocks before deleting them.

useExternalGrafanaDatabaseboolean

Point Grafana at a Postgres database you manage instead of provisioning a dedicated one with this installation.

grafanaDatabaseUrlstring

Postgres connection URL (`postgres://user:password@host:5432/grafana?sslmode=require`) for Grafana when using an external database.

grafanaAdminPasswordstring

Generated once for the built-in Grafana `admin` user and retained across upgrades.

datasourceSecretstring

Used 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`.

organizationDisplayNamestring

Applies 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.

deletionProtectionboolean

Protects the buckets and the Grafana database from accidental destruction. Disable before tearing down the stack.

Outputs

This blueprint exposes 11 outputs that other services can reference.

connectionNamestring

Name remote collectors use to address this stack.

lokiIngestUrlstring

Base URL remote collectors push logs to.

mimirIngestUrlstring

Base URL remote collectors push metrics to.

lokiUrlstring

Loki 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.

mimirUrlstring

Mimir 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.

lokiTailnetUrlstring

HTTPS tailnet endpoint for loki through the tenant auth-proxy. Existing API credentials are still required.

mimirTailnetUrlstring

HTTPS tailnet endpoint for mimir through the tenant auth-proxy. Existing API credentials are still required.

grafanaUrlstring

Canonical 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.

lokiBucketNamestring

Object storage bucket holding Loki chunks and ruler state.

mimirBucketNamestring

Object storage bucket holding Mimir blocks, ruler and alertmanager state.

grafanaAdminPasswordstring

Password for the built-in Grafana `admin` user.