Back to Checks
Prowlerprowler-provider-azure
Virtual Machine uses an organization-approved SKU size
vm_desired_sku_size
Service: vmSeverity: medium
OfficialBuilt-inVerified
Resource Type:microsoft.compute/virtualmachines
Azure virtual machines are compared against an organization allowlist of VM size SKUs defined in desired_vm_sku_sizes.
Instances using sizes outside this list are flagged as non-standard.
Risk
Unrestricted VM sizes enable over-provisioned or exotic SKUs, leading to:
- Sudden cost spikes and quota exhaustion (availability)
- Use of hardware lacking required security features (confidentiality/integrity)
- Abuse by compromised accounts for cryptomining at scale
Run this check with Prowler
Run in Prowler CloudRun
prowler azure --checks vm_desired_sku_sizeRecommendation
Adopt a least privilege, policy-enforced allowlist of VM size SKUs per workload tier and region.
- Deny creation of non-approved sizes across scopes
- Require exception reviews with time-bound overrides
- Reassess the list regularly for cost, performance, and compliance
- Monitor provisioning and cost anomalies for drift
Remediation
CLI
az vm resize --resource-group <RESOURCE_GROUP> --name <VM_NAME> --size <desired-sku-1>Terraform
# Enforce allowed VM SKUs via Azure Policy
resource "azurerm_policy_assignment" "<example_resource_name>" {
name = "<example_resource_name>"
scope = "/subscriptions/<example_resource_id>"
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/<example_resource_id>"
parameters = jsonencode({
listOfAllowedSKUs = { value = ["<desired-sku-1>", "<desired-sku-2>"] } # CRITICAL: only these SKUs are allowed
})
}NativeIaC
// Resize VM to an approved SKU
resource vm 'Microsoft.Compute/virtualMachines@2023-09-01' = {
name: '<example_resource_name>'
location: '<example_location>'
properties: {
hardwareProfile: {
vmSize: '<desired-sku-1>' // CRITICAL: sets VM to an approved size so the check passes
}
}
}Other
1In Azure Portal, go to Virtual machines and select the VM
2Under Availability + scale, select Size
3Choose an approved size (e.g., <desired-sku-1>) and click Resize
4If the size isn't listed, Stop (deallocate) the VM, then retry Resize
Check Code
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.vm.vm_client import vm_client
class vm_desired_sku_size(Check):
"""
Ensure that Azure virtual machines are using SKU sizes that are approved by your organization.
This check evaluates whether each virtual machine's SKU size is included in the organization's approved list of VM sizes.
The approved SKU sizes are configured in the Prowler configuration file under azure.desired_vm_sku_sizes.
- PASS: The VM is using a SKU size that is approved by the organization.
- FAIL: The VM is using a SKU size that is not approved by the organization.
"""
def execute(self) -> list[Check_Report_Azure]:
"""
Execute the check to verify that virtual machines are using desired SKU sizes.
Returns:
A list of check reports for each virtual machine
"""
findings = []
# Get the desired SKU sizes from configuration
DESIRED_SKU_SIZES = vm_client.audit_config.get(
"desired_vm_sku_sizes",
[
"Standard_A8_v2",
"Standard_DS3_v2",
"Standard_D4s_v3",
],
)
for subscription_id, vms in vm_client.virtual_machines.items():
subscription_name = vm_client.subscriptions.get(
subscription_id, subscription_id
)
for vm in vms.values():
report = Check_Report_Azure(metadata=self.metadata(), resource=vm)
report.subscription = subscription_id
if vm.vm_size in DESIRED_SKU_SIZES:
report.status = "PASS"
report.status_extended = f"VM {vm.resource_name} is using desired SKU size {vm.vm_size} in subscription {subscription_name} ({subscription_id})."
else:
report.status = "FAIL"
report.status_extended = f"VM {vm.resource_name} is using {vm.vm_size} which is not a desired SKU size in subscription {subscription_name} ({subscription_id})."
findings.append(report)
return findings