Azure FinOps Dashboard
Cost visibility that answers the question a bill cannot: not what you spent, but which resource changed behavior and what it will cost you next. Statistical anomaly detection and trend forecasting over the Cost Management API, written in C# and running credential-free.
/01Problem
A cloud bill tells you what you spent after you have already spent it, aggregated to a level where nothing is actionable. By the time a runaway resource shows up as a line item, it has been running for most of a billing cycle, and the person who could have caught it has no signal that anything changed.
The three questions worth answering are earlier and more specific: which resources are behaving differently than they did last month, where is spend heading if nothing changes, and which resources cannot even be attributed to an owner because nobody tagged them.
/02Approach
- A timer-triggered Function ingests the previous seven days of actual cost from the Cost Management REST API each morning, grouped by resource, resource type, and resource group, upserting into Cosmos DB keyed by resource ID so re-runs are idempotent.
- Anomaly detection runs half an hour later against the stored history: a rolling 30-day mean and standard deviation per resource, flagging any resource whose latest daily cost exceeds two sigma, tiered Low at 2.0, Medium at 2.5, and High at 3.0.
- Forecasting runs after that, projecting 14 days on a linear trend over the trailing 30-day window with confidence intervals derived from historical variance, and refuses to project at all on fewer than seven days of data rather than emitting a number nobody should trust.
- A tag hygiene pass evaluates every subscription resource against a required-tag policy and reports both a compliance percentage and the specific resources missing specific tags, because a percentage alone is not something anyone can act on.
/03Architecture
Five HTTP-triggered Functions expose the stored results as a REST API to a React single-page app on Static Web Apps, so the read path never touches the Cost Management API and page loads are not gated on an upstream call. The four Cosmos containers separate daily costs, anomalies, forecasts, and budgets, which keeps the analysis jobs from contending with the read path.
The whole thing runs without a stored credential. The Function App uses a system-assigned managed identity with exactly three role assignments: Cost Management Reader and Reader at subscription scope for cost and resource metadata, and Cosmos DB Built-in Data Contributor at database scope for the data plane. Key-based access to Cosmos is disabled at the account level, so even a leaked connection string would be inert. Three reusable Terraform modules compose into a dev environment with remote state in Azure Storage.
/04Outcome
A cost pipeline where every number on the dashboard is traceable to a stored record and a stated method: the anomaly tiers are a sigma threshold rather than a heuristic, and the forecast declares its own confidence bounds and refuses to run on thin data.
The FinOps counterpart on the AWS side is the Cost Intelligence Dashboard, which applies the same z-score and regression approach to Cost Explorer. Running the same method across both clouds is what makes the practice portable rather than a single-provider trick.