
Azure Finops
- 46 installs
- 6 repo stars
- Updated July 22, 2026
- julianobarbosa/claude-code-skills
Helps with ai & agent building tasks.
About
azure-finops is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- azure-finops
- AI & Agent Building
- AI-coding skill
Azure Finops by the numbers
- 46 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #7,629 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/julianobarbosa/claude-code-skills --skill azure-finopsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 46 |
|---|---|
| repo stars | ★ 6 |
| Last updated | July 22, 2026 |
| Repository | julianobarbosa/claude-code-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
AzureFinOps Skill
Azure cost optimization through reservation analysis, waste discovery, and stakeholder reporting.
Important
- All Azure operations are READ-ONLY — zero modifications to any resource
- Primary output language: Portuguese (BR) for stakeholder responses
- Python CLI fallback:
uv run python -m azure_finopswhen MCP/CLI auth unavailable
Context Files
AzureToolReference.md— MCP tools + CLI commands quick referenceReservationInventory.md— SKU matching and reservation interpretation SOPPricingComparison.md— PAYG vs RI pricing methodology and savings formulas
Workflow Routing
| Workflow | Trigger | File |
|---|---|---|
| ValidateCosts | "validate costs", "are these reservations or PAYG", "check billing" | Workflows/ValidateCosts.md |
| FindWaste | "find waste", "orphaned disks", "orphaned resources" | Workflows/FindWaste.md |
| CoverageAnalysis | "reservation coverage", "reservation gaps", "savings analysis" | Workflows/CoverageAnalysis.md |
| DraftResponse | "draft response for", "resposta para", "executive summary" | Workflows/DraftResponse.md |
Examples
Example 1 — Cost Validation:
"Are these January costs reservations or pay-as-you-go?"
Routes to: Workflows/ValidateCosts.mdExample 2 — Waste Discovery:
"Find orphaned disks and wasted resources across all subscriptions"
Routes to: Workflows/FindWaste.mdExample 3 — Executive Response:
"Draft a response for Jean about the January billing anomalies"
Routes to: Workflows/DraftResponse.md---
Gotchas
- Reservation matching: SKU naming differs between usage data and purchase data —
Standard_D8s_v3in usage vsD8sv3in RI. A direct join misses 100%. - Savings Plan vs Reservation can stack — calculators that pick one ignore the combined savings.
- PAYG vs RI pricing: Marketplace listings are excluded from RI — surprise unreserved charges show up for SQL Server BYOL, etc.
- Cost data lag is 24-48 hours — same-day analyses miss recent activity entirely.
- RI scope (shared vs single-subscription): wrong scope means the RI applies to unintended workloads — and you discover it months later in an audit.
- Currency conversion in EA reports: exchange rate is locked at month close; mid-month estimates use a different rate than the final invoice.
Azure Tool Reference
Quick reference for all Azure tools used by AzureFinOps workflows.
MCP Tools (mcp__azure__*)
| Tool | Command | Purpose |
|---|---|---|
mcp__azure__subscription_list | subscription_list | List all accessible subscriptions |
mcp__azure__advisor | advisor_recommendation_list | Cost optimization recommendations |
mcp__azure__pricing | pricing_get | PAYG and reserved instance pricing |
mcp__azure__compute | compute_vm_get, compute_vm_list | VM details and inventory |
mcp__azure__sql | sql_server_list, sql_db_list | SQL Server and database inventory |
mcp__azure__storage | storage_account_list | Storage account details |
mcp__azure__monitor | monitor_metrics_list | Resource utilization metrics |
MCP Tool Invocation Pattern
mcp__azure__compute → compute_vm_list
Parameters: subscription, resource_group (optional)
Returns: List of VMs with SKU, location, status
mcp__azure__pricing → pricing_get
Parameters: service_name, sku_name, region
Returns: PAYG price, 1yr RI price, 3yr RI priceCLI Commands (No MCP Equivalent)
Reservation Orders
# List all reservation orders in tenant
az reservations reservation-order list --query "[].{name:name, displayName:displayName, createdDateTime:createdDateTime}" -o table
# List reservations within a specific order
az reservations reservation list --reservation-order-id <ORDER_ID> --query "[].{name:name, sku:sku.name, quantity:quantity, location:location, provisioningState:provisioningState}" -o tableResource Graph Queries
# Find orphaned (unattached) managed disks
az graph query -q "Resources | where type =~ 'microsoft.compute/disks' | where managedBy == '' or isnull(managedBy) | project name, resourceGroup, subscriptionId, properties.diskSizeGB, sku.name, location" --first 1000
# Find stopped/deallocated VMs
az graph query -q "Resources | where type =~ 'microsoft.compute/virtualMachines' | where properties.extended.instanceView.powerState.code == 'PowerState/deallocated' | project name, resourceGroup, subscriptionId" --first 1000
# Find unassociated public IPs
az graph query -q "Resources | where type =~ 'microsoft.network/publicipaddresses' | where properties.ipConfiguration == '' or isnull(properties.ipConfiguration) | project name, resourceGroup, subscriptionId" --first 1000Tool Selection Guide
| Task | Preferred Tool | Why |
|---|---|---|
| Reservation orders/details | az reservations CLI | No MCP equivalent exists |
| Orphaned resource queries | az graph query CLI | Resource Graph needs full KQL |
| Subscription listing | MCP subscription_list | Simpler wrapper |
| Advisor recommendations | MCP advisor | Structured output |
| Pricing comparison | MCP pricing | Clean API parameters |
| VM/disk/storage lookup | MCP compute/storage | Typed responses |
| Batch offline analysis | Python CLI (uv run) | When MCP/CLI auth unavailable |
Authentication Notes
- MCP tools use the active Azure CLI session (
az login) - CLI commands require
az loginwith tenant access - If auth expires mid-workflow, re-authenticate:
az login --tenant <TENANT_ID> - Python CLI fallback reads from exported CSV data when live auth unavailable
Pricing Comparison Methodology
Standard methodology for comparing Pay-As-You-Go (PAYG) vs Reserved Instance (RI) pricing.
Using mcp__azure__pricing
mcp__azure__pricing → pricing_get
Parameters:
service_name: "Virtual Machines" | "SQL Database" | "Storage" | etc.
sku_name: "Standard_D32s_v5" | "P50" | etc.
region: "eastus" | "brazilsouth" | etc.
currency: "BRL" | "USD"Always request pricing in BRL for Brazilian stakeholders. Include USD for reference if needed.
Savings Calculation Formula
Monthly PAYG Cost = hourly_rate * 730 (hours/month)
Monthly 1yr RI Cost = annual_price / 12
Monthly 3yr RI Cost = triennial_price / 36
Monthly Savings (1yr) = Monthly PAYG - Monthly 1yr RI
Monthly Savings (3yr) = Monthly PAYG - Monthly 3yr RI
Savings Percentage = (Monthly Savings / Monthly PAYG) * 100
Annual Savings = Monthly Savings * 12Typical RI Savings by Service Type
| Service | 1-Year RI Savings | 3-Year RI Savings | Notes |
|---|---|---|---|
| Virtual Machines (general) | 20-40% | 50-72% | Varies heavily by series |
| VM MSv2 (SAP HANA) | ~42% | ~72% | High absolute savings due to cost |
| Microsoft Fabric | ~40% | — | Check current availability |
| Azure SQL Database | 25-40% | 50-65% | PaaS only |
| Premium SSD Managed Disks | ~5% | — | Low savings, consider right-sizing |
| Blob Storage Reserved Capacity | 20-26% | 30-38% | Tiered by commitment size (1TB/10TB/100TB) |
| Azure Files | 20-36% | 29-36% | Depends on tier and redundancy |
| App Service | 30-55% | 50-65% | Premium v3 plans |
Pricing Report Format
For each service analyzed, present:
| Attribute | Value |
|-----------|-------|
| Service | {service name and SKU} |
| Region | {region} |
| Monthly PAYG | BRL {amount} |
| Monthly 1yr RI | BRL {amount} ({savings_pct}% savings) |
| Monthly 3yr RI | BRL {amount} ({savings_pct}% savings) |
| Recommended Term | {1yr or 3yr} — {reasoning} |
| Annual Savings | BRL {amount} |When to Recommend Each Term
| Signal | Recommended Term |
|---|---|
| Workload stable for 3+ years (SAP, core infra) | 3-year RI |
| Workload stable but uncertain long-term | 1-year RI |
| Variable/seasonal workload | Savings Plan or no RI |
| Workload being migrated/decommissioned | No RI |
| Disk with potential right-sizing opportunity | Right-size first, then RI |
Common Pricing Pitfalls
1. Comparing wrong SKU: Ensure the pricing SKU matches exactly what billing shows 2. Region mismatch: Prices vary significantly by region (brazilsouth often 20-40% more than eastus) 3. Currency fluctuation: BRL prices change with exchange rates — always use current pricing 4. Instance size flexibility: A reservation for a larger VM can cover multiple smaller ones at ratio 5. Cancelled reservations: Former reservations that were cancelled still show in order history but provide zero savings
Reservation Inventory SOP
Standard operating procedure for interpreting Azure reservation data and matching SKUs.
Order vs Reservation Distinction
- Reservation Order: The purchase container. Has an order ID, created date, billing plan.
- Reservation: The actual capacity commitment within an order. Has SKU, quantity, location, term.
- One order can contain multiple reservations (rare but possible).
- Always drill from order → reservation to get the actual SKU details.
SKU Matching Rules
Exact Match
The reservation SKU exactly matches the billing line item SKU.
Billing: Standard_D32s_v5
Reservation: Standard_D32s_v5
Result: COVEREDInstance Size Flexibility
Azure VM reservations within the same series/family can cover different sizes:
- A D16s_v5 reservation covers 2x D8s_v5 or 0.5x D32s_v5
- Flexibility applies ONLY within the same series and region
- Check the instance size flexibility ratio table for exact mappings
Common Mismatch Patterns
| Billing Line | Reservation SKU | Covered? | Why |
|---|---|---|---|
| SQL Server Enterprise VM License | SQLDB_GP_Compute_Gen5 | NO | IaaS VM license vs PaaS SQL Database |
| Block Blob Hot RA-GRS | Block Blob Cool LRS | NO | Different tier AND redundancy |
| Fabric Compute CU | (none) | NO | No Fabric reservations exist in most tenants |
| Premium SSD P50 | (cancelled reservation) | NO | Cancelled reservations provide zero coverage |
| VM MSv2 M416ms_v2 | Standard_D-series | NO | Different VM family entirely |
PaaS vs IaaS Distinction
This is the most common source of false "covered" assessments:
- IaaS SQL: VM running SQL Server → needs VM reservation + SQL license (or AHB)
- PaaS SQL: Azure SQL Database → needs SQLDB reservation (different SKU family)
- A SQLDB reservation NEVER covers an IaaS SQL VM license cost
Reservation State Interpretation
| State | Meaning |
|---|---|
Succeeded | Active and providing coverage |
Cancelled | No longer provides coverage (even if not yet expired) |
Expired | Term ended, no coverage |
Processing | Being provisioned, not yet active |
Billing Plan Impact
| Plan | How It Appears in Cost Management |
|---|---|
| Monthly | Recurring charge each month — looks like regular PAYG |
| Upfront | Large one-time charge in purchase month — easy to spot |
| Mixed | Some upfront + monthly remainder |
Monthly billing reservations are the hardest to distinguish from PAYG in Cost Management views. Always cross-reference against reservation order list.
Verification Checklist
When asked "is service X covered by a reservation?":
1. List all reservation orders: az reservations reservation-order list 2. For each order, get reservation details: az reservations reservation list 3. Match the billing SKU against reservation SKUs using rules above 4. Check reservation state is Succeeded 5. Check reservation region matches resource region 6. Check reservation quantity vs resource count 7. Report: COVERED / PARTIAL / NOT COVERED with evidence
CoverageAnalysis Workflow
Full reservation gap analysis with savings projections for uncovered Azure services.
Prerequisites
- Read
../AzureToolReference.mdfor tool invocation patterns - Read
../ReservationInventory.mdfor SKU matching rules - Read
../PricingComparison.mdfor savings calculation methodology
Steps
1. Identify High-Cost Uncovered Services
Source from either:
- User-provided service list
- Output of ValidateCosts workflow (services marked "NO" coverage)
- Cost Management top-N spenders
2. List Active Reservations
az reservations reservation-order list
az reservations reservation list --reservation-order-id <ORDER_ID>Build complete reservation inventory with SKU, quantity, region, state, term.
3. Check Each Service for Coverage
For each high-cost service:
- Match against reservation inventory using
ReservationInventory.mdrules - Classify: COVERED / PARTIAL / NOT COVERED
- For PARTIAL: explain the gap (wrong SKU, wrong tier, insufficient quantity)
4. Query Azure Advisor Recommendations
mcp__azure__advisor → advisor_recommendation_list
Filter: category = "Cost"Advisor may recommend specific RI purchases — capture these as independent validation.
5. Get PAYG vs RI Pricing
For each uncovered service:
mcp__azure__pricing → pricing_get
Parameters: service_name, sku_name, region, currency="BRL"Calculate savings using formulas from PricingComparison.md.
6. Locate Actual Resources
Verify resources exist and are active to confirm the spend is real:
mcp__azure__compute → compute_vm_list (for VMs)
mcp__azure__sql → sql_server_list (for SQL)
mcp__azure__storage → storage_account_list (for storage)7. Present Prioritized Coverage Report
Output format — prioritized by monthly savings (highest first):
## Reservation Coverage Analysis
| # | Service | Monthly (BRL) | Coverage | Savings (1yr) | Savings (3yr) |
|---|---------|--------------|----------|---------------|---------------|
| 1 | {service} | {amount} | NO | {amount} ({pct}%) | {amount} ({pct}%) |
## Recommended Actions (Priority Order)
1. **{Service}** — {term} RI saves ~BRL {amount}/month. {reasoning}.
2. ...
## Summary
| Metric | Value |
|--------|-------|
| Total unprotected monthly spend | BRL {amount} |
| Estimated monthly savings (full RI) | BRL {amount} |
| Estimated annual savings | BRL {amount} |Output
- Per-service coverage status with pricing evidence
- Prioritized reservation purchase recommendations
- Total savings projection (monthly and annual)
- Advisor recommendations cross-referenced against findings
DraftResponse Workflow
Generate executive stakeholder responses from Azure FinOps analysis results.
Prerequisites
- Analysis must be completed first (ValidateCosts, FindWaste, or CoverageAnalysis)
- Read analysis output from
Plans/directory or current session context
Steps
1. Load Analysis Context
Check for analysis results in order of preference: 1. Current session context (if analysis was just performed) 2. Plans/reservation-coverage-analysis-*.md 3. Plans/response-*-*.md (previous responses for context)
2. Determine Language
| Signal | Language |
|---|---|
| Default | Portuguese (BR) |
| Recipient name is Portuguese/Brazilian | Portuguese (BR) |
| User explicitly says "in English" | English |
| User explicitly says "em portugues" | Portuguese (BR) |
3. Determine Audience Tone
| Audience | Tone | Detail Level |
|---|---|---|
| Executive (Director+) | High-level, focus on impact and savings | Summary table, key findings, next steps |
| Technical (Engineer/Architect) | Detailed, include SKUs and commands | Full breakdown with resource names |
| Finance (Controller/CFO) | Numbers-first, ROI focus | Cost tables, annual projections, recommendations |
4. Structure Response
# Response Template
{Greeting — informal but professional}
{1-2 sentence summary answering the core question}
{Summary table: Service | Monthly Cost | Reservation Status}
{Key findings — 2-4 bullet points}
{Waste findings if applicable — orphaned resources, cleanup opportunity}
{Savings opportunity if applicable — estimated monthly/annual savings}
{Next steps — what you can do or present}
---
## Technical Detail (for internal reference)
{Detailed breakdown for the recipient's team}5. Save Response
Save to: Plans/response-{recipient-firstname}-{subject-slug}.md
Include metadata header:
# Resposta para {Recipient} — {Subject}
**De:** {sender}
**Para:** {recipient full name}
**Data:** {date}
**Assunto:** {subject in recipient's language}Key Principles
- Lead with the answer — don't make the reader hunt for the conclusion
- Use BRL for all amounts — this is the stakeholder's currency
- Include the evidence chain — "validated directly in Azure" builds credibility
- Offer next steps — always close with what you can do next
- Keep executive section under 300 words — detail goes in technical appendix
Output
- Formatted response ready to send/share
- Saved to
Plans/directory for future reference - Technical appendix with full analysis detail
FindWaste Workflow
Discover orphaned and wasted Azure resources across all subscriptions.
Prerequisites
- Read
../AzureToolReference.mdfor Resource Graph query patterns
Steps
1. Query Orphaned Disks
az graph query -q "
Resources
| where type =~ 'microsoft.compute/disks'
| where managedBy == '' or isnull(managedBy)
| project name, resourceGroup, subscriptionId,
diskSizeGB=properties.diskSizeGB,
sku=sku.name, location
" --first 10002. Query Stopped VMs
az graph query -q "
Resources
| where type =~ 'microsoft.compute/virtualMachines'
| where properties.extended.instanceView.powerState.code == 'PowerState/deallocated'
| project name, resourceGroup, subscriptionId,
vmSize=properties.hardwareProfile.vmSize, location
" --first 10003. Query Unassociated Public IPs
az graph query -q "
Resources
| where type =~ 'microsoft.network/publicipaddresses'
| where properties.ipConfiguration == '' or isnull(properties.ipConfiguration)
| project name, resourceGroup, subscriptionId, location
" --first 10004. Categorize by Type and Size
Group discovered waste by:
- Disk type: StandardSSD_LRS, Premium_LRS, Standard_LRS, Premium_ZRS, etc.
- Disk size: Small (<128GB), Medium (128-1024GB), Large (>1024GB)
- Subscription: Group by subscription for ownership attribution
5. Calculate Monthly Waste
For each orphaned resource, estimate cost using:
mcp__azure__pricing → pricing_get
Parameters: service_name, sku_name, regionSum by category and overall.
6. Verify Specific Resources (Optional)
If user asks about specific disks (e.g., "are the P50 disks orphaned?"):
mcp__azure__compute → compute_vm_get
Check managedBy field on specific disks
Cross-reference disk names against VM disk attachments7. Present Waste Report
Output format:
## Orphaned Resources Summary
| Category | Count | Monthly Waste (BRL) | Annual Waste (BRL) |
|----------|-------|--------------------|--------------------|
| Unattached Disks | {n} | {amount} | {amount} |
| Stopped VMs | {n} | {amount} | {amount} |
| Unused Public IPs | {n} | {amount} | {amount} |
| **Total** | | **{total}** | **{total}** |
### Disk Breakdown
| Disk Type | Count | Est. Monthly (BRL) |
|-----------|-------|--------------------|
| StandardSSD_LRS | {n} | {amount} |
| Premium_LRS | {n} | {amount} |Output
- Categorized waste report with BRL amounts
- Specific resource details if requested
- Recommendation: cleanup candidates vs resources to investigate further
ValidateCosts Workflow
Cross-reference billing costs against active reservations to determine PAYG vs RI coverage.
Prerequisites
- Read
../AzureToolReference.mdfor tool invocation patterns - Read
../ReservationInventory.mdfor SKU matching rules
Steps
1. Parse Target Services
Extract the services/SKUs the user wants validated from their request or from Cost Management data.
2. List All Subscriptions
mcp__azure__subscription_list → subscription_listNote all subscription IDs for subsequent queries.
3. List Active Reservation Orders
az reservations reservation-order list \
--query "[].{orderId:name, displayName:displayName, created:createdDateTime}" \
-o table4. Get Reservation Details Per Order
For each reservation order:
az reservations reservation list \
--reservation-order-id <ORDER_ID> \
--query "[].{name:name, sku:sku.name, quantity:quantity, location:location, state:provisioningState, term:properties.term}" \
-o table5. Cross-Reference SKUs
For each target service from step 1:
- Find matching reservation using SKU matching rules from
ReservationInventory.md - Check for exact match, instance size flexibility, and common mismatches
- Check reservation state is
Succeeded - Check region alignment
6. Explain Billing Discrepancies
Common explanations for unexpected costs:
- Partial month: New resource provisioned mid-month — first bill is prorated
- View filter: Cost Management showing "Actual Cost" vs "Amortized Cost" produces different numbers
- Monthly billing RI: Reserved instances with monthly billing look identical to PAYG in cost views
- Renewal batch: Multiple reservation renewals processed on same day create a spending spike
7. Present Coverage Table
Output format:
| # | Service | Monthly (BRL) | RI Coverage | Notes |
|---|---------|--------------|-------------|-------|
| 1 | {service} | {amount} | COVERED / PARTIAL / NO | {explanation} |Output
- Per-service coverage table with evidence
- Explanation of any billing anomalies
- List of services with no reservation coverage (candidates for CoverageAnalysis workflow)