Azure FinOps Monthly Report
Generate a cross-validated Azure cost report with interactive dashboard, CxO executive summary, and Azure Advisor-sourced recommendations — in under 15 minutes.
Quickstart (2 steps)
# Step 1: Export CSV from Azure Portal > Cost Management > Cost Analysis > Export
# Save to: data/finops/azure/YYYY-MM/cost-analysis-{subscriptions,services}.csv
# Step 2: Generate report + dashboard
/finops:azure-monthly --billing-period YYYY-MM --budget YOUR_BUDGET_NZD --data-dir data/finops/azure/YYYY-MM
Or manually:
export AZURE_MONTHLY_BUDGET_NZD=45000
python azure-finops-dashboard.py
open azure-finops-dashboard.html
Prerequisites
| Requirement | How to Verify |
|---|---|
| Azure CLI installed | az --version |
| Authenticated | az login then az account show |
| ADLC framework | .claude/ directory exists in your project |
| Portal CSV exported | data/finops/azure/YYYY-MM/cost-analysis-subscriptions.csv exists |
Environment Variables
export AZURE_SUBSCRIPTION_ID=YOUR_SUBSCRIPTION_ID
export AZURE_TENANT_ID=YOUR_TENANT_ID
export AZURE_LOCATION=YOUR_REGION # e.g., australiaeast
export AZURE_MONTHLY_BUDGET_NZD=YOUR_BUDGET # e.g., 45000
export AZURE_OVERAGE_THRESHOLD_PCT=10 # Alert at 10% over budget
Monthly Process (5 Steps)
Step 1: Export Portal CSV (SSOT)
- Open Azure Portal > Cost Management > Cost Analysis
- Set date range to the billing month (e.g., Feb 1-28, 2026)
- Group by: Subscription → Click Export → Save as
cost-analysis-subscriptions.csv - Group by: Service Name → Click Export → Save as
cost-analysis-services.csv - Save both to:
data/finops/azure/YYYY-MM/
The Azure Cost Management API (az rest) only returns data for subscriptions where you have RBAC Reader access. Portal CSV exports at EA billing scope include ALL subscriptions — even those without RBAC. See SSOT Hierarchy below.
Step 2: Run the Report Command
/finops:azure-monthly --billing-period YYYY-MM --budget 45000 --data-dir data/finops/azure/YYYY-MM
This generates:
- Interactive HTML dashboard (Plotly charts, budget gauge, KPI cards)
- CxO executive report (markdown)
- Stakeholder email (copy-paste ready)
- CSV exports (subscription costs, service breakdown)
- Excel workbook
- Cross-validation evidence (JSON)
Step 3: Review Azure Advisor Recommendations
- Open Azure Portal > Advisor > Cost tab
- Filter: All subscriptions
- Note each recommendation's:
- Yearly savings (NZD)
- Impacted subscription and resource
- Impact level (High/Medium/Low)
- Recommendation type ID (for audit trail)
- Add to the dashboard and CxO report
Never include savings estimates from pricing pages, calculations, or agent-generated numbers. Azure Advisor recommendations are evidence-based and include the recommendation type ID for independent verification.
Step 4: Send to Stakeholders
Copy azure-email.txt to your email client. Attach:
azure-finops-dashboard.html(interactive dashboard)azure-cxo-report.md(executive summary)subscription-costs.csv+service-breakdown.csv
Step 5: Archive Evidence
# Evidence is auto-saved to:
# Git-tracked: projects/CloudOps-S1/finops-reports/YYYY-MM/
# Ephemeral: tmp/cloud-infrastructure/finops/azure/
Deliverables
| File | Format | Audience | Content |
|---|---|---|---|
azure-finops-dashboard.html | HTML | CxO, FinOps | Interactive charts, KPIs, budget gauge |
azure-cxo-report.md | Markdown | CFO, CTO | Executive summary, top subscriptions, services, recommendations |
azure-email.txt | Plain text | Stakeholders | Copy-paste email with key figures |
azure-stakeholder-email.md | Markdown | CloudOps | Detailed email with data quality, Advisor table |
subscription-costs.csv | CSV | Analytics | Per-subscription breakdown with cost tiers |
service-breakdown.csv | CSV | Analytics | Per-service breakdown with categories |
azure-monthly-YYYY-MM.xlsx | Excel | Finance | Workbook with styled sheets |
azure-scoring.json | JSON | QA | Agent scoring evidence |
Data Source Hierarchy
┌─────────────────────────────────────────────────────────────┐
│ 1. Portal CSV (EA billing) ← AUTHORITATIVE │
│ Includes ALL subscriptions regardless of RBAC │
│ │
│ 2. Azure API (az rest) ← RBAC-SCOPED │
│ Only returns subs where user has Reader access │
│ May be PARTIAL — missing ungoverned subscriptions │
│ │
│ 3. MCP Server ← VALIDATION ONLY │
│ Cross-check layer, not primary source │
└─────────────────────────────────────────────────────────────┘
When API total < Portal CSV total: A subscription exists in the EA billing that the current user cannot access via API (no RBAC Reader). Document the gap with subscription-level reconciliation.
Anti-pattern: FINOPS_API_SSOT_MISMATCH — presenting API-only totals as authoritative without the RBAC caveat.
Cross-Validation
Every monthly report should include a cross-validation check:
# Compare API result vs Portal CSV
# API: az rest query → total across accessible subscriptions
# Portal: CSV sum → total across ALL subscriptions (EA billing)
# Delta: If > 1%, investigate which subscriptions are missing
The cross-validation evidence is saved as cross-validation-YYYY-MM-DD.json with:
- L1 (API total), L2 (CLI total), L3 (Portal CSV total)
- Variance percentage
- Root cause if delta exists
- 5-why analysis for material gaps
Configuration
| Parameter | Environment Variable | Default | Description |
|---|---|---|---|
| Subscription | AZURE_SUBSCRIPTION_ID | Required | Primary subscription UUID |
| Tenant | AZURE_TENANT_ID | Required | Azure AD tenant UUID |
| Region | AZURE_LOCATION | australiaeast | Primary Azure region |
| Budget | AZURE_MONTHLY_BUDGET_NZD | Required | Monthly budget in NZD |
| Overage | AZURE_OVERAGE_THRESHOLD_PCT | 10 | Alert threshold (%) |
Monthly Cadence
| Week | Action | Command |
|---|---|---|
| 1st of month | Export prior month CSV from Portal | Manual (Azure Portal) |
| 1st of month | Generate report + dashboard | /finops:azure-monthly |
| 1st of month | Review Advisor recommendations | Manual (Azure Portal > Advisor) |
| 1st of month | Send stakeholder email | Copy azure-email.txt |
| Mid-month | Check budget vs MTD | /finops:azure-monthly (current month) |