Overview
Thanos turns many independent Prometheus servers into one queryable metrics system. This template deploys Thanos Query — a stateless global PromQL layer that fans each query out over the gRPC Store API endpoints you list (typically the Thanos sidecar of each Prometheus template install, across GVCs and regions) and deduplicates HA pairs — plus an optional object-storage tier (Store Gateway + Compactor) that serves and manages long-term metric history from your bucket.This is a self-hosted query layer for your own metrics from your own Prometheus servers. It is separate from — and not a replacement for — Control Plane’s built-in observability, which continues to collect and dashboard your workloads’ metrics natively.
Architecture
- Thanos Query — A stateless standard workload. UI and PromQL API on port
10902, gRPC Store API on10901. Single replica by default — setreplicas: 2or more for an HA query tier; queries keep succeeding through rolling restarts and replica loss. - Store Gateway (optional, default off) — A stateful workload that serves historical blocks from your object bucket to Query, with a local index/meta cache volume (safe to lose — it rebuilds on start). Query picks it up automatically when enabled.
- Compactor (optional, default off) — A stateful singleton that compacts, downsamples, and applies retention to the blocks in your bucket.
- Object storage (optional) — The bucket your Prometheus Thanos sidecars upload blocks to; the Store Gateway and Compactor share one rendered
objstore.ymlconfiguration for it.
What Gets Created
- Standard Thanos Query Workload — Serves the UI and PromQL API on port
10902and its own Store API on10901. - Stateful Store Gateway Workload (optional) — Serves historical bucket blocks to Query.
- Stateful Compactor Workload (optional) — Compacts, downsamples, and applies retention to bucket blocks.
- Volume Sets (optional) — A 10 GiB cache volume for the Store Gateway and a 20 GiB workspace volume for the Compactor.
- Secret (optional) — An opaque secret holding the rendered
objstore.ymlbucket configuration, mounted as a file; created only when the storage tier is enabled. - Identity & Policy — A shared identity bound to all workloads; when the storage tier is enabled, a policy grants it
revealon the objstore secret, and cloud access is scoped to exactly your bucket (AWS and GCP backends).
This template does not create a GVC. You must deploy it into an existing GVC.
Prerequisites
None for a default install — Query boots with an empty store list and you point it at your store endpoints viastores.
The optional storage tier (storeGateway / compactor) requires an existing bucket in one of the supported backends — the same bucket your Prometheus template’s Thanos sidecar uploads blocks to. Complete the steps for your chosen backend below.
- AWS S3
- Google Cloud Storage
- S3-compatible (MinIO, R2, Wasabi)
AWS S3 uses a Control Plane cloud identity — no credentials are stored; the workload’s identity vends temporary credentials at runtime.
1
Create a bucket
Create an S3 bucket. Set
storage.aws.bucket and storage.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
storage.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 storage.aws.policyName to the policy’s name (bare name, not ARN):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
Configuration
The defaultvalues.yaml for this template:
Query
image— The Thanos container image, shared by all components.resources— CPU and memory for the Query container (the Store Gateway and Compactor have their ownresourcesblocks under their keys).replicas— Query is stateless, so replicas need no coordination. Set2or more for an HA query tier that serves queries without interruption through rolling restarts and replica loss.
Store Endpoints
Eachstores entry is a gRPC Store API endpoint — typically the Thanos sidecar of a Prometheus template install — as host:port with no scheme:
Two things to know for cross-GVC endpoints, both on the Prometheus side:
- The target workload’s internal firewall must allow inbound from this Query workload — set its
internalAccess.typetosame-org, orworkload-listincluding//gvc/GVC/workload/RELEASE-thanos. A store showing as “down” in the Query UI is almost always this firewall. - Cross-location internal traffic (Query in one region querying sidecars in another) incurs egress charges — co-locate the query tier with its stores where practical.
queryReplicaLabels names the external label(s) that mark HA duplicates: series identical except for this label are collapsed into one at query time. The default replica matches the Prometheus template’s HA pair recipe — the label name must exactly match what your HA pair sets.
Changing stores takes effect via helm upgrade — endpoints are workload arguments, so an upgrade safely redeploys Query with the new list, and Query keeps answering queries even while some listed endpoints are down.
Access
publicAccess.enabled— Exposes the Query UI and PromQL API at a*.cpln.appcanonical endpoint. Query has no built-in authentication, so anyone with the URL can run queries against everything it federates — keep this off (the default) or front Query with your own authenticating proxy.internalAccess.type— Controls which workloads can reach Query internally:
workloads entries take the form //gvc/GVC_NAME/workload/WORKLOAD_NAME.
Long-Term Storage Tier
Off by default, the storage tier serves metric history from the object bucket your Prometheus sidecars upload blocks to — configure the same bucket understorage:
storeGateway.enabled— Runs the Store Gateway, which serves historical bucket blocks to Query. Query picks up its endpoint automatically — nostoresentry needed. Its volume is only a local index/meta cache and is safe to lose.compactor.enabled— Runs the Compactor, which compacts and downsamples bucket blocks and appliescompactor.retentionper resolution (raw,fiveMinutes,oneHour;"0d"keeps forever).
storeGateway.enabled: true here to serve them.
Object Storage
Setstorage.type to aws, gcp, or minio, and configure that block. AWS and GCP use a Control Plane cloud identity — no credentials are stored. See Prerequisites for the per-backend setup steps.
Connecting
Point your Grafana at Query instead of individual Prometheus servers to get one deduplicated global view. The Query UI’s Stores page shows every configured endpoint with its health and labels — the first place to look when a source is missing from results.
Important Notes
- Query has no built-in authentication — with
publicAccess.enabled: true, anyone with the URL can run queries. Keep it off, or front Query with your own authenticating proxy. - Run exactly one Compactor per bucket, across all installs and regions — a second one corrupts the block layout and requires manual repair.
- Cross-GVC stores need a firewall change on the Prometheus side — the sidecar workload must allow inbound
same-orgor list this Query workload (see Store Endpoints). - No deduplication happening?
queryReplicaLabelsmust exactly match the external label name your HA Prometheus pair sets (replicaby default). - Long-term reads need both halves on the same bucket — a sidecar uploading blocks to it, and
storeGateway.enabled: truehere to serve them. - Disabling the storage tier does not remove existing cloud grants from the identity — the platform deep-merges updates, so a previously-applied AWS/GCP binding stays until you remove it (edit the identity, or uninstall and reinstall the release).
External References
Thanos Documentation
Official Thanos documentation
Query Component
Global query layer, fan-out, and deduplication reference
Store Gateway Component
Serving historical bucket blocks to the query layer
Compactor Component
Compaction, downsampling, and retention reference
Thanos (GitHub)
Source code and releases
Thanos Template
View the source files, default values, and chart definition