Skip to content

ADR-015: Azure FinOps Architecture with FOCUS 1.3 NormalizationΒΆ

Note: This ADR consolidates 5 source documents during the 2026-01-28 namespace consolidation: - azure-finops-cross-validation-architecture-2026-01-17.md - azure-finops-dependency-decisions-2026-01-17.md - azure-finops-gap-closure-2026-01-18.md - azure-finops-skills-architecture-2026-01-18.md - azure-finops-architecture-diagram.md

Status: Accepted Date: 2026-01-28 (consolidated from 2026-01-17/2026-01-18 originals) Deciders: @cloud-architect, @product-owner, HITL/Manager Framework: ADLC v3.0.0 Constitutional Principle: IV. Hybrid Deployment, V. Observability & Resilience


Executive SummaryΒΆ

This architecture establishes CFO-grade FinOps validation for Azure Cost Management using:

  1. Ground Truth Validation: 3-way cross-validation between Azure Native APIs (primary), Portal CSV Exports (baseline), and MCP Server (AI agent access)
  2. FOCUS 1.3 Normalization: 37-column cross-cloud cost schema enabling AWS + Azure aggregation
  3. 4-Component Accuracy Formula: β‰₯99.5% target (cloning proven AWS MCP pattern with 99.73% accuracy)
  4. CLI Enhancement: Custom date ranges via --start-date/--end-date flags

Success Criteria: - Overall accuracy: β‰₯99.5% (4-component weighted formula) - Cost value match: Β±$0.01 tolerance (40% weight, CFO compliance) - FOCUS column coverage: 37/37 (100% FOCUS 1.3 specification) - Evidence collection: 100% (all operations logged to tmp/)


ContextΒΆ

Problem StatementΒΆ

Azure FinOps requires CFO-grade precision for cost analysis across multiple subscriptions. The existing system has gaps:

  1. CLI Date Handling: Only relative months (--months), no historical queries
  2. MCP Tools: 0 Azure Cost tools with FOCUS 1.3 normalization
  3. FOCUS Columns: 6 columns (21.4% coverage) vs required 37 columns (100%)
  4. Validation Accuracy: Unknown baseline (no cross-validation established)

AWS Reference (Proven Pattern)ΒΆ

AWS Cost Explorer MCP achieved 99.73% accuracy using: - 4-component accuracy formula - 3-file evidence pattern (ground-truth, mcp-response, validation-result) - Native CLI as PRIMARY ground truth


DecisionΒΆ

Clone AWS MCP validation pattern for Azure with FOCUS 1.3 normalization.

Architecture ComponentsΒΆ

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TIER 1: GROUND TRUTH (PRIMARY - 100% canonical)                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   Azure Native APIs                                                        β”‚
β”‚   β”œβ”€β”€ az consumption usage list    (detailed records)                     β”‚
β”‚   └── az costmanagement query      (aggregated costs)                     β”‚
β”‚   Evidence: tmp/finops/azure/cross-validation/ground-truth.json           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TIER 2: CLI ENHANCEMENT (Human + AI access)                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   runbooks finops azure monthly --start-date YYYY-MM-DD --end-date ...    β”‚
β”‚   NEW FLAGS: --start-date, --end-date (ISO 8601, ≀366 days)              β”‚
β”‚   Evidence: tmp/finops/azure/cli-output/monthly-*.json                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TIER 3: MCP SERVER (AI Agent access with FOCUS 1.3)                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   Azure Cost Management MCP Server (4 tools)                               β”‚
β”‚   β”œβ”€β”€ Tool 1: query_costs (timeframe β†’ FOCUS 1.3 JSON)                   β”‚
β”‚   β”œβ”€β”€ Tool 2: export_focus (JSON/CSV with 37 columns)                    β”‚
β”‚   β”œβ”€β”€ Tool 3: get_focus_schema (column definitions)                      β”‚
β”‚   └── Tool 4: validate_accuracy (4-component formula)                    β”‚
β”‚   Target Accuracy: β‰₯99.5%                                                  β”‚
β”‚   Evidence: tmp/finops/mcp-validation/azure/cross-validation-*.json       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

4-Component Accuracy FormulaΒΆ

overall_accuracy = (
    0.40 * cost_value_match +         # Β±$0.01 tolerance (CFO compliance)
    0.30 * subscription_count_match + # Exact count match
    0.20 * service_name_match +       # β‰₯95% intersection
    0.10 * focus_column_match         # 37/37 columns present
)

# Target: β‰₯99.5% (AWS parity)
Component Weight Calculation Pass Criteria
Cost Value Match 40% abs(mcp - native) ≀ $0.01 1.0 if within tolerance
Subscription Count 30% mcp_count == native_count Binary (1.0 or 0.0)
Service Name Match 20% intersection / union (Jaccard) β‰₯0.95
FOCUS Column Match 10% columns_present / 37 1.0 (100%)

FOCUS 1.3 Column Mapping (37/37 Complete)ΒΆ

Category Columns Azure Source Mapping Type
Billing 6 costInBillingCurrency, billingAccountId, etc. Direct
Charge 5 chargeType, product, date Direct + Mapped
Commitment 1 reservationName Direct
Consumption 2 quantity, unitOfMeasure Direct
Cost 3 effectivePrice, costInBillingCurrency Direct
Invoice 1 - Static ("Microsoft")
List Cost 2 paygCostInBillingCurrency, paygPrice Direct
Pricing 3 quantity, unitOfMeasure Direct + Derived
Provider 2 publisherName Direct + Static
Region 2 resourceLocation Direct + Mapped
Resource 3 resourceId, resourceName, meterCategory Direct
Service 2 meterCategory, meterSubCategory Direct
SKU 2 meterId Direct + Derived
Sub-Account 2 subscriptionId, subscriptionName Direct
Tags 1 tags Direct

