Back to Checks
Virtual Machine is protected by Azure Backup
vm_backup_enabled
Service: vmSeverity: high
OfficialBuilt-inVerified
Categories:resilience
Resource Type:microsoft.compute/virtualmachines
Azure VMs are evaluated for protection by Azure Backup by confirming they exist as VM backup items in a Recovery Services vault.
VMs absent from any vault item indicate no configured backup coverage.
Risk
Unprotected VMs jeopardize availability and integrity. Deletion, corruption, or ransomware can wipe data, and without recovery points recovery is slow or impossible, causing extended outages, missed RPO/RTO, and cascading impact on dependent services.
Run this check with Prowler
Run in Prowler CloudRun
prowler azure --checks vm_backup_enabledRecommendation
Protect all VMs with Azure Backup in a Recovery Services vault under a standardized policy. Align schedules and retention to RPO/RTO, use GRS/ZRS and immutable vault features, enforce least privilege on backup operations, automate enrollment at provisioning, and regularly test restores.
Remediation
CLI
az backup protection enable-for-vm --resource-group <vault-resource-group> --vault-name <vault-name> --vm <vm-name> --vm-resource-group <vm-resource-group> --policy-name DefaultPolicyTerraform
# Protect an existing VM with Azure Backup
resource "azurerm_backup_protected_vm" "<example_resource_name>" {
resource_group_name = "<example_resource_name>" # vault's resource group
recovery_vault_name = "<example_resource_name>"
source_vm_id = "<example_resource_id>" # critical: VM to protect
backup_policy_id = "<example_resource_id>" # critical: policy that enables backup
}NativeIaC
// Enable Azure Backup protection for an existing VM in an existing Recovery Services vault
param vmId string // e.g., /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Compute/virtualMachines/<vm>
param vaultName string
param vaultRg string
param policyId string // e.g., /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.RecoveryServices/vaults/<vault>/backupPolicies/<policy>
resource vault 'Microsoft.RecoveryServices/vaults@2023-04-01' existing = {
name: vaultName
scope: resourceGroup(vaultRg)
}
var vmRg = split(split(vmId, '/resourceGroups/')[1], '/')[0]
var vmName = split(vmId, '/virtualMachines/')[1]
resource protect 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems@2023-02-01' = {
// critical: this resource creates the protected item, enabling backup for the VM
name: '${vault.name}/Azure/protectionContainers/iaasvmcontainer;iaasvmcontainerv2;${vmRg};${vmName}/protectedItems/VM;iaasvmcontainerv2;${vmRg};${vmName}'
properties: {
protectedItemType: 'Microsoft.Compute/virtualMachines' // critical: VM backup item type
sourceResourceId: vmId // critical: target VM to protect
policyId: policyId // critical: associates the VM with a backup policy
}
}Other
1In Azure Portal, go to Virtual machines > <VM> > Backup
2Select a Recovery Services vault in the same region (or create one if prompted)
3Choose the DefaultPolicy (or an existing VM backup policy)
4Click Enable backup
Check Code
from azure.mgmt.recoveryservicesbackup.activestamp.models import DataSourceType
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.recovery.recovery_client import recovery_client
from prowler.providers.azure.services.vm.vm_client import vm_client
class vm_backup_enabled(Check):
"""
Ensure that Microsoft Azure Backup service is in use for your Azure virtual machines (VMs).
This check evaluates whether each Azure VM in the subscription is protected by Azure Backup.
- PASS: The VM is protected by Azure Backup (present in a Recovery Services vault).
- FAIL: The VM is not protected by Azure Backup (not present in any Recovery Services vault).
"""
def execute(self) -> list[Check_Report_Azure]:
"""Execute Azure VM backup enabled check.
Returns:
A list of reports containing the result of the check.
"""
findings = []
for subscription_id, vms in vm_client.virtual_machines.items():
subscription_name = recovery_client.subscriptions.get(
subscription_id, subscription_id
)
vaults = recovery_client.vaults.get(subscription_id, {})
for vm in vms.values():
found = False
found_vault_name = None
for vault in vaults.values():
for backup_item in vault.backup_protected_items.values():
if (
backup_item.workload_type == DataSourceType.VM
and backup_item.name.split(";")[-1].lower()
== vm.resource_name.lower()
):
found = True
found_vault_name = vault.name
break
if found:
break
report = Check_Report_Azure(metadata=self.metadata(), resource=vm)
report.subscription = subscription_id
if found:
report.status = "PASS"
report.status_extended = f"VM {vm.resource_name} in subscription {subscription_name} ({subscription_id}) is protected by Azure Backup (vault: {found_vault_name})."
else:
report.status = "FAIL"
report.status_extended = f"VM {vm.resource_name} in subscription {subscription_name} ({subscription_id}) is not protected by Azure Backup."
findings.append(report)
return findings