This is documentation for the next version of Grafana Mimir documentation. For the latest stable release, go to the latest version.
Configure Grafana Mimir object storage backend
Grafana Mimir can use different object storage services to persist blocks containing the metrics data, as well as recording rules and Alertmanager state.
Mimir doesn’t create the configured storage bucket, you must create it yourself. The supported backends are:
- Amazon S3 (and compatible implementations like MinIO)
- Google Cloud Storage
- Azure Blob Storage
- Swift (OpenStack Object Storage)
Note
Like Amazon S3, the chosen object storage implementation must not create directories. Grafana Mimir doesn’t have any notion of object storage directories, and so will leave empty directories behind when removing blocks. For example, if you use Azure Blob Storage, you must disable hierarchical namespace.
To configure the storage retention on a per-tenant basis, set overrides in the runtime configuration:
Ruler and alertmanager support a
local implementation,
which is similar to filesystem in the way that it uses the local file system,
but it is a read-only data source and can be used to provision state into those components.
Common configuration
To avoid repetition, you can use the common configuration and fill the common configuration block or by providing the -common.storage.* CLI flags.
To use environment variables in the configuration file, ensure that you enable expansion for the variables.
Note
Blocks storage can’t be located in the same path of the same bucket as the ruler and Alertmanager stores.
When using the common configuration, make
blocks_storageuse either a:
- different bucket, overriding the common bucket name
- storage prefix
Grafana Mimir will fail to start if you configure blocks storage to use the same bucket and storage prefix that the Alertmanager or ruler store uses.
Find examples of setting up the different object stores below:
Note
If you’re using a mixture of YAML files and CLI flags, pay attention to their precedence logic.
S3
common:
storage:
backend: s3
s3:
endpoint: s3.us-east-2.amazonaws.com
region: us-east-2
access_key_id: "${AWS_ACCESS_KEY_ID}" # This is a secret injected via an environment variable
secret_access_key: "${AWS_SECRET_ACCESS_KEY}" # This is a secret injected via an environment variable
blocks_storage:
s3:
bucket_name: mimir-blocks
alertmanager_storage:
s3:
bucket_name: mimir-alertmanager
ruler_storage:
s3:
bucket_name: mimir-rulerNote
Don’t prefix the endpoint value with your bucket name. For example, if your bucket is named “my-storage-bucket”, you cannot name the endpoint “my-storage-bucket.s3.amazonaws.com”.
GCS
common:
storage:
backend: gcs
gcs:
# This is an example to illustrate what the service account content should look like.
# We recommend injecting the service_account via an environment variable instead.
service_account: |
{
"type": "service_account",
"project_id": "my-project",
"private_key_id": "1234abc",
"private_key": "-----BEGIN PRIVATE KEY-----\n\n-----END PRIVATE KEY-----\n",
"client_email": "test@my-project.iam.gserviceaccount.com",
"client_id": "5678",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/test%40my-project.iam.gserviceaccount.com"
}
blocks_storage:
gcs:
bucket_name: mimir-blocks
alertmanager_storage:
gcs:
bucket_name: mimir-alertmanager
ruler_storage:
gcs:
bucket_name: mimir-rulerAzure Blob Storage
You must disable hierarchical namespace, otherwise Grafana Mimir will leave empty directories behind when deleting blocks.
common:
storage:
backend: azure
azure:
account_key: "${AZURE_ACCOUNT_KEY}" # This is a secret injected via an environment variable
account_name: mimirprod
endpoint_suffix: "blob.core.windows.net"
blocks_storage:
azure:
container_name: mimir-blocks
alertmanager_storage:
azure:
container_name: mimir-alertmanager
ruler_storage:
azure:
container_name: mimir-rulerAzure Workload Identity
When account_key and connection_string are unset, Mimir authenticates
to Azure Blob Storage with Azure AD / managed identity (including Azure
Workload Identity on Kubernetes).
You still need a storage account that trusts the identity (RBAC role such as Storage Blob Data Contributor on the account or containers).
Mimir configuration (no account key)
common:
storage:
backend: azure
azure:
account_name: mimirprod
endpoint_suffix: blob.core.windows.net
# account_key: leave unset to use managed / workload identity
# user_assigned_id: "<client-id-of-user-assigned-identity>" # optional
blocks_storage:
azure:
container_name: mimir-blocks
alertmanager_storage:
azure:
container_name: mimir-alertmanager
ruler_storage:
azure:
container_name: mimir-rulerKubernetes: Azure Workload Identity
On AKS (or any cluster with the Workload Identity webhook), bind a Kubernetes service account to a user-assigned managed identity. Typical steps:
- Create a user-assigned managed identity and grant it blob data access on the storage account.
- Create a federated identity credential from that identity to your cluster’s OIDC issuer and the Mimir pods’ service account (
system:serviceaccount:<namespace>:<sa-name>). - Label pods and annotate the service account so the webhook injects the token:
# Helm values sketch — field paths depend on the chart
serviceAccount:
create: true
name: mimir-storage
annotations:
azure.workload.identity/client-id: "${USER_ASSIGNED_IDENTITY_CLIENT_ID}"
labels:
azure.workload.identity/use: "true"
# Ensure Mimir pods get the label (chart-specific; e.g. global.podLabels)
global:
podLabels:
azure.workload.identity/use: "true"Set user_assigned_id in the Mimir Azure storage config to the same client ID,
or rely on the environment injected by the webhook when using a single
user-assigned identity.
Note
Unlike with Tempo, federated tokens are not supported with Mimir beyond this managed / workload identity path. Do not set
account_keyif you want identity-based authentication.
OpenStack SWIFT
common:
storage:
backend: swift
swift:
auth_url: http://10.121.xx.xx:5000/v3
username: mimir
user_domain_name: Default
password: "${OPENSTACK_API_KEY}" # This is a secret injected via an environment variable
project_name: mimir-prod
domain_name: Default
blocks_storage:
swift:
container_name: mimir-blocks
alertmanager_storage:
swift:
container_name: mimir-alertmanager
ruler_storage:
swift:
container_name: mimir-ruler