Coverage: 27 direct + 3 mapped + 2 static + 5 derived = 37/37 (100%)


Dependency DecisionsΒΆ

REJECTED Dependencies (KISS Compliance)ΒΆ

Dependency Reason for Rejection Alternative
kaleido>=0.2.1 Single-purpose Plotly export Use playwright (multi-purpose, already in project)
weasyprint>=62.3 Not in MVP acceptance criteria Defer to Phase 2 (CTO quarterly reports)
jinja2>=3.1.5 Already transitive via vizro→dash→flask Trust transitive dependency

APPROVED DependenciesΒΆ

dependencies = [
    "vizro>=0.1.33",        # McKinsey executive dashboards (Apache 2.0)
    "plotly>=5.24.1",       # Interactive charts (MIT)
    "dash>=2.18.2",         # Custom dashboards (MIT, transitive via vizro)
    "playwright>=1.40.0",   # E2E tests + Plotly screenshot capture (Apache 2.0)
]

Evidence StructureΒΆ

tmp/cloud-infrastructure/finops/azure/
β”œβ”€β”€ cli-output/                              # CLI Enhancement
β”‚   └── monthly-2025-11-01-to-2025-11-30.json
β”œβ”€β”€ mcp-queries/                             # MCP Server
β”‚   β”œβ”€β”€ query-YYYY-MM-DD-HH-MM-SS.json
β”‚   └── query-body-YYYY-MM-DD-HH-MM-SS.json
β”œβ”€β”€ mcp-validation/                          # MCP Validation
β”‚   └── cross-validation-YYYY-MM-DD.json
β”œβ”€β”€ cross-validation/                        # Jupyter Notebook
β”‚   β”œβ”€β”€ ground-truth-nov-2025.json           # Native az consumption API
β”‚   β”œβ”€β”€ mcp-response-nov-2025.json           # MCP FOCUS 1.3 response
β”‚   └── validation-result-nov-2025.json      # 4-component accuracy
β”œβ”€β”€ focus-exports/                           # FOCUS Export
β”‚   β”œβ”€β”€ focus-export-YYYY-MM-DD.json
β”‚   └── focus-export-YYYY-MM-DD.csv
└── focus-validation/                        # Schema Validation
    └── column-coverage-report.json

ConsequencesΒΆ

PositiveΒΆ

  • AWS Parity: Proven accuracy formula (99.73% achieved in AWS)
  • Cross-Cloud Consistency: Same validation pattern for AWS and Azure
  • CFO-Grade Precision: Β±$0.01 tolerance for financial reporting
  • FOCUS 1.3 Standard: Industry-standard schema (FinOps Foundation endorsed)
  • Evidence-Based: ADLC-compliant validation with audit trail

NegativeΒΆ

  • Dual API Calls: Requires native + MCP calls per validation
  • Mapping Maintenance: 37-column mapping needs updates with API changes
  • Exchange Rate Dependency: NZD/USD conversions may introduce variance

RisksΒΆ

Risk Probability Impact Mitigation
Azure API Rate Limiting MEDIUM HIGH Exponential backoff, response caching
FOCUS Schema Changes LOW MEDIUM Version pin to 1.3, monitor spec updates
MCP Server Stability MEDIUM HIGH Error handling, fallback to native CLI
Currency Conversion LOW HIGH Use Azure's conversion rates, document source

Quality Gates (BLOCKING)ΒΆ

Gate Target Measurement Rejection Criteria
API Accuracy β‰₯99.5% 4-component formula <99.5% β†’ REJECT
FOCUS Coverage 37/37 columns Pydantic validation Missing columns β†’ REJECT
Date Range Support 100% CLI accepts flags Invalid dates β†’ REJECT
MCP Tool Operability 4/4 tools claude mcp call tests Tool failure β†’ REJECT
Evidence Collection 100% All paths exist Missing files β†’ REJECT

Implementation PhasesΒΆ

Phase Duration Owner Deliverables
1: CLI Enhancement 2 days python-expert --start-date/--end-date flags, validation logic
2: MCP Server 3 days mcp-integration-engineer 4 tools, β‰₯99.5% accuracy
3: FOCUS Validation 1 day qa-engineer 37/37 column coverage tests
4: Cross-Validation Notebook 2 days data-engineer Jupyter notebook, 3-file evidence

Total: 8 days


ReferencesΒΆ


Source Documents (Consolidated)ΒΆ

Original Document Date Key Contribution
azure-finops-cross-validation-architecture-2026-01-17.md 2026-01-17 3-way validation, sequence diagram, evidence schema
azure-finops-dependency-decisions-2026-01-17.md 2026-01-17 KISS/DRY analysis, dependency rejections
azure-finops-gap-closure-2026-01-18.md 2026-01-18 Gap analysis, CLI enhancement spec, MCP server design
azure-finops-skills-architecture-2026-01-18.md 2026-01-18 Tier 3 customization model, skills/commands location
azure-finops-architecture-diagram.md 2026-01-18 Visual architecture, FOCUS mapping table

Version: 1.0.0 ADLC Framework: v3.0.0 Maintainer: @cloud-architect Coordination Log: tmp/cloud-infrastructure/coordination-logs/cloud-architect-2026-01-28-adr-migration.json