Azure Accounts
Connect an Azure subscription to CostLens with a dedicated App Registration granted Cost Management Reader — least privilege, no agents.
CostLens reads your Azure cost data and resource configuration through a dedicated App Registration (service principal) granted the read-only Cost Management Reader role. Setup takes about 5 minutes, requires no agents, and never modifies your resources during scanning.
Multi-cloud from one workspace
Azure subscriptions sit alongside your AWS and GCP accounts in the same CostLens organization. Spend, recommendations, and fixes are filterable per cloud and rolled up across all of them.
How it works
| Step | What happens |
|---|---|
| 1. You create an App Registration | A dedicated Entra ID app + service principal that CostLens authenticates as. |
| 2. You grant Cost Management Reader | Read-only access to cost data at the subscription (or management-group) scope. |
| 3. CostLens scans automatically | Billing data syncs every 6 hours via the Azure Cost Management Query API; optimisation checks and AI explanations run every 12 hours. |
What you'll paste into CostLens
CostLens stores only non-secret identifiers plus one encrypted secret bundle:
| Field | Where it comes from |
|---|---|
| Tenant ID | Your Entra ID directory ID |
| Client ID | The App Registration's Application (client) ID |
| Client secret | The secret you generate for the app (encrypted at rest with AES-256) |
| Subscription ID(s) | The subscription(s) you want CostLens to analyse |
Step-by-step — Azure CLI (recommended)
The Add Account → Azure dialog generates this script with your IDs pre-filled and offers a one-click copy/download. Run it in Azure Cloud Shell or any terminal with the az CLI signed in as a user who can create app registrations and assign roles.
#!/usr/bin/env bash
# CostLens — Azure connection setup (Cost Management Reader, least privilege)
set -euo pipefail
SUBSCRIPTION_ID="<SUBSCRIPTION_ID>"
APP_NAME="costlens-cost-reader"
az account set --subscription "$SUBSCRIPTION_ID"
# 1. Create an app registration + service principal
APP_ID=$(az ad app create --display-name "$APP_NAME" --query appId -o tsv)
az ad sp create --id "$APP_ID" >/dev/null
# 2. Create a client secret (valid 12 months) — copy the printed value
CLIENT_SECRET=$(az ad app credential reset --id "$APP_ID" --years 1 --query password -o tsv)
# 3. Grant Cost Management Reader (read-only cost data) at the subscription scope
az role assignment create \
--assignee "$APP_ID" \
--role "Cost Management Reader" \
--scope "/subscriptions/$SUBSCRIPTION_ID"
TENANT_ID=$(az account show --query tenantId -o tsv)
echo ""
echo "Paste these into CostLens:"
echo " Tenant ID: $TENANT_ID"
echo " Client ID: $APP_ID"
echo " Client secret: $CLIENT_SECRET"
echo " Subscription ID: $SUBSCRIPTION_ID"Paste the four printed values into the CostLens connect dialog and click Save. CostLens validates the credentials and starts the first sync.
Broader scope
To cover many subscriptions at once, assign the role at a management group scope instead of a single subscription:
--scope "/providers/Microsoft.Management/managementGroups/<MG_ID>". Enter the management group ID in the connect dialog and the generated script updates automatically.
Recommendations & Advisor
Azure recommendations come from two places, both read-only:
- Azure Advisor cost recommendations (right-sizing, shutdown, reservations) — the authoritative source, surfaced by the Azure Advisor (Cost) check.
- CostLens resource checks over the Azure Resource Manager + Monitor APIs — idle VMs, unattached disks, orphaned snapshots, idle public IPs and load balancers.
Reading Advisor, resource metadata, and Monitor metrics uses the Reader and Cost Management Reader roles. If you assigned only Cost Management Reader above, also add Reader at the same scope so the resource checks can enumerate resources:
az role assignment create --assignee "$APP_ID" \
--role "Reader" --scope "/subscriptions/$SUBSCRIPTION_ID"Kubernetes (AKS) cost & optimization
The Cost Management Reader + Reader roles above already give CostLens what it needs for AKS. Reader covers Azure Monitor metric reads and VM Scale Set enumeration, so no separate Monitoring Reader role is required.
Node-pool optimization — no cluster change needed
CostLens follows each AKS node pool to its backing VM Scale Set (in the MC_… node resource group) and reads its CPU from Azure Monitor. Idle / right-sizing / Spot node-pool recommendations appear on the Recommendations page automatically. See Kubernetes Optimization.
Per-cluster node cost — automatic
AKS node compute lives in the cluster's node resource group (MC_<resource-group>_<cluster>_<region>). CostLens attributes that resource group's spend to the cluster using the Cost Management Reader role — nothing to enable.
Per-namespace & per-workload cost — enable the AKS cost analysis add-on
On each cluster, enable the AKS cost analysis add-on (Azure Portal → cluster → Cost analysis, or the aks-preview CLI). Azure Cost Management then allocates the cluster's spend by Kubernetes namespace and controller, which appears in the Kubernetes panel on the Billing page within ~24 hours. See Kubernetes Costs.
No agent, no cluster access
CostLens reads AKS cost and utilisation entirely from Cost Management, Azure Resource Graph, and Azure Monitor — there is nothing to install in the cluster and no Kubernetes API access is required.
Applying fixes (optional)
Scanning is fully read-only. Applying a fix (deallocating an idle VM, deleting an unattached disk/snapshot, releasing a public IP, removing an idle load balancer) requires write access. Grant a Contributor role — or a custom role limited to the specific write actions — at the scope you want CostLens to remediate. Without a write role, recommendations are shown but the Apply Fix button stays disabled. See Auto-Fix for the approval workflow.
Enabling automatic Auto-Fix (least privilege)
Automatic Auto-Fix (hands-off apply) on Azure covers exactly one reversible action today — stopping an idle VM (deallocate). To enable it with least privilege, grant only VM power control via a custom role rather than broad Contributor:
az role definition create --role-definition '{
"Name": "CostLens Auto-Fix (VM power)",
"Description": "Least-privilege VM start/deallocate for CostLens Auto-Fix",
"Actions": [
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/deallocate/action"
],
"AssignableScopes": ["/subscriptions/<SUBSCRIPTION_ID>"]
}'
az role assignment create --assignee "<CLIENT_ID>" \
--role "CostLens Auto-Fix (VM power)" --scope "/subscriptions/<SUBSCRIPTION_ID>"First sync phases
| Phase | What happens |
|---|---|
| Fetching billing data | Pulls monthly + daily cost (normalised to USD via the CostUSD metric) from the Cost Management Query API |
| Running optimisation checks | Ingests Azure Advisor + runs the CostLens resource checks |
| Generating AI explanations | Aevi writes plain-English explanations and savings estimates |
Common errors and fixes
| Error | Fix |
|---|---|
AUTH_FAILED | The client secret is wrong or expired. Re-run az ad app credential reset and update the secret via Edit Credentials. |
INSUFFICIENT_PERMISSIONS | The service principal is missing a role. Confirm Cost Management Reader (and Reader for resource checks) is assigned at the correct scope. |
EXPORT_NOT_CONFIGURED | Cost Management data isn't available yet for a new subscription — allow up to 24–48 hours after first usage. |
| No recommendations appear | Azure Advisor needs a few days of usage to generate cost recommendations; resource checks require the Reader role. |
| No per-namespace AKS cost | Enable the AKS cost analysis add-on on the cluster; allow ~24h for allocated data to appear. |