OpenCost Deployment for Microsoft Azure
This guide explains how to deploy OpenCost for an AKS cluster.
Prerequisites
Before starting the deployment, ensure you have the following:
Infrastructure & permissions:
AKS cluster
Administrator access to the cluster
Cloud permissions:
Contributorrole at the subscription or resource group levelUser Access Administratorrole (required to manage service principals)
Tools:
azCLI toolkubectlCLI toolhelmCLI tool (v3.x or later)
Step 1. Configure Service Principal
Create a service principal
In the Azure Portal, navigate to Microsoft Entra ID.
Under Manage, select App registrations. Click +New registration.
Set the following:
Name:
opencost-spSupported account types: Single tenant
After creating the application, note:
Application (client) ID
Directory (tenant) ID
Create a client secret
Open the newly created application.
Under Manage, select Certificates & secrets. Click +New client secret.
Set a description and select an expiry period.
Copy and save the generated secret value. This value cannot be retrieved later.
Assign permissions
Navigate to the subscription that contains the AKS cluster.
Navigate to Access control (IAM).
Click +Add -> Add role assignment.
Assign the following roles to the service principal:
Reader(required for cost metrics)Storage Blob Data Contributor(required for Parquet exports)
Step 2. Set up Storage Account
In the Azure Portal, navigate to Storage accounts.
Click Create and configure the following:
Name:
exampleopencostPerformance: Standard
Redundancy: any
Open the newly created storage account.
Navigate to Access Control (IAM) and assign Storage Blob Data Reader role to the service principal created for Cloudaware access:
Assign access to: User, group, or service principal
Members: click +Select members → select the Cloudaware application, e.g.
cloudaware-api-access(see Azure Start Guide)
Navigate to Containers and create a new container with the following settings:
Name:
opencost-exportsPublic access level: Private
Step 3. Connect to AKS Cluster
Go to Kubernetes services.
Select the created cluster.
Click Connect. Copy credentials
Run the
az aks get-credentialscommand.
Step 4. Deploy Prometheus
Add the Prometheus Helm repository:
CODEhelm repo add prometheus-community https://prometheus-community.github.io/helm-chartsCreate the Prometheus namespace:
CODEkubectl create namespace prometheus-systemInstall Prometheus:
CODEhelm install prometheus prometheus-community/prometheus \ --namespace prometheus-system \ --set prometheus-pushgateway.enabled=false \ --set alertmanager.enabled=false
Step 5. Deploy OpenCost
Add the OpenCost Helm repository:
CODEhelm repo add opencost https://opencost.github.io/opencost-helm-chartCreate the OpenCost namespace:
CODEkubectl create namespace opencostCreate a Kubernetes secret for the service principal credentials. Replace
<YOUR_CLIENT_SECRET>with the value created in Step 1:CODEkubectl create secret generic azure-secret \ --from-literal=password=<YOUR_CLIENT_SECRET> \ --namespace opencostInstall OpenCost:
CODEhelm --namespace opencost upgrade --install opencost opencost/opencost -f - <<EOF serviceAccount: create: true name: opencost-sa opencost: prometheus: namespaceName: prometheus-system podAnnotations: prometheus.io/path: /metrics prometheus.io/port: "9003" prometheus.io/scrape: "true" EOF
The podAnnotations ensure that Prometheus scrapes metrics from the OpenCost pods, enabling label-based cost attribution in reports.
Step 6. Deploy Parquet Exporter
Install the OpenCost Parquet Exporter.
To store reports in subfolders or use a naming prefix, use the command below, replacing
<YOUR_CLUSTER_PREFIX>,<YOUR_AKS_CLUSTER_ID>*,<YOUR_OPENCOST_STORAGE>,<YOUR_TENANT_ID>, and<YOUR_CLIENT_ID>with the appropriate values.CODEhelm install parquet-exporter opencost/opencost-parquet-exporter \ --namespace opencost \ --set schedule="0 */12 * * *" \ --set existingServiceAccount=opencost-sa \ --values - <<EOF resources: limits: cpu: "1" memory: 1Gi requests: cpu: 100m memory: 100Mi env: - name: OPENCOST_PARQUET_SVC_HOSTNAME value: "opencost.opencost.svc.cluster.local" - name: OPENCOST_PARQUET_STORAGE_BACKEND value: "azure" - name: OPENCOST_PARQUET_FILE_KEY_PREFIX value: "<YOUR_CLUSTER_PREFIX>"/"<YOUR_AKS_CLUSTER_ID>"/ - name: OPENCOST_PARQUET_JSON_SEPARATOR value: "_" - name: OPENCOST_PARQUET_AZURE_STORAGE_ACCOUNT_NAME value: "<YOUR_OPENCOST_STORAGE>" - name: OPENCOST_PARQUET_AZURE_CONTAINER_NAME value: "opencost" - name: OPENCOST_PARQUET_AZURE_TENANT value: "<YOUR_TENANT_ID>" - name: OPENCOST_PARQUET_AZURE_APPLICATION_ID value: "<YOUR_CLIENT_ID>" - name: OPENCOST_PARQUET_AZURE_APPLICATION_SECRET valueFrom: secretKeyRef: name: azure-secret key: password EOF
*Use the AKS cluster ID without the leading forward slash (/) in the command. Example:
- name: OPENCOST_PARQUET_FILE_KEY_PREFIX
- value: prodk8s/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/opencost/providers/Microsoft.ContainerService/managedClusters/opencost-aks/
To store reports in the root folder, use the command below, replacing
<YOUR_AKS_CLUSTER_ID>*,<YOUR_OPENCOST_STORAGE>,<YOUR_TENANT_ID>, and<YOUR_CLIENT_ID>with the appropriate values.CODEhelm install parquet-exporter opencost/opencost-parquet-exporter \ --namespace opencost \ --set schedule="0 */12 * * *" \ --set existingServiceAccount=opencost-sa \ --values - <<EOF resources: limits: cpu: "1" memory: 1Gi requests: cpu: 100m memory: 100Mi env: - name: OPENCOST_PARQUET_SVC_HOSTNAME value: "opencost.opencost.svc.cluster.local" - name: OPENCOST_PARQUET_STORAGE_BACKEND value: "azure" - name: OPENCOST_PARQUET_FILE_KEY_PREFIX value: "<YOUR_AKS_CLUSTER_ID>"/ - name: OPENCOST_PARQUET_JSON_SEPARATOR value: "_" - name: OPENCOST_PARQUET_AZURE_STORAGE_ACCOUNT_NAME value: "<YOUR_OPENCOST_STORAGE>" - name: OPENCOST_PARQUET_AZURE_CONTAINER_NAME value: "opencost" - name: OPENCOST_PARQUET_AZURE_TENANT value: "<YOUR_TENANT_ID>" - name: OPENCOST_PARQUET_AZURE_APPLICATION_ID value: "<YOUR_CLIENT_ID>" - name: OPENCOST_PARQUET_AZURE_APPLICATION_SECRET valueFrom: secretKeyRef: name: azure-secret key: password EOF
*Use the AKS cluster ID without the leading forward slash (/) in the command. Example:
- name: OPENCOST_PARQUET_FILE_KEY_PREFIX
- value: subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/opencost/providers/Microsoft.ContainerService/managedClusters/opencost-aks/
For multi-cluster environments, deploy the Parquet Explorer separately on each cluster.
Step 7. Verify Deployment
Check that all pods are running:
CODEkubectl get pods -n prometheus kubectl get pods -n opencostAccess the OpenCost UI:
CODEkubectl port-forward -n opencost service/opencost 9090:9090Open
http://localhost:9090in your browser.
The first Parquet export may take up to 24 hours. To verify the export, check your Azure Storage container for newly created files.
Next Steps
Return to the parent guide to proceed with the Kubernetes Billing setup in Cloudaware.