“Unlimited scalability” is a selling point for developers and a liability for finance teams — unless the platform enforces guardrails before spend happens. Most organizations discover this mismatch via a surprise bill at month-end, followed by a scramble to identify who created the expensive resources.
In an enterprise landing zone, cost governance cannot be reactive. If a resource lacks a required tag, ARM should reject the deployment. If a subscription approaches its budget ceiling, the platform team should know before it crosses. This guide implements the automated controls required to prevent cloud sprawl.
By the end of this guide, you will:
- Implement Deny policies to block untagged resource creation.
- Automate tag inheritance from Resource Groups using Modify policies.
- Deploy subscription-level budgets with forecasted alerts as code.
- Configure FOCUS v1.3 cost exports for cross-cloud reporting.
- Query cost anomalies using KQL.
This is Post 9 in the Azure Platform Engineering series.
Tagging Enforcement: The Foundation of Accountability
Every FinOps capability — chargeback, showback, and cost allocation — depends on tags. A resource without a CostCenter tag cannot be mapped to a business unit.
Deny Policies for Untagged Resources
A Deny policy evaluates the request before the resource is created. The mode: 'Indexed' setting is critical; it ensures the policy only evaluates resource types that support tags, avoiding errors on internal Azure resources like managed disks or NICs.
Bicep: CostCenter Enforcement
resource requireCostCenter 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
name: 'require-costcenter-tag'
properties: {
displayName: 'Require CostCenter tag'
mode: 'Indexed'
policyRule: {
if: { field: 'tags[\'CostCenter\']', exists: 'false' }
then: { effect: 'Deny' }
}
}
}
Tag Inheritance via Modify Policy
Use a Modify policy to automatically copy tags from a Resource Group to its child resources. This requires granting the policy identity the Tag Contributor role (4a9aeed2-a923-413d-95c2-739962ca585d) at the target scope.
Automated Budgeting and Alerts
Every vended subscription should receive a default budget at creation. Configure the 80% Forecasted alert as your primary operational trigger. Forecasted alerts fire when the projected month-end cost will exceed the threshold, giving you days to act rather than hours.
Terraform: Monthly Budget
resource "azurerm_consumption_budget_subscription" "default" {
name = "${var.subscription_name}-budget"
subscription_id = var.subscription_id
amount = 1000
time_grain = "Monthly"
time_period {
start_date = formatdate("YYYY-MM-01'T'00:00:00Z", timestamp())
}
notification {
threshold = 80
operator = "GreaterThan"
threshold_type = "Forecasted"
contact_emails = [var.admin_email]
}
}
Note: Cost Management data has an 8–24 hour lag. Alerts evaluate against the previous day’s billing data.
FinOps Automation and Visibility
Cost Anomaly Detection (KQL)
Identify Resource Groups with the largest day-over-day cost increase. Requirement: Enable the Azure Cost Management connector for Log Analytics.
UsageDetails
| where TimeGenerated > ago(7d)
| summarize DailyCost = sum(PreTaxCost) by bin(TimeGenerated, 1d), ResourceGroup
| serialize
| extend PrevDailyCost = prev(DailyCost)
| extend CostChange = DailyCost - PrevDailyCost
| where CostChange > 100 // Flag $100+/day increases
| project Date = TimeGenerated, ResourceGroup, DeltaUSD = round(CostChange, 2)
FOCUS v1.3 Exports
Export your cost data in the FOCUS (FinOps Open Cost & Usage Specification) format for normalized cloud reporting. These exports must be configured at the Billing Account scope.
az costmanagement export create \
--name "platform-focus-export" \
--scope "/providers/Microsoft.Billing/billingAccounts/12345" \
--type FocusCost \
--dataset-configuration version="1.3" \
--recurrence "Daily"
Best Practices
- Limit Mandatory Tags: Enforce no more than 3–5 tags. Tag fatigue leads to teams entering “junk” data to bypass the policy.
- Forecast Over Actual: Always prioritize forecasted alerts for operations. Actual alerts at 100% only tell you that the budget has already been spent.
- Grant Reader Access: Grant your finance team the
Cost Management Readerrole at the management group scope. This allows full visibility without infrastructure permissions.
Sources
Next, proceed to Post 10: Day-2 Operations. This final article covers maintaining and evolving your landing zone after initial deployment.
