The first time most engineers look at Cost Management is the day after a surprise invoice. Ten minutes of setup avoids that. Prices and discounts vary by agreement, so this post sticks to where to look and what to configure.
Where the numbers are
In the portal: Cost Management + Billing > Cost Management > Cost analysis, scoped to a subscription or resource group. Three views answer most questions:
- Group by: Resource group: which project is spending.
- Group by: Service name: compute, storage, network, databases.
- Group by: Tag (for example
ownerorcostcenter): who owns the spend, if your tags are good.
Switch Granularity to Daily to spot the day something started.
Tip
Cost data is not real time. It typically lags by several hours to a day, so a budget alert is an early warning, not a hard stop.
Know what usually costs the most
| Item | Why it surprises people |
|---|---|
| VMs left running | "Stopped" in the OS still bills compute; deallocate |
| Premium disks and snapshots | Bill while the VM is deallocated |
| Log Analytics ingestion | Verbose diagnostic settings send a lot of data |
| Public IPs, gateways, firewalls | Bill per hour whether used or not |
| Data egress | Traffic out of a region or to the internet |
| Orphaned resources | Disks, NICs and IPs left after a VM was deleted |
Find orphaned disks quickly:
az disk list --query "[?diskState=='Unattached'].{Name:name, RG:resourceGroup, GB:diskSizeGb, Sku:sku.name}" -o table
Create a budget
A budget compares spend with a monthly amount and emails people at thresholds you choose.
SUB=$(az account show --query id -o tsv)
az consumption budget create \
--budget-name bud-app-dev-monthly \
--amount 500 --category cost --time-grain monthly \
--start-date 2026-11-01 --end-date 2027-10-31 \
--resource-group rg-app-dev
The CLI budget commands vary by version, and notification settings are easiest in the portal: Cost Management > Budgets > Add, then add alert conditions such as Actual 80%, Actual 100% and Forecasted 100%, each with email recipients or an action group.
PowerShell alternative:
New-AzConsumptionBudget -Name bud-app-dev-monthly -Amount 500 -Category Cost `
-TimeGrain Monthly -StartDate 2026-11-01 -EndDate 2027-10-31 `
-ResourceGroupName rg-app-dev `
-ContactEmail me@contoso.com -NotificationKey Actual80 -NotificationThreshold 80 -NotificationEnabled
Warning
A budget does not stop resources. If you need an automatic action, link the alert to an action group that runs an automation runbook (for example, deallocate dev VMs), and test it.
Check spend from the command line
az consumption usage list --start-date 2026-10-01 --end-date 2026-10-29 \
--query "[].{Res:instanceName, Cost:pretaxCost, Cur:currency}" -o table
For larger analysis, set up a scheduled export instead: Cost analysis > Exports > Add, daily, to a storage account. You then get CSV or Parquet files you can load into Excel, Power BI or a query engine.
Tag so costs have an owner
az group update -n rg-app-dev --tags owner=team-payments costcenter=CC1234 env=dev
Tags on a resource group are not inherited by the resources inside it automatically. Use the Inherit a tag from the resource group built-in policy if you want that.
A weekly five-minute routine
- Cost analysis, last 30 days, daily, grouped by resource group. Any new spike?
- Advisor > Cost recommendations. Anything idle or oversized?
- Unattached disks and unused public IPs list.
- Budgets page: any forecast over 100%?
Prevent it next time
- One budget per subscription and per major resource group, with forecast alerts.
- Auto-shutdown on every dev/test VM.
- Require
ownerandenvtags with Azure Policy. - Review Log Analytics diagnostic settings before enabling "all logs" on busy resources.