Releases: microsoft/capacity-toolkit
Releases · microsoft/capacity-toolkit
Release list
v0.2.0
Added
- Continuous integration (
.github/workflows/ci.yml) — runs on every push and pull
request tomain: parses every script under Windows PowerShell 5.1 (the toolkit's
compatibility target), scans for PowerShell 7-only syntax, and runs PSScriptAnalyzer
against a checked-inPSScriptAnalyzerSettings.psd1. The build fails on any parse error
or Error-severity finding; Warnings are surfaced as annotations for triage. - Subscription / RG structural-limit visibility (
Get-SubscriptionLimits.ps1) — a read-only
collector for ARM control-plane limits that silently block deployments but are not capacity
quotas. It counts live objects via Azure Resource Graph and the ARM control plane and compares
each against the documented limit on Microsoft Learn: resource groups per subscription (vs 980),
tags applied to the subscription (vs 50), and resources per resource group per type (vs 800,
near/at-limit rows only). Opt-in switches add tags-per-resource density (-IncludeTagDensity,
vs 50), subscription deployment history per location and distinct deployment locations
(-IncludeDeploymentHistory, vs 800 / 10), role assignments at/below the subscription scope
(-IncludeRoleAssignments, vs the fixed 4000), and an Informational resources-per-region
inventory (-IncludeRegionInventory). Every row carriesLimitSource=MicrosoftLearnDocumented,
IsTrueQuota=Falseand aDocReferenceto the exact Learn article — these are documented ARM
constants, not adjustable capacity quotas, and they do not feed the compute-only quota-groups
feature. Reader-only. Resolves #16. - PaaS quota visibility (
Get-PaasQuota.ps1) — a read-only collector for the data-PaaS tier.
Azure SQL is reported as true quota from theMicrosoft.Sqlusage APIs: subscription/region
counters (ServerQuota,VCoreQuota,RegionalVCoreQuotaForSQLDBAndDW, Managed Instance vCore
quotas, etc.) and per-logical-server DTU quota (server_dtu_quota), each emitted generically with
used / limit / available /PctUsedandOK/NearLimit/AtLimitflags; free-tier /
promotional countdown counters (*Free*,*DaysLeft) are classifiedInformationalso a healthy
"full" countdown is not mistaken for exhaustion. Cosmos DB has no verified subscription/region
RU/s quota API, so it is reported honestly as inventory: the per-account configured
totalThroughputLimit(a real limit only when positive) and, optionally
(-IncludeCosmosThroughputInventory), provisioned RU/s per SQL-API database and container, all
flaggedIsInformational. Scope via-Service AzureSQL|CosmosDB|All; supports-Location,
-AllLocationsand the standard subscription selectors. Does not feed the compute-only
quota-groups feature. Reader-only. Resolves #15. - Storage quota visibility (
Get-StorageQuota.ps1) — a read-only collector that reports the
per-subscription, per-region storage-account count quota (the data behind
az storage account show-usage, default limit 250) with used / limit / available /PctUsedand an
OK / NearLimit / AtLimit flag (threshold via-NearLimitPct, default 80). Optionally
(-IncludeDiskCapacityInventory) it adds an informational managed-disk capacity inventory —
total provisioned GiB by region and disk SKU, summed from Resource Graph — explicitly flagged
IsQuota=False/Informationalwith a blank limit, because Azure exposes no general
per-subscription managed-disk capacity quota usage API. Supports-Location,-AllLocationsand the
standard subscription selectors. Reader-only. Resolves #14. - App Service quota visibility (
Get-AppServiceQuota.ps1) — a read-only collector that joins App
Service Plan inventory (Resource Graph) with the subscription/region
Microsoft.Web/locations/{loc}/usagesand per-planMicrosoft.Web/serverfarms/{name}/usagesAPIs
(api-version2025-05-01). Emits three row scopes —SubscriptionRegion,AppServicePlan, and an
InventoryDerivedrow comparing each plan's current instance count to its documented tier scale-out
ceiling (Basic 3 / Standard 10 / Premium v1 20 / Premium v2-v4 30 / Isolated 100) — with
used / limit / available /PctUsed,NearLimit/AtLimitandPlanAtInstanceCeilingflags.
True API-reported quota rows (IsTrueQuota=True) are kept distinct from documented/inventory rows via
LimitBasis; SKUs without a fixed ceiling (Consumption / Flex Consumption) are flagged
HasUnknownLimitrather than given a fabricated limit. Supports-Location,-AllLocationsand the
standard subscription selectors. Reader-only. Resolves #7. - Network quota visibility (
Get-NetworkQuota.ps1) — a read-only collector that reports
per-subscription, per-region Microsoft.Network usage vs limit (the data behind
az network list-usages/ theMicrosoft.Network/locations/{loc}/usagesAPI): Virtual Networks,
Public IP Addresses, Network Interfaces, Load Balancers, NAT Gateways and the rest. Networking quota
is a common, silent deployment blocker — you cannot create a VM if the subscription is out of public
IPs or NICs in the region, regardless of compute headroom. Each counter is emitted with
used / limit / available /PctUsedandNearLimit/AtLimitflags (threshold via
-NearLimitPct, default 80). Counters the API returns with the placeholder2147483647limit are
markedIsUnbounded(no fabricated math); per-VNet sub-counters (…PerVirtualNetwork) are flagged
PerResourceScope. Supports-Location,-AllLocations, and the standard subscription selectors.
Reader-only. Resolves #13. - AKS scale-headroom check (
Get-AksScaleHeadroom.ps1) — a read-only derivation that answers
"if every node pool scaled to its autoscalermaxCount, would we run out of family quota?" It
joins data the toolkit already reads — AKS node pools (Resource Graph),Microsoft.Compute/skus
(VM size → family + vCPUs) andaz vm list-usage(per-family used/limit) — to compute the
incremental vCPUs each pool needs to reach its target, aggregates per VM family, and flags
families that cannot fully scale within current quota. Pools in the same family are summed
before comparison; Spot pools are checked against the separate regional low-priority pool, never
the regular family quota; autoscale-disabled pools target their current count. Emits a per-pool
detail CSV and a per-family rollup CSV, withFindingcodes
(OK/QuotaShortfall/MissingSkuMetadata/MissingQuotaFamily/SpotQuotaCheckNeeded).
Reader-only. Resolves #12. - Capacity Reservation inventory (
Get-CapacityReservations.ps1) — a read-only collector that
enumeratesMicrosoft.Compute/capacityReservationGroupsand their childcapacityReservations
across visible subscriptions (ARM read, api-version2024-07-01,$expand=instanceView) and reports,
per reservation, the SKU, region, zone, reserved instance count, the capacity actually reserved at
runtime, how many instances are consuming it, and idle / over-allocated / at-capacity flags. This
closes the loop on the one construct that guarantees capacity (as distinct from quota), which
docs/concepts.mdalready teaches. Reader-only; empty and unreadable (shared-scope) groups are
surfaced as explicit rows. Resolves #11. - Spot Placement Score lens (
Get-SpotPlacementScore.ps1) — a read-only collector that calls the
Azure Spot Placement Score API (Microsoft.Compute/locations/.../placementScores/spot/generate,
api-version2025-06-05) to return an allocation-likelihood signal (High/Medium/Low) per
VM size × region × zone — the closest programmatic answer to the toolkit's "quota ≠ capacity"
caveat. It scores Spot capacity (a proxy for regional pressure, not an on-demand guarantee), is
time-sensitive (every row timestamped), and needs the read-only built-in "Compute Recommendations
Role" in addition to Reader. Chunks requests to the API limits (≤8 regions × ≤5 sizes) and handles
throttling / missing-role responses gracefully. - Quota Group rollout (opt-in write tool) —
Deploy-QuotaGroups.ps1, a generic,
config-driven, idempotent engine that provisions Azure Quota Groups
(Microsoft.Quota/groupQuotas) from a JSON design: registers providers, creates groups at
a management-group scope, adds members, requests pooled group limits, and allocates quota to
subscriptions. Requires PowerShell 7+, supports-WhatIf, and is guarded byShouldProcess.
This is the toolkit's only write capability and is kept separate from the read-only scans. - Quota Group config bridge (
New-QuotaGroupConfig.ps1) — turns a quota report into a
deploy-ready design, auto-detecting either the toolkit-native widequota-usageCSV (from
Get-QuotaUsage.ps1) or an external azure-quota-reports CSV; computes allocations and
pooled group limits with a configurable headroom buffer. - Synthetic
examples/quota-groups.sample.jsondesign and a Quota Groups rollout
guide; a "Services & coverage" matrix in the README. - AI & agent governance section in
AGENTS.md— states the toolkit runs no AI models and sends
no data to any model or third party; the only AI relationship is an agent operating it under the
file's read-only-by-default guardrails. - Synthetic demo data generator (
New-DemoDataset.ps1) — produces a complete,
self-consistent fictional dataset ("Zava Inc") from a deterministic seed, with no Azure
access required, so the dashboard can be previewed entirely offline. The generated universe
exercises a range of dashboard states (SKU blocks and zone gaps, near-capacity quota, a GPU
crunch, a pooled quota group, AKS lifecycle states, zone-redundant HA databases).
Changed
- Positioning reframed to "read-only by default." Docs, badges and templates no longer claim
zero mutations now...
v0.1.0
First release of the Azure Capacity & Enablement Toolkit — read-only PowerShell scripts and a self-contained HTML dashboard for analyzing Azure regional/zonal capacity, SKU enablement, quota, and zonal resilience using only Reader access.
Highlights
- Capacity & enablement scans — discover which SKUs you run, check regional + zonal enablement, and see quota/headroom per family.
- Resilience view — per-subscription zone mapping, zone-pinned resource sweep, AKS and Flexible Server footprint.
- Region comparison — score candidate regions for a move or failover, with capacity-honest verdicts.
- One-command report — orchestrator joins the scans into a CSV + Markdown summary and an offline, tabbed HTML dashboard.
Everything is read-only — the only writes are local files under output/.
See the docs to get started, and the changelog for the full list.