Azure Metrics Integration :: Kloudfuse Docs

Azure Metrics Integration

Kloudfuse collects Azure Monitor metrics using the Cloud Exporter — a scraper that runs inside your cluster and periodically pulls metrics from the Azure Monitor Metrics API. No additional agents or Azure-side configuration are required beyond the initial Service Principal setup.

For an overview of how this fits into the broader Azure integration architecture, see Azure Integration Architecture.

Overview

The Cloud Exporter polls the Azure Monitor Metrics API on a fixed interval — every minute by default — and stores the retrieved metric time series directly in Kloudfuse. It supports multiple Azure subscriptions simultaneously, so a single Cloud Exporter deployment can collect metrics from all subscriptions in your organization.

Metric collection is opt-in by resource type. You list the Azure resource types you want in custom-values.yaml; Kloudfuse owns which metrics, aggregations, time grains, and dimension filters are collected for each type — you never specify individual metric names. An empty or absent list collects nothing.

Kloudfuse supports built-in Azure Monitor metrics across Compute (Virtual Machines and Scale Sets), Containers (AKS), Networking (Load Balancers and Application Gateways), Storage (Storage Accounts, blobs, and file shares), Databases (Azure Database for PostgreSQL), Cache (Redis), Messaging (Event Hubs and IoT Hub), Cognitive Services, and Azure Data Explorer (Kusto). For the full list of supported resource types and the metrics collected under each, see Supported Azure Metrics.

For a resource type that is not in the catalog yet, define your own scrape jobs inline with customResourceTypes (see Add a Resource Type That Isn’t Supported Yet) — collected in addition to the catalog picks, without waiting for a release.

Prerequisites

Step 1: Create a Service Principal

The Cloud Exporter authenticates to Azure using a Service Principal. Create one using the Azure CLI:

az ad sp create-for-rbac \
  --name kloudfuse-cloud-exporter \
  --role "Monitoring Reader" \
  --scopes /subscriptions/<subscription-id>

The output contains the values you need:

{
  "appId":       "<AZURE_CLIENT_ID>",
  "displayName": "kloudfuse-cloud-exporter",
  "password":    "<AZURE_CLIENT_SECRET>",
  "tenant":      "<AZURE_TENANT_ID>"
}

Save appId, password, and tenant — you will use them in the Helm configuration.

The --role "Monitoring Reader" flag grants read-only access to Azure Monitor metrics for the specified subscription.
It does not grant access to resource configurations or any control-plane operations.

Step 2: Assign Monitoring Reader to Additional Subscriptions

If you want to collect metrics from multiple subscriptions, assign the Monitoring Reader role for each one:

az role assignment create \
  --assignee <AZURE_CLIENT_ID> \
  --role "Monitoring Reader" \
  --scope /subscriptions/<additional-subscription-id>

Repeat for each subscription. The subscription IDs are listed in the subscriptions field in the Helm values (see Step 3: Configure Kloudfuse via Helm).

Step 3: Configure Kloudfuse via Helm

Enable the Cloud Exporter

In your custom-values.yaml, enable the cloud-exporter under the global section:

global:
  cloud-exporter:
    enabled: true

Option A: Inline Credentials

Add the Azure credentials and subscription list directly in custom-values.yaml:

kfuse-cloud-exporter:
  azure-metrics-exporter:
    enabled: true
    subscriptions:
      - <subscription-id-1>
      - <subscription-id-2>
    secrets:
      AZURE_CLIENT_ID: "<AZURE_CLIENT_ID>"
      AZURE_TENANT_ID: "<AZURE_TENANT_ID>"
      AZURE_CLIENT_SECRET: "<AZURE_CLIENT_SECRET>"
    resourceTypes:            # opt-in list; values from the supported catalog
      - Microsoft.ContainerService/managedClusters
      - Microsoft.Cache/Redis
    scrapeInterval: 1m        # optional, default 1m
Storing credentials in plain text in custom-values.yaml is convenient for initial setup but is not recommended for production.
Use Option B in production environments.

Option B: Kubernetes Secret (Recommended)

Create a Kubernetes secret in the Kloudfuse namespace (kfuse by default — replace if your installation uses a different namespace):

kubectl create secret generic azure-cloud-exporter-credentials \
  --namespace <kloudfuse-namespace> \
  --from-literal=AZURE_CLIENT_ID="<AZURE_CLIENT_ID>" \
  --from-literal=AZURE_TENANT_ID="<AZURE_TENANT_ID>" \
  --from-literal=AZURE_CLIENT_SECRET="<AZURE_CLIENT_SECRET>"

Reference the secret in custom-values.yaml:

kfuse-cloud-exporter:
  azure-metrics-exporter:
    enabled: true
    subscriptions:
      - <subscription-id-1>
      - <subscription-id-2>
    resourceTypes:                        # opt-in list; values from the supported catalog
      - Microsoft.ContainerService/managedClusters
      - Microsoft.Cache/Redis
    scrapeInterval: 1m                    # optional, default 1m
    extraEnv:
      - name: AZURE_CLIENT_ID
        valueFrom:
          secretKeyRef:
            name: azure-cloud-exporter-credentials
            key: AZURE_CLIENT_ID
      - name: AZURE_TENANT_ID
        valueFrom:
          secretKeyRef:
            name: azure-cloud-exporter-credentials
            key: AZURE_TENANT_ID
      - name: AZURE_CLIENT_SECRET
        valueFrom:
          secretKeyRef:
            name: azure-cloud-exporter-credentials
            key: AZURE_CLIENT_SECRET

Configuration Reference

The azure-metrics-exporter block accepts the following fields:

Field Required Meaning
enabled yes Turns Azure metric collection on.
subscriptions yes One or more Azure subscription IDs to scrape. Every job queries all listed subscriptions.
secrets.AZURE_CLIENT_ID yes Service Principal (app registration) client ID.
secrets.AZURE_TENANT_ID yes Azure Active Directory tenant ID.
secrets.AZURE_CLIENT_SECRET yes Service Principal client secret. The principal needs the Monitoring Reader role on the subscriptions.
resourceTypes yes Resource types to collect, using values from the supported catalog. An empty or absent list collects nothing.
customResourceTypes no Customer-authored jobs for resource types not in the catalog, collected in addition to resourceTypes. See Add a Resource Type That Isn’t Supported Yet.
scrapeInterval no How often every Azure job polls, as a Prometheus duration (30s, 1m, 5m). Default 1m.

Apply the Helm Upgrade

helm upgrade --install kfuse oci://us-east1-docker.pkg.dev/mvp-demo-301906/kfuse-helm/kfuse \
  -n kfuse \
  --version <VERSION> \ (1)
  -f custom-values.yaml

Select the Resource Types to Collect

The resourceTypes list is the opt-in set of Azure resource types Kloudfuse collects metrics for. Use the exact resource type strings from Supported Azure Metrics — for example Microsoft.Cache/Redis.

kfuse-cloud-exporter:
  azure-metrics-exporter:
    enabled: true
    subscriptions:
      - <subscription-id>
    resourceTypes:
      - Microsoft.ContainerService/managedClusters
      - Microsoft.Cache/Redis
      - Microsoft.DBforPostgreSQL/flexibleServers

How collection behaves:

Add a Resource Type That Isn’t Supported Yet

If a resource type is not in the catalog, define its collection jobs inline under customResourceTypes.

kfuse-cloud-exporter:
  azure-metrics-exporter:
    enabled: true
    subscriptions:
      - <subscription-id>
    resourceTypes:
      - Microsoft.ContainerService/managedClusters
    customResourceTypes:
      Microsoft.DocumentDB/databaseAccounts:
        - jobName: Microsoft.DocumentDB/databaseAccounts_requests
          metrics: [TotalRequests, MetadataRequests]
          interval: PT1M
          aggregation: [count]
        - jobName: Microsoft.DocumentDB/databaseAccounts_consumption
          metrics: [TotalRequestUnits, NormalizedRUConsumption]
          interval: PT1M
          aggregation: [average]
    scrapeInterval: 1m

Monitor Multiple Subscriptions

