Azure SKU scout — explore availability zones, capacity, pricing, and plan VM deployments across subscriptions
Project description
Azure Scout: az-scout
Scout Azure regions for VM availability, zone mappings, pricing, spot scores, and quota — then plan deployments with confidence.
az-scout helps you compare how Azure maps logical Availability Zones to physical zones across subscriptions, evaluate SKU capacity and pricing, and generate deterministic deployment plans — all from a single web UI or MCP-powered AI agent.
Features
- Logical-to-physical zone mapping – visualise how Azure maps logical Availability Zones (Zone 1, Zone 2, Zone 3) to physical zones (e.g., eastus-az1, eastus-az2) across subscriptions in a region.
- SKU availability view – shows VM SKU availability per physical zone with vCPU quota usage (limit / used / remaining), numeric operator filters, and CSV export.
- Spot Placement Scores – evaluate the likelihood of Spot VM allocation (High / Medium / Low) per SKU for a given region and instance count, powered by the Azure Compute RP.
- Deployment Confidence Score – a composite 0–100 score per SKU estimating deployment success probability, synthesised from quota headroom, Spot Placement Score, availability zone breadth, restrictions, and price pressure signals. Missing signals are automatically excluded with weight renormalisation. The score updates live when Spot Placement Scores arrive.
- Deployment Plan – agent-ready
POST /api/deployment-planendpoint that evaluates (region, SKU) combinations against zones, quotas, spot scores, pricing, and restrictions. Returns a deterministic, ranked plan with business and technical views (no LLM, no invention — missing data is flagged explicitly). - Capacity Strategy Advisor – a multi-region strategy recommendation engine that goes beyond single-region planning. Given a workload profile (instances, constraints, statefulness, latency sensitivity, budget), it evaluates candidate regions against zones, quotas, restrictions, spot scores, pricing, confidence and inter-region latency to recommend a deployment strategy:
single_region,active_active,active_passive,sharded_multi_region,burst_overflow,time_window_deploy, orprogressive_ramp. Includes business justification, technical allocations, latency matrix, and warnings. No LLM — all decisions are deterministic and traceable. - AI Chat Assistant (optional) – interactive chat panel powered by Azure OpenAI with streaming responses, tool calling (zones, SKUs, pricing, spot scores), and markdown rendering. Supports pin-to-side mode, conversation persistence, input history, clickable choice chips, and error retry. Requires Azure OpenAI environment variables (see below).
- MCP server – expose all capabilities as MCP tools for AI agents (see below).
- Plugin system – extend az-scout with pip-installable plugins (API routes, MCP tools, UI tabs, chat modes). See docs/plugins.md.
Quick start
Prerequisites
| Requirement | Details |
|---|---|
| Python | ≥ 3.11 |
| Azure credentials | Any method supported by DefaultAzureCredential (az login, managed identity, …) |
| RBAC | Reader on the subscriptions you want to query, Virtual Machine Contributor on the subscriptions for Spot Placement Scores retrieval |
| Azure OpenAI (optional) | For the AI Chat Assistant: set AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, AZURE_OPENAI_DEPLOYMENT, and optionally AZURE_OPENAI_API_VERSION |
Run locally with uv tool (recommended)
# Make sure you are authenticated to Azure
az login
# Run the tool (no install required)
uvx az-scout
Your browser opens automatically at http://127.0.0.1:5001.
Installation options
Recommended: install with uv
uv install az-scout
uvx az-scout
Alternative: install with pip
pip install az-scout
az-scout
Docker
docker run --rm -p 8000:8000 \
-e AZURE_TENANT_ID=<your-tenant> \
-e AZURE_CLIENT_ID=<your-sp-client-id> \
-e AZURE_CLIENT_SECRET=<your-sp-secret> \
ghcr.io/lrivallain/az-scout:latest
Dev Container
The repository includes a Dev Container configuration for a one-click development environment with all tools pre-installed.
Prerequisites
- Docker running locally
- VS Code with the Dev Containers extension
Getting started
-
Clone the repository and open it in VS Code.
-
When prompted, click "Reopen in Container" — or run the command Dev Containers: Reopen in Container from the Command Palette (
Ctrl+Shift+P). -
Wait for the container to build and dependencies to install (first time only).
-
Start the server:
# Via VS Code task (Terminal → Run Task → "Backend: run") # Or from the terminal: uv run az-scout web --host 0.0.0.0 --port 5001 --reload --no-open -v
-
Open http://localhost:5001 in your browser.
What's included
| Category | Details |
|---|---|
| Python | 3.12 + uv package manager |
| System tools | git, curl, jq, make, unzip, ripgrep |
| Azure CLI | Pre-installed via devcontainer feature |
| VS Code extensions | Python, Pylance, Ruff, Docker, Azure, GitLens, Copilot |
| Tasks | Backend: run, Backend: test, Backend: lint, Dev: run all checks |
Note: Azure authentication is not required to build or run tests. Use
az logininside the container when you need to query live Azure data.
Azure Container App
It is also possible to deploy az-scout as a web app in Azure using the provided Bicep template (see Deploy to Azure section below).
Note: The web UI is designed for local use and may not be suitable for public-facing deployment without additional security measures (authentication, network restrictions, etc.). The MCP server can be exposed over the public internet if needed, but ensure you have proper authentication and authorization in place to protect access to Azure data.
UI guided deployment
A Bicep template is provided to deploy az-scout as an Azure Container App with a managed identity. You can use the Deploy to Azure button above for a portal-guided experience, or use the CLI commands below.
Bicep deploy from CLI
# Create a resource group
az group create -n rg-az-scout -l <your-region>
# Deploy (replace subscription IDs with your own)
az deployment group create \
-g rg-az-scout \
-f deploy/main.bicep \
-p readerSubscriptionIds='["SUB_ID_1","SUB_ID_2"]'
See deploy/main.example.bicepparam for all available parameters.
Resources created
The deployment creates:
| Resource | Purpose |
|---|---|
| Container App | Runs ghcr.io/lrivallain/az-scout |
| Managed Identity | Reader role on target subscriptions |
| VM Contributor | Virtual Machine Contributor role for Spot Placement Scores (enabled by default) |
| Log Analytics | Container logs and diagnostics |
| Container Apps Env | Hosting environment |
Note: The
Virtual Machine Contributorrole is required for querying Spot Placement Scores (POST endpoint). SetenableSpotScoreRole=falseto skip this if you don't need spot scores or prefer to manage permissions manually.
Enable Entra ID authentication (EasyAuth)
For a complete walkthrough (App Registration creation, client secret, user assignment, troubleshooting), see deploy/EASYAUTH.md.
Usage
CLI options
az-scout [COMMAND] [OPTIONS]
az-scout --help. # show global help
az-scout web --help # show web subcommand help
az-scout mcp --help # show mcp subcommand help
az-scout --version # show version
az-scout web (default)
Run the web UI. This is the default when no subcommand is given.
--host TEXT Host to bind to. [default: 127.0.0.1]
--port INTEGER Port to listen on. [default: 5001]
--no-open Don't open the browser automatically.
-v, --verbose Enable verbose logging.
--reload Auto-reload on code changes (development only).
--help Show this message and exit.
az-scout mcp
Run the MCP server.
--http Use Streamable HTTP transport instead of stdio.
--port INTEGER Port for Streamable HTTP transport. [default: 8080]
-v, --verbose Enable verbose logging.
--help Show this message and exit.
MCP server
An MCP server is included, allowing AI agents (Claude Desktop, VS Code Copilot, etc.) to query zone mappings and SKU availability directly.
Available tools
| Tool | Description |
|---|---|
list_tenants |
Discover Azure AD tenants and authentication status |
list_subscriptions |
List enabled subscriptions (optionally scoped to a tenant) |
list_regions |
List regions that support Availability Zones |
get_zone_mappings |
Get logical→physical zone mappings for subscriptions in a region |
get_sku_availability |
Get VM SKU availability per zone with restrictions, capabilities, and vCPU quota per family |
get_spot_scores |
Get Spot Placement Scores (High / Medium / Low) for a list of VM sizes in a region |
get_sku_pricing_detail |
Get detailed Linux pricing (PayGo, Spot, RI 1Y/3Y, SP 1Y/3Y) and VM profile for a single SKU |
capacity_strategy |
Compute a deterministic multi-region deployment strategy based on capacity signals and latency |
region_latency |
Return indicative RTT latency between two Azure regions (Microsoft published statistics) |
get_sku_availability supports optional filters to reduce output size:
name, family, min_vcpus, max_vcpus, min_memory_gb, max_memory_gb.
stdio transport (default – for Claude Desktop, VS Code, etc.)
az-scout mcp
Add to your MCP client configuration:
{
"mcpServers": {
"az-scout": {
"command": "az-scout",
"args": ["mcp"]
}
}
}
If using uv:
{
"mcpServers": {
"az-scout": {
"command": "uvx",
"args": ["az-scout", "mcp"]
}
}
}
Streamable HTTP transport
When running in web mode, the MCP server is automatically available at /mcp for integration with web-based clients or when running as a hosted deployment (Container App, etc.).
For MCP-only use with Streamable HTTP transport, run:
az-scout mcp --http --port 8082
Add to your MCP client configuration:
{
"mcpServers": {
"az-scout": {
"url": "http://localhost:8082/mcp" // or "https://<your-app-url>/mcp" for web command
}
}
}
Hosted deployment: When running as a Container App (or any hosted web server), the MCP endpoint is automatically available at
/mcpalongside the web UI — no separate server needed. Point your MCP client tohttps://<your-app-url>/mcp.EasyAuth: If your Container App has EasyAuth enabled, MCP clients must pass a bearer token in the
Authorizationheader. See the EasyAuth guide for detailed instructions.
API
API documentation is available at /docs (Swagger UI) and /redoc (ReDoc) when the server is running.
Deployment Plan API
The POST /api/deployment-plan endpoint provides a deterministic decision engine for deployment planning. It is designed for Sales / Solution Engineers and AI agents: no LLM is involved — every decision traces back to real Azure data.
Request
{
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"regionConstraints": {
"allowRegions": ["francecentral", "westeurope"],
"dataResidency": "EU"
},
"skuConstraints": {
"preferredSkus": ["Standard_D2s_v3", "Standard_E8s_v4"],
"requireZonal": true
},
"scale": { "instanceCount": 4 },
"pricing": {
"currencyCode": "EUR",
"preferSpot": true,
"maxHourlyBudget": 2.0
},
"timing": { "urgency": "now" }
}
Response (abbreviated)
{
"summary": {
"recommendedRegion": "francecentral",
"recommendedSku": "Standard_D2s_v3",
"recommendedMode": "zonal",
"riskLevel": "low",
"confidenceScore": 85
},
"businessView": {
"keyMessage": "Standard_D2s_v3 in francecentral is recommended ...",
"reasons": ["Available in 3 availability zone(s).", "Sufficient quota ..."],
"risks": [],
"mitigations": [],
"alternatives": [{ "region": "westeurope", "sku": "Standard_E8s_v4", "reason": "..." }]
},
"technicalView": {
"evaluation": { "regionsEvaluated": ["francecentral", "westeurope"], "perRegionResults": [] },
"dataProvenance": { "evaluatedAt": "...", "cacheTtl": {}, "apiVersions": {} }
},
"warnings": ["Spot placement score is probabilistic and not a guarantee."],
"errors": []
}
Note: Spot placement scores are probabilistic and not a guarantee of allocation. Quota values are dynamic and may change between planning and actual deployment.
Capacity Strategy Advisor API
The POST /api/capacity-strategy endpoint is a multi-region strategy recommendation engine. It evaluates candidate (region, SKU) combinations against zones, quotas, restrictions, spot scores, pricing, deployment confidence, and inter-region latency to recommend a deployment strategy. No LLM — every decision is deterministic and traceable.
Latency data source
Inter-region RTT values come from Microsoft published network latency statistics. These are indicative and must be validated with in-tenant measurements (e.g. Azure Connection Monitor).
Request
{
"workloadName": "inference-cluster",
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"scale": {
"sku": "Standard_NC24ads_A100_v4",
"instanceCount": 48,
"gpuCountTotal": 48
},
"constraints": {
"dataResidency": "EU",
"requireZonal": true,
"maxInterRegionRttMs": 50
},
"usage": {
"statefulness": "stateless",
"crossRegionTraffic": "medium",
"latencySensitivity": "high"
},
"pricing": {
"currencyCode": "EUR",
"preferSpot": true,
"maxHourlyBudget": 100.0
},
"timing": {
"deploymentUrgency": "this_week"
}
}
Response (abbreviated)
{
"summary": {
"workloadName": "inference-cluster",
"strategy": "sharded_multi_region",
"totalInstances": 48,
"regionCount": 3,
"estimatedHourlyCost": 82.56,
"currency": "EUR",
"overallConfidence": 72,
"overallConfidenceLabel": "Medium"
},
"businessView": {
"keyMessage": "Recommended strategy: Sharded multi-region ...",
"justification": ["Insufficient quota in any single region; ..."],
"risks": ["Quota is insufficient or low in some regions."],
"mitigations": ["Request quota increase via Azure portal."]
},
"technicalView": {
"allocations": [
{
"region": "swedencentral",
"role": "primary",
"sku": "Standard_NC24ads_A100_v4",
"instanceCount": 20,
"zones": ["1", "2", "3"],
"confidenceScore": 78
}
],
"latencyMatrix": {
"swedencentral": { "swedencentral": 0, "westeurope": 29, "francecentral": 32 }
},
"evaluatedAt": "2025-01-15T14:30:00+00:00"
},
"warnings": ["Spot placement score is probabilistic and not a guarantee."],
"missingInputs": [],
"errors": [],
"disclaimer": "This tool is not affiliated with Microsoft. ..."
}
Strategy types
| Strategy | When selected |
|---|---|
single_region |
Enough capacity in one region, or only one candidate available |
active_active |
Stateless workload with multi-region benefit |
active_passive |
Stateful workload requiring a failover region |
sharded_multi_region |
Quota insufficient in any single region — instances split across regions |
progressive_ramp |
Partial quota available — start in primary, overflow to secondary |
time_window_deploy |
Spot preference but current spot score is low — wait for better window |
burst_overflow |
Burst-capable workload with a dedicated overflow region |
Agent usage examples
Via the MCP capacity_strategy tool:
- "Deploy 48 GPUs across EU regions with max 50ms latency"
- "Multi-region inference architecture for Standard_NC24ads_A100_v4 with spot pricing"
- "Active/passive failover for stateful workload in France with EUR budget cap"
Under the hood
The backend calls the Azure Resource Manager REST API to fetch:
- Zone mappings:
availabilityZoneMappingsfrom/subscriptions/{id}/locationsendpoint - Resource SKUs: SKU details from
/subscriptions/{id}/providers/Microsoft.Compute/skusendpoint with zone restrictions and capabilities - Compute Usages: vCPU quota per VM family from
/subscriptions/{id}/providers/Microsoft.Compute/locations/{region}/usagesendpoint (cached for 10 minutes, with retry on throttling and graceful handling of 403) - Spot Placement Scores: likelihood indicators for Spot VM allocation from
/subscriptions/{id}/providers/Microsoft.Compute/locations/{region}/placementScores/spot/generateendpoint (batched in chunks of 100, sequential execution with retry/back-off, cached for 10 minutes). Note: these scores reflect the probability of obtaining a Spot VM allocation, not datacenter capacity.
Deployment Confidence Score
The Deployment Confidence Score is a heuristic 0–100 estimate of how likely a VM SKU deployment is to succeed in a given region/subscription. It is computed exclusively on the backend by the canonical module src/az_scout/scoring/deployment_confidence.py — the frontend displays what the API returns and never recomputes locally.
Scoring version
The current scoring version is v1 (SCORING_VERSION = "v1"). Every API response includes a scoringVersion field. Bump the version when weights or normalisation rules change.
Signals & weights
| Signal | Weight | Source | Normalisation |
|---|---|---|---|
quota |
0.25 | Compute Usages API | remaining_vcpus / vcpus_per_vm / 10, capped at 1.0 |
spot |
0.35 | Spot Placement Scores API | High → 1.0, Medium → 0.6, Low → 0.25 |
zones |
0.15 | Resource SKUs API | available_zones / 3, capped at 1.0 |
restrictions |
0.15 | Resource SKUs API | No restrictions → 1.0, any → 0.0 |
pricePressure |
0.10 | Retail Prices API | (0.8 − spot/paygo) / 0.6, clamped 0–1 |
Missing signals & renormalisation
When a signal is unavailable (e.g. Spot score not fetched), it is excluded and the remaining weights are renormalised so they sum to 1.0. If fewer than 2 signals are available, the result is label="Unknown", score=0.
Label mapping
| Threshold | Label |
|---|---|
| ≥ 80 | High |
| ≥ 60 | Medium |
| ≥ 40 | Low |
| < 40 | Very Low |
Disclaimers
Every result includes these disclaimers:
- This is a heuristic estimate, not a guarantee of deployment success.
- Signals are derived from Azure APIs and may change at any time.
- No Microsoft guarantee is expressed or implied.
Bulk endpoint
POST /api/deployment-confidence accepts a list of SKU names and returns canonical confidence results for each. The frontend calls this endpoint after spot-score updates to refresh displayed scores.
License
Disclaimer
This tool is not affiliated with Microsoft. All capacity, pricing, and latency information are indicative and not a guarantee of deployment success. Spot placement scores are probabilistic. Quota values and pricing are dynamic and may change between planning and actual deployment. Latency values are based on Microsoft published statistics and must be validated with in-tenant measurements.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file az_scout-2026.2.8.tar.gz.
File metadata
- Download URL: az_scout-2026.2.8.tar.gz
- Upload date:
- Size: 298.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4fbf1d9eef44f133fcde5305559683a473b2b74afd8060849ad99b46d902f974
|
|
| MD5 |
512625764aeb4581361931a3336cfb23
|
|
| BLAKE2b-256 |
737f39013c97bc93a783c977bcdbdf9d9392c862a27e4ebe44f5617a131ef81c
|
Provenance
The following attestation bundles were made for az_scout-2026.2.8.tar.gz:
Publisher:
publish.yml on lrivallain/az-scout
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
az_scout-2026.2.8.tar.gz -
Subject digest:
4fbf1d9eef44f133fcde5305559683a473b2b74afd8060849ad99b46d902f974 - Sigstore transparency entry: 1004843196
- Sigstore integration time:
-
Permalink:
lrivallain/az-scout@be5dc59c6cd74947150212d0ec3eb1e487220005 -
Branch / Tag:
refs/tags/v2026.2.8 - Owner: https://github.com/lrivallain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@be5dc59c6cd74947150212d0ec3eb1e487220005 -
Trigger Event:
push
-
Statement type:
File details
Details for the file az_scout-2026.2.8-py3-none-any.whl.
File metadata
- Download URL: az_scout-2026.2.8-py3-none-any.whl
- Upload date:
- Size: 148.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4b4fc36619c3f2a38a319294c36a7dbde02b671d10db4c04803b3782e4cbd94
|
|
| MD5 |
62e9dfdaa17daf431f62e688dff0bae2
|
|
| BLAKE2b-256 |
70f56b79a96882de848bd48d65eba016abd14ae1d33c7a9ab8fef82a016caf74
|
Provenance
The following attestation bundles were made for az_scout-2026.2.8-py3-none-any.whl:
Publisher:
publish.yml on lrivallain/az-scout
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
az_scout-2026.2.8-py3-none-any.whl -
Subject digest:
a4b4fc36619c3f2a38a319294c36a7dbde02b671d10db4c04803b3782e4cbd94 - Sigstore transparency entry: 1004843198
- Sigstore integration time:
-
Permalink:
lrivallain/az-scout@be5dc59c6cd74947150212d0ec3eb1e487220005 -
Branch / Tag:
refs/tags/v2026.2.8 - Owner: https://github.com/lrivallain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@be5dc59c6cd74947150212d0ec3eb1e487220005 -
Trigger Event:
push
-
Statement type: