Manage Subscription Budgets¶
The engineer's guide to subscription budgets and cost alerts. Use this runbook to:
- Change a subscription's monthly budget.
- Change who receives budget and cost anomaly alerts.
- Respond to a budget or anomaly alert.
For how budgets, FinOpsId and the monthly review fit together, see
Budgets and Cost Allocation.
A budget alerts, it doesn't stop anything
Azure budgets send email. They don't stop resources, block deployments or cap spend. Someone has to read the alert and act.
What every subscription gets¶
Vending creates two cost resources on every subscription, from the same two
inputs in its <name>.tf:
| Resource | Name | Fires when |
|---|---|---|
| Budget | budget-<name>-monthly |
Actual spend passes 80%; actual spend passes 100%; forecast spend for the month passes 100% |
| Cost anomaly alert | caa-<name> |
Azure's anomaly detection sees unusual daily spend |
Budget alerts go to budget_alert_emails and to anyone holding Owner or
Contributor on the subscription at that moment. Anomaly alerts go to
budget_alert_emails only.
The amount is in the billing account's currency (EUR) and resets on the 1st of each month.
The projects¶
| Project | Lane | Holds |
|---|---|---|
subscription-vending-workload |
B | budget_amount and budget_alert_emails in each workload subscription's <name>.tf. CI applies on merge. |
subscription-vending-platform |
A | The same inputs for platform subscriptions. You apply with ./apply.ps1. |
terraform-azurerm-subscription-budget |
— | The thresholds and contact roles. Change these here only if every subscription should change. |
Change the budget amount¶
📁
subscription-vending-*: 📃<name>.tf
Set it to what the workload should cost in a normal month, plus a margin, not to what it cost last month. If the budget is set at the bill, the 80% alert fires every month and people learn to ignore it.
A rough way to size it:
- Cost Management → Cost analysis, scoped to the subscription, last 3 months, grouped by month.
- Take the normal month, remove anything that was a one-off, and add any change the team has planned.
- Round up by about 20%.
Open an MR and say in the description why the amount changed. The plan
should show one in-place update to azurerm_consumption_budget_subscription
changing amount, and nothing else. Merge (and for a platform subscription,
apply).
Change who gets alerts¶
Use a team mailbox or distribution list rather than a person, so the alert still lands when someone leaves. At least one address is required.
The plan should show in-place updates to the budget (every
notification block's contact_emails) and to azurerm_cost_anomaly_alert.
Respond to an alert¶
| Alert | What it means | Do this |
|---|---|---|
| Forecast 100% | At the current rate, the month will end over budget | Look now, while there's time to act. Find what changed (below). |
| Actual 80% | Most of the month's budget is spent | Check the date. On the 25th, it's probably fine. On the 10th, find what changed. |
| Actual 100% | Over budget | Find what changed. Either fix it, or raise the budget with a reason. |
| Anomaly | One day's spend was unusual for this subscription | Find the resource. Anomalies often catch a mistake (a VM left on, a log level left at verbose) days before the budget does. |
To find what changed:
- Cost Management → Cost analysis, scoped to the subscription.
- View Daily costs, grouped by Resource, for this month.
- Find the day the line jumped and the resource behind it.
-
Check that resource's Activity log for who changed it and when. It's also in the central Log Analytics workspace,
log-platform-prod: -
Tell the workload owner (the
WorkloadOwnertag). Record what you found and what was done in the alert's ticket.
Check it worked¶
az consumption budget list --subscription <sub-id> \
--query "[].{name:name, amount:amount, spent:currentSpend.amount}" -o table
In the portal: Cost Management → Budgets, scoped to the subscription,
shows budget-<name>-monthly with the new amount. Cost Management → Cost
alerts → Anomaly alert rules shows caa-<name> with the new emails.
When it fails¶
| Symptom | Cause | Fix |
|---|---|---|
| Plan wants to replace the budget | Someone set budget_start_date on an existing budget, or the budget module changed the name |
Remove budget_start_date. It's only read when the budget is first created. If the name changed, read the module's release notes before applying. |
| Azure rejects the budget's start date on a new subscription | budget_start_date is before the current month |
Leave it null. The module uses the 1st of the current month. |
| Nobody got the alert | The email is a person who left, or the mail went to junk | Change budget_alert_emails to a team mailbox. Allow azure-noreply@microsoft.com. |
| The budget shows €0 spent for a new subscription | Cost data takes 8–24 hours to appear | Wait a day. |
| Alerts come every month | The budget is set at the normal monthly bill | Re-size it as in Change the budget amount. |