List every subscription you want to collect metrics from under subscriptions. The Cloud Exporter collects metrics from all listed subscriptions using the same Service Principal, provided it has the Monitoring Reader role assigned on each one.

kfuse-cloud-exporter:
  azure-metrics-exporter:
    enabled: true
    subscriptions:
      - xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx   # Production
      - yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy   # Staging
      - zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz  # Development
    resourceTypes:                             # applied to every listed subscription
      - Microsoft.ContainerService/managedClusters
      - Microsoft.Cache/Redis

Verify the Integration

Confirm the Cloud Exporter is Running

Check that the Cloud Exporter pod is healthy:

kubectl get pods -n <kloudfuse-namespace> -l app=azure-metrics-exporter

The pod status must be Running. If it is CrashLoopBackOff, check the logs:

kubectl logs -n <kloudfuse-namespace> -l app=azure-metrics-exporter --tail=100

Confirm Metrics are Arriving in Kloudfuse

  1. In the Kloudfuse UI, click the Metrics tab and select Explorer from the drop-down.
  2. In the metric search field, type azure_ to list all ingested Azure Monitor metrics.

Troubleshooting

Cloud Exporter Pod is in CrashLoopBackOff

kubectl logs -n <kloudfuse-namespace> -l app=azure-metrics-exporter --tail=50

Common causes:

Error message Resolution
ClientAuthenticationError or AADSTS70011 The Client Secret is incorrect or has expired. Regenerate it: az ad app credential reset --id <AZURE_CLIENT_ID> and update the Kubernetes secret or Helm values.
AuthorizationFailed The Service Principal lacks the Monitoring Reader role on the target subscription. Run the role assignment command in Step 2: Assign Monitoring Reader to Additional Subscriptions.
InvalidSubscriptionId A subscription ID in the subscriptions list is malformed. Verify each value with az account list --output table.
Secret key not found The Kubernetes secret name or key does not match the secretKeyRef in the Helm values. Run kubectl get secret azure-cloud-exporter-credentials -n <kloudfuse-namespace> -o yaml to verify.

No Azure Metrics Appear in Kloudfuse

  1. Confirm resourceTypes is non-empty. An empty or absent list collects nothing...
  2. Confirm the Cloud Exporter pod is Running...
  3. Wait at least one scrape interval (one minute by default) after the pod starts — the first scrape takes up to one interval to complete.
  4. Check the Cloud Exporter logs for scrape errors:
kubectl logs -n <kloudfuse-namespace> -l app=azure-metrics-exporter | grep -i error
  1. Confirm the subscription IDs in custom-values.yaml match the subscriptions returned by:
az account list --query "[].{Name:name,ID:id}" --output table

Metrics for a Listed Resource Type Never Appear

If one entry in resourceTypes produces no metrics while others work, the type is most likely not in the supported catalog and was silently skipped — there is no warning.

  1. Check the spelling and casing against Supported Azure Metrics. Entries must match exactly...
  2. If the type genuinely is not in the catalog, collect it with customResourceTypes (see Add a Resource Type That Isn’t Supported Yet).

Metrics from One Subscription are Missing

  1. Confirm the subscription ID is listed in the subscriptions field in custom-values.yaml.
  2. Confirm the Service Principal has the Monitoring Reader role on that subscription:
az role assignment list \
     --assignee <AZURE_CLIENT_ID> \
     --scope /subscriptions/<subscription-id> \
     --query "[].{Role:roleDefinitionName,Scope:scope}" \
     --output table
  1. If the role is missing, add it with az role assignment create as shown in Step 2: Assign Monitoring Reader to Additional Subscriptions.

TLS Verification Errors on AKS

If the Cloud Exporter cannot verify TLS certificates when connecting to Azure Monitor, it may be a corporate proxy or custom CA issue. Add the CA certificate to the pod’s trust store via the Helm values, or temporarily disable TLS verification for diagnosis only:

kfuse-cloud-exporter:
  azure-metrics-exporter:
    extraEnv:
      - name: AZURE_SDK_DISABLE_CERT_VERIFICATION
        value: "true"