Microsoft Defender for Cloud · Virtual Machine Scale Sets
Virtual machine scale sets should be configured securely
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Virtual machine scale sets should be configured securely" check?
Flags virtual machine scale sets that have unremediated operating system security-configuration vulnerabilities. The backing recommendation, 'On virtual machine scale sets, remediate vulnerabilities to protect them from attacks', is driven by the policy 'Vulnerabilities in security configuration on your virtual machine scale sets should be remediated'. Defender for Cloud collects the in-guest OS configuration of each instance and compares it against a catalogue of known weak settings (the CCE security-configuration checks, such as weak password policy, missing audit logging or enabled legacy protocols), then reports each instance that still has open findings. It surfaces existing weaknesses rather than enforcing a baseline: it does not scan installed packages for software CVEs, does not check Azure-side properties like network rules or disk encryption, and its data path historically depended on the now-deprecated Log Analytics or Azure Monitoring agent, so the recommendation itself is on a deprecated assessment.
Why does "Virtual machine scale sets should be configured securely" matter?
A scale set multiplies whatever base image you deploy across every instance, so one weak default, an open management protocol, verbose error pages or a permissive local account policy, becomes the same foothold on tens or hundreds of machines at once. A known security-configuration weakness is exactly what an attacker probes for after landing on a single node, and it is invisible to perimeter controls because the gap lives inside the OS. Remediating the flagged findings across the fleet closes that window before an incident rather than after, and it keeps the configuration weaknesses on the scale set visible and tracked as it grows and shrinks.
How do I fix "Virtual machine scale sets should be configured securely"?
- Open the recommendation in Defender for Cloud and review the security-configuration findings it lists for the scale set, then remediate each flagged weakness in the source image so every instance inherits the fix: az vmss show --resource-group <rg> --name <vmss> --query virtualMachineProfile.storageProfile.imageReference to confirm which image the fleet runs.
- Rebuild the golden image with the weak settings corrected (or apply the change to a running instance to validate it), update the scale set to the hardened image, and roll it out: az vmss update --resource-group <rg> --name <vmss> --set virtualMachineProfile.storageProfile.imageReference.id=<hardened-image-id>, then az vmss update-instances --resource-group <rg> --name <vmss> --instance-ids '*'.
- Because this recommendation runs on the deprecated Log Analytics or Azure Monitoring agent assessment, move ongoing posture coverage to the current machine configuration baseline instead. Assign the built-in initiative by looking up its name rather than a hardcoded GUID: pid=$(az policy set-definition list --query "[?displayName=='Deploy prerequisites to enable Guest Configuration policies on virtual machines'].name" -o tsv); az policy assignment create --name vmss-guestconfig --policy-set-definition "$pid" --scope <scope> --location <region> --mi-system-assigned.
Remediation script · bash
# Step 1: give a machine the system-assigned identity the agent needs to authenticate.
az vm identity assign --resource-group prod-apps --name legacy-app-01
# Install the machine configuration agent (instance name MUST be AzurePolicyforWindows / AzurePolicyforLinux).
az vm extension set \
--resource-group prod-apps --vm-name legacy-app-01 \
--publisher Microsoft.GuestConfiguration \
--name ConfigurationforLinux \
--extension-instance-name AzurePolicyforLinux \
--enable-auto-upgrade true
# Step 2: assign the deploy-prerequisites initiative so identity + agent self-heal across the scope.
# Look the initiative up by its EXACT display name rather than pasting a GUID.
scope="/subscriptions/00000000-0000-0000-0000-000000000000"
setid=$(az policy set-definition list \
--query "[?displayName=='Deploy prerequisites to enable Guest Configuration policies on virtual machines'].name" -o tsv)
az policy assignment create \
--name deploy-gc-prereqs \
--policy-set-definition "$setid" \
--scope "$scope" \
--location uksouth \
--mi-system-assigned
# Assign the Windows compute security baseline initiative (look it up by display name too).
baseid=$(az policy set-definition list \
--query "[?displayName=='Windows machines should meet requirements for the Azure compute security baseline'].name" -o tsv)
az policy assignment create \
--name assign-win-baseline \
--policy-set-definition "$baseid" \
--scope "$scope" Full walkthrough (console steps, edge cases and verification) in the lesson Apply guest configuration baselines.
Is "Virtual machine scale sets should be configured securely" a false positive?
A scale set running a hardened bespoke image (for example a regulated workload following a CIS or DISA STIG profile that legitimately differs from the settings the checks expect) can still flag findings where the profiles diverge. Where you have a documented stricter standard, record an exemption in Defender for Cloud against the specific findings rather than disabling the recommendation, so the remaining open weaknesses on the fleet stay visible.