VMware private cloud outside production
An Azure VMware Solution private cloud tagged non-production.
Why it happens
Azure VMware Solution is dedicated bare-metal billed per node for every hour the private cloud exists, whatever is running on it. Microsoft sets the minimum deployment at three hosts and states that clusters cannot be scaled down past three, so the floor is roughly $16,100 a month on the AV36 SKU and about $25,000 on AV64, before a single virtual machine runs. A development or test private cloud is the most expensive idle resource an Azure subscription can hold. There is no automated remedy: the cluster cannot be trimmed below its floor, and removing it destroys the VMware estate on it, so this check reports the cost and the floor and leaves the decision to a human.
Paste this into Resource Graph Explorer in the Azure portal.
resources
| where type =~ 'microsoft.avs/privateclouds'
// Scope below matches CloudFinOpsPro policy DEFAULTS: exclusions.protectTag, environment.tagKeys,
// environment.allowedTagValues, and allowUntagged false so an untagged resource counts as production.
// If your policy.yaml differs, edit the three lines below or this will disagree with your own agent.
| where tolower(tostring(coalesce(tags['cfop:protect'], ''))) !in ('true', 'yes', '1')
| extend cfopEnv = tolower(trim(' ', tostring(coalesce(tags['Environment'], tags['environment'], tags['env'], ''))))
| where cfopEnv in ('dev', 'development', 'test', 'qa', 'sandbox', 'nonprod', 'non-prod', 'staging')
// The SKU is a top-level column for this type, spelled lowercase by ARM and uppercase by the meters.
| extend avsSku = tostring(coalesce(sku.name, properties.sku.name))
// Node count decides the bill. Falls back to counting the hosts array where the count is absent.
| extend nodes = coalesce(toint(properties.managementCluster.clusterSize), array_length(properties.managementCluster.hosts))
| project name, resourceGroup, location, sku = avsSku, nodes, environment = cfopEnvAzure VMware Solution is dedicated bare-metal billed per node for every hour the private cloud exists, whatever runs on it. Microsoft sets the minimum deployment at three hosts and states that clusters cannot be scaled down past three, so the floor is roughly $16,100 a month on AV36 and about $25,000 on AV64. Pricing this is unusually easy to get wrong: the meters are published under the service name 'Specialized Compute', not 'Azure VMware Solution', which returns no rows at all; the Trial node meters are published at $0.00; the reservation rows carry a unit of '1 Hour' with values up to $209,915 that are multi-year totals; and AV36 is a prefix of AV36P, so a loose match prices a premium node at the standard rate. The check reads the rate live and refuses to quote a figure when the SKU or region does not match. This query returns the nodes rather than a cost for the same reason. It is a structural test, so what it returns is what the check reports.
Applies to microsoft.avs/privatecloudsWhat the agent does about it
An Azure VMware Solution private cloud tagged non-production.
It will not fix this one
It reports this and takes no action. A check only earns the right to change something once the action behind it can re-read live state before it fires and knows the way back.
Related checks
Idle virtual machine
A running VM whose CPU and network have been near zero for the whole window.
Oversized virtual machine
A running VM whose sustained peak fits comfortably inside the next size down.
Unattached managed disk
A managed disk attached to nothing, billing its full provisioned size every month.