-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Azure pricing skill #859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rahulbats
wants to merge
4
commits into
github:staged
Choose a base branch
from
rahulbats:azure-pricing-plugin
base: staged
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+474
−0
Open
Azure pricing skill #859
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| --- | ||
| name: azure-pricing | ||
| description: 'Fetches real-time Azure retail pricing using the Azure Retail Prices API (prices.azure.com). Use when the user asks about the cost of any Azure service, wants to compare SKU prices, needs pricing data for a cost estimate, or mentions Azure pricing, Azure costs, or Azure billing. Covers compute, storage, networking, databases, AI, and all other Azure service families.' | ||
| compatibility: Requires internet access to prices.azure.com. No authentication needed. | ||
| metadata: | ||
| author: anthonychu | ||
| version: "1.0" | ||
| --- | ||
|
|
||
| # Azure Pricing Skill | ||
|
|
||
| Use this skill to retrieve real-time Azure retail pricing data from the public Azure Retail Prices API. No authentication is required. | ||
|
|
||
| ## When to Use This Skill | ||
|
|
||
| - User asks about the cost of an Azure service (e.g., "How much does a D4s v5 VM cost?") | ||
| - User wants to compare pricing across regions or SKUs | ||
| - User needs a cost estimate for a workload or architecture | ||
| - User mentions Azure pricing, Azure costs, or Azure billing | ||
| - User asks about reserved instance vs. pay-as-you-go pricing | ||
| - User wants to know about savings plans or spot pricing | ||
|
|
||
| ## API Endpoint | ||
|
|
||
| ``` | ||
| GET https://prices.azure.com/api/retail/prices?api-version=2023-01-01-preview | ||
| ``` | ||
|
|
||
| Append `$filter` as a query parameter using OData filter syntax. Always use `api-version=2023-01-01-preview` to ensure savings plan data is included. | ||
|
|
||
| ## Step-by-step Instructions | ||
|
|
||
| If anything is unclear about the user's request, ask clarifying questions to identify the correct filter fields and values before calling the API. | ||
|
|
||
| 1. **Identify filter fields** from the user's request (service name, region, SKU, price type). | ||
| 2. **Resolve the region**: the API requires `armRegionName` values in lowercase with no spaces (e.g. "East US" → `eastus`, "West Europe" → `westeurope`, "Southeast Asia" → `southeastasia`). See [references/REGIONS.md](references/REGIONS.md) for a complete list. | ||
| 3. **Build the filter string** using the fields below and fetch the URL. | ||
| 4. **Parse the `Items` array** from the JSON response. Each item contains price and metadata. | ||
| 5. **Follow pagination** via `NextPageLink` if you need more than the first 1000 results (rarely needed). | ||
| 6. **Calculate cost estimates** using the formulas in [references/COST-ESTIMATOR.md](references/COST-ESTIMATOR.md) to produce monthly/annual estimates. | ||
| 7. **Present results** in a clear summary table with service, SKU, region, unit price, and monthly/annual estimates. | ||
|
|
||
| ## Filterable Fields | ||
|
|
||
| | Field | Type | Example | | ||
| |---|---|---| | ||
| | `serviceName` | string (exact, case-sensitive) | `'Azure Functions'`, `'Virtual Machines'`, `'Azure Blob Storage'` | | ||
| | `serviceFamily` | string (exact, case-sensitive) | `'Compute'`, `'Storage'`, `'Databases'`, `'AI + Machine Learning'` | | ||
| | `armRegionName` | string (exact, lowercase) | `'eastus'`, `'westeurope'`, `'southeastasia'` | | ||
| | `armSkuName` | string (exact) | `'Standard_D4s_v5'`, `'Standard_LRS'` | | ||
| | `skuName` | string (contains supported) | `'D4s v5'` | | ||
| | `priceType` | string | `'Consumption'`, `'Reservation'`, `'DevTestConsumption'` | | ||
| | `meterName` | string (contains supported) | `'Spot'` | | ||
|
|
||
| Use `eq` for equality, `and` to combine, and `contains(field, 'value')` for partial matches. | ||
|
|
||
| ## Example Filter Strings | ||
|
|
||
| ``` | ||
| # All consumption prices for Functions in East US | ||
| serviceName eq 'Functions' and armRegionName eq 'eastus' and priceType eq 'Consumption' | ||
| # D4s v5 VMs in West Europe (consumption only) | ||
| armSkuName eq 'Standard_D4s_v5' and armRegionName eq 'westeurope' and priceType eq 'Consumption' | ||
| # All storage prices in a region | ||
| serviceName eq 'Storage' and armRegionName eq 'eastus' | ||
| # Spot pricing for a specific SKU | ||
| armSkuName eq 'Standard_D4s_v5' and contains(meterName, 'Spot') and armRegionName eq 'eastus' | ||
| # 1-year reservation pricing | ||
| serviceName eq 'Virtual Machines' and priceType eq 'Reservation' and armRegionName eq 'eastus' | ||
| # Azure AI / OpenAI pricing (now under Foundry Models) | ||
| serviceName eq 'Foundry Models' and armRegionName eq 'eastus' and priceType eq 'Consumption' | ||
| # Azure Cosmos DB pricing | ||
| serviceName eq 'Azure Cosmos DB' and armRegionName eq 'eastus' and priceType eq 'Consumption' | ||
| ``` | ||
|
|
||
| ## Full Example Fetch URL | ||
|
|
||
| ``` | ||
| https://prices.azure.com/api/retail/prices?api-version=2023-01-01-preview&$filter=serviceName eq 'Functions' and armRegionName eq 'eastus' and priceType eq 'Consumption' | ||
| ``` | ||
|
|
||
| URL-encode spaces as `%20` and quotes as `%27` when constructing the URL. | ||
|
|
||
| ## Key Response Fields | ||
|
|
||
| ```json | ||
| { | ||
| "Items": [ | ||
| { | ||
| "retailPrice": 0.000016, | ||
| "unitPrice": 0.000016, | ||
| "currencyCode": "USD", | ||
| "unitOfMeasure": "1 Execution", | ||
| "serviceName": "Functions", | ||
| "skuName": "Premium", | ||
| "armRegionName": "eastus", | ||
| "meterName": "vCPU Duration", | ||
| "productName": "Functions", | ||
| "priceType": "Consumption", | ||
| "isPrimaryMeterRegion": true, | ||
| "savingsPlan": [ | ||
| { "unitPrice": 0.000012, "term": "1 Year" }, | ||
| { "unitPrice": 0.000010, "term": "3 Years" } | ||
| ] | ||
| } | ||
| ], | ||
| "NextPageLink": null, | ||
| "Count": 1 | ||
| } | ||
| ``` | ||
|
|
||
| Only use items where `isPrimaryMeterRegion` is `true` unless the user specifically asks for non-primary meters. | ||
|
|
||
| ## Supported serviceFamily Values | ||
|
|
||
| `Analytics`, `Compute`, `Containers`, `Data`, `Databases`, `Developer Tools`, `Integration`, `Internet of Things`, `Management and Governance`, `Networking`, `Security`, `Storage`, `Web`, `AI + Machine Learning` | ||
|
|
||
| ## Tips | ||
|
|
||
| - `serviceName` values are case-sensitive. When unsure, filter by `serviceFamily` first to discover valid `serviceName` values in the results. | ||
| - If results are empty, try broadening the filter (e.g., remove `priceType` or region constraints first). | ||
| - Prices are always in USD unless `currencyCode` is specified in the request. | ||
| - For savings plan prices, look for the `savingsPlan` array on each item (only in `2023-01-01-preview`). | ||
| - See [references/SERVICE-NAMES.md](references/SERVICE-NAMES.md) for a catalog of common service names and their correct casing. | ||
| - See [references/COST-ESTIMATOR.md](references/COST-ESTIMATOR.md) for cost estimation formulas and patterns. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| | Issue | Solution | | ||
| |-------|----------| | ||
| | Empty results | Broaden the filter — remove `priceType` or `armRegionName` first | | ||
| | Wrong service name | Use `serviceFamily` filter to discover valid `serviceName` values | | ||
| | Missing savings plan data | Ensure `api-version=2023-01-01-preview` is in the URL | | ||
| | URL errors | Check URL encoding — spaces as `%20`, quotes as `%27` | | ||
| | Too many results | Add more filter fields (region, SKU, priceType) to narrow down | | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| # Cost Estimator Reference | ||
|
|
||
| Formulas and patterns for converting Azure unit prices into monthly and annual cost estimates. | ||
|
|
||
| ## Standard Time-Based Calculations | ||
|
|
||
| ### Hours per Month | ||
|
|
||
| Azure uses **730 hours/month** as the standard billing period (365 days × 24 hours / 12 months). | ||
|
|
||
| ``` | ||
| Monthly Cost = Unit Price per Hour × 730 | ||
| Annual Cost = Monthly Cost × 12 | ||
| ``` | ||
|
|
||
| ### Common Multipliers | ||
|
|
||
| | Period | Hours | Calculation | | ||
| |--------|-------|-------------| | ||
| | 1 Hour | 1 | Unit price | | ||
| | 1 Day | 24 | Unit price × 24 | | ||
| | 1 Week | 168 | Unit price × 168 | | ||
| | 1 Month | 730 | Unit price × 730 | | ||
| | 1 Year | 8,760 | Unit price × 8,760 | | ||
|
|
||
| ## Service-Specific Formulas | ||
|
|
||
| ### Virtual Machines (Compute) | ||
|
|
||
| ``` | ||
| Monthly Cost = hourly price × 730 | ||
| ``` | ||
|
|
||
| For VMs that run only business hours (8h/day, 22 days/month): | ||
| ``` | ||
| Monthly Cost = hourly price × 176 | ||
| ``` | ||
|
|
||
| ### Azure Functions | ||
|
|
||
| ``` | ||
| Execution Cost = price per execution × number of executions | ||
| Compute Cost = price per GB-s × (memory in GB × execution time in seconds × number of executions) | ||
| Total Monthly = Execution Cost + Compute Cost | ||
| ``` | ||
|
|
||
| Free grant: 1M executions and 400,000 GB-s per month. | ||
|
|
||
| ### Azure Blob Storage | ||
|
|
||
| ``` | ||
| Storage Cost = price per GB × storage in GB | ||
| Transaction Cost = price per 10,000 ops × (operations / 10,000) | ||
| Egress Cost = price per GB × egress in GB | ||
| Total Monthly = Storage Cost + Transaction Cost + Egress Cost | ||
| ``` | ||
|
|
||
| ### Azure Cosmos DB | ||
|
|
||
| #### Provisioned Throughput | ||
| ``` | ||
| Monthly Cost = (RU/s / 100) × price per 100 RU/s × 730 | ||
| ``` | ||
|
|
||
| #### Serverless | ||
| ``` | ||
| Monthly Cost = (total RUs consumed / 1,000,000) × price per 1M RUs | ||
| ``` | ||
|
|
||
| ### Azure SQL Database | ||
|
|
||
| #### DTU Model | ||
| ``` | ||
| Monthly Cost = price per DTU × DTUs × 730 | ||
| ``` | ||
|
|
||
| #### vCore Model | ||
| ``` | ||
| Monthly Cost = vCore price × vCores × 730 + storage price per GB × storage GB | ||
| ``` | ||
|
|
||
| ### Azure Kubernetes Service (AKS) | ||
|
|
||
| ``` | ||
| Monthly Cost = node VM price × 730 × number of nodes | ||
| ``` | ||
|
|
||
| Control plane is free for standard tier. | ||
|
|
||
| ### Azure App Service | ||
|
|
||
| ``` | ||
| Monthly Cost = plan price × 730 (for hourly-priced plans) | ||
| ``` | ||
|
|
||
| Or flat monthly price for fixed-tier plans. | ||
|
|
||
| ### Azure OpenAI | ||
|
|
||
| ``` | ||
| Monthly Cost = (input tokens / 1000) × input price per 1K tokens | ||
| + (output tokens / 1000) × output price per 1K tokens | ||
| ``` | ||
|
|
||
| ## Reservation vs. Pay-As-You-Go Comparison | ||
|
|
||
| When presenting pricing options, always show the comparison: | ||
|
|
||
| ``` | ||
| | Pricing Model | Monthly Cost | Annual Cost | Savings vs. PAYG | | ||
| |---------------|-------------|-------------|------------------| | ||
| | Pay-As-You-Go | $X | $Y | — | | ||
| | 1-Year Reserved | $A | $B | Z% | | ||
| | 3-Year Reserved | $C | $D | W% | | ||
| | Savings Plan (1yr) | $E | $F | V% | | ||
| | Savings Plan (3yr) | $G | $H | U% | | ||
| | Spot (if available) | $I | N/A | T% | | ||
| ``` | ||
|
|
||
| Savings percentage formula: | ||
| ``` | ||
| Savings % = ((PAYG Price - Reserved Price) / PAYG Price) × 100 | ||
| ``` | ||
|
|
||
| ## Cost Summary Table Template | ||
|
|
||
| Always present results in this format: | ||
|
|
||
| ```markdown | ||
| | Service | SKU | Region | Unit Price | Unit | Monthly Est. | Annual Est. | | ||
| |---------|-----|--------|-----------|------|-------------|-------------| | ||
| | Virtual Machines | Standard_D4s_v5 | East US | $0.192/hr | 1 Hour | $140.16 | $1,681.92 | | ||
| ``` | ||
|
|
||
| ## Tips | ||
|
|
||
| - Always clarify the **usage pattern** before estimating (24/7 vs. business hours vs. sporadic). | ||
| - For **storage**, ask about expected data volume and access patterns. | ||
| - For **databases**, ask about throughput requirements (RU/s, DTUs, or vCores). | ||
| - For **serverless** services, ask about expected invocation count and duration. | ||
| - Round to 2 decimal places for display. | ||
| - Note that prices are in **USD** unless otherwise specified. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # Azure Region Names Reference | ||
|
|
||
| The Azure Retail Prices API requires `armRegionName` values in lowercase with no spaces. Use this table to map common region names to their API values. | ||
|
|
||
| ## Region Mapping | ||
|
|
||
| | Display Name | armRegionName | | ||
| |-------------|---------------| | ||
| | East US | `eastus` | | ||
| | East US 2 | `eastus2` | | ||
| | Central US | `centralus` | | ||
| | North Central US | `northcentralus` | | ||
| | South Central US | `southcentralus` | | ||
| | West Central US | `westcentralus` | | ||
| | West US | `westus` | | ||
| | West US 2 | `westus2` | | ||
| | West US 3 | `westus3` | | ||
| | Canada Central | `canadacentral` | | ||
| | Canada East | `canadaeast` | | ||
| | Brazil South | `brazilsouth` | | ||
| | North Europe | `northeurope` | | ||
| | West Europe | `westeurope` | | ||
| | UK South | `uksouth` | | ||
| | UK West | `ukwest` | | ||
| | France Central | `francecentral` | | ||
| | France South | `francesouth` | | ||
| | Germany West Central | `germanywestcentral` | | ||
| | Germany North | `germanynorth` | | ||
| | Switzerland North | `switzerlandnorth` | | ||
| | Switzerland West | `switzerlandwest` | | ||
| | Norway East | `norwayeast` | | ||
| | Norway West | `norwaywest` | | ||
| | Sweden Central | `swedencentral` | | ||
| | Italy North | `italynorth` | | ||
| | Poland Central | `polandcentral` | | ||
| | Spain Central | `spaincentral` | | ||
| | East Asia | `eastasia` | | ||
| | Southeast Asia | `southeastasia` | | ||
| | Japan East | `japaneast` | | ||
| | Japan West | `japanwest` | | ||
| | Australia East | `australiaeast` | | ||
| | Australia Southeast | `australiasoutheast` | | ||
| | Australia Central | `australiacentral` | | ||
| | Korea Central | `koreacentral` | | ||
| | Korea South | `koreasouth` | | ||
| | Central India | `centralindia` | | ||
| | South India | `southindia` | | ||
| | West India | `westindia` | | ||
| | UAE North | `uaenorth` | | ||
| | UAE Central | `uaecentral` | | ||
| | South Africa North | `southafricanorth` | | ||
| | South Africa West | `southafricawest` | | ||
| | Qatar Central | `qatarcentral` | | ||
|
|
||
| ## Conversion Rules | ||
|
|
||
| 1. Remove all spaces | ||
| 2. Convert to lowercase | ||
| 3. Examples: | ||
| - "East US" → `eastus` | ||
| - "West Europe" → `westeurope` | ||
| - "Southeast Asia" → `southeastasia` | ||
| - "South Central US" → `southcentralus` | ||
|
|
||
| ## Common Aliases | ||
|
|
||
| Users may refer to regions informally. Map these to the correct `armRegionName`: | ||
|
|
||
| | User Says | Maps To | | ||
| |-----------|---------| | ||
| | "US East", "Virginia" | `eastus` | | ||
| | "US West", "California" | `westus` | | ||
| | "Europe", "EU" | `westeurope` (default) | | ||
| | "UK", "London" | `uksouth` | | ||
| | "Asia", "Singapore" | `southeastasia` | | ||
| | "Japan", "Tokyo" | `japaneast` | | ||
| | "Australia", "Sydney" | `australiaeast` | | ||
| | "India", "Mumbai" | `centralindia` | | ||
| | "Korea", "Seoul" | `koreacentral` | | ||
| | "Brazil", "São Paulo" | `brazilsouth` | | ||
| | "Canada", "Toronto" | `canadacentral` | | ||
| | "Germany", "Frankfurt" | `germanywestcentral` | | ||
| | "France", "Paris" | `francecentral` | | ||
| | "Sweden", "Stockholm" | `swedencentral` | |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
serviceNameexamples here don’t match the values used elsewhere in this skill and inreferences/SERVICE-NAMES.md. For example, Azure Functions is shown as'Azure Functions'but the reference (and your example filters below) use'Functions', and Blob Storage is under theStorageservice (serviceName eq 'Storage') rather than'Azure Blob Storage'. Updating these examples will prevent users from building filters that return empty results.