Microsoft Defender for Cloud · Virtual Machine Scale Sets
Diagnostic logs in Virtual Machine Scale Sets should be enabled
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Diagnostic logs in Virtual Machine Scale Sets should be enabled" check?
Audits each Microsoft.Compute/virtualMachineScaleSets resource for an active diagnostic setting that ships its resource logs to a destination such as a Log Analytics workspace, event hub or storage account. It is an AuditIfNotExists check: it only confirms a diagnostic setting exists and is enabled, not that the categories you actually need are selected or that retention is long enough. It does not inspect the guest operating system, so application and security event logs from inside the VM instances are out of scope: collecting those needs the Azure Monitor Agent and a data collection rule, which this control does not evaluate. Note the underlying built-in policy (7c1b1214) is the deprecated 'Resource logs in Virtual Machine Scale Sets' definition, so treat it as a coverage signal and plan the move to the Azure Monitor Agent.
Why does "Diagnostic logs in Virtual Machine Scale Sets should be enabled" matter?
A scale set is elastic by design: instances are created and destroyed as load changes, and with them any logs held only on local disk. If no diagnostic setting is forwarding resource logs off the instances, the evidence you would need to reconstruct an incident is gone the moment the fleet scales in. When an attacker pivots through a compromised instance, an investigation with no centralised logs cannot establish what was accessed, how far the breach spread or when it began, which turns a contained incident into an unbounded one and undermines breach-notification and audit obligations. Forwarding logs to a workspace with sensible retention preserves the activity trail independently of instance lifecycle.
How do I fix "Diagnostic logs in Virtual Machine Scale Sets should be enabled"?
- Create a diagnostic setting on the scale set that streams its resource logs to a Log Analytics workspace: az monitor diagnostic-settings create --name vmss-logs --resource <vmss-resource-id> --workspace <workspace-resource-id> --logs '[{"categoryGroup":"allLogs","enabled":true}]'.
- Standardise it in Bicep with a Microsoft.Insights/diagnosticSettings resource scoped to the scale set, setting workspaceId and a logs array of { categoryGroup: 'allLogs', enabled: true }, so every new scale set is covered at deployment time.
- Enforce it at scale with the current built-in diagnostic-settings initiative rather than the deprecated per-resource Deploy-Diagnostics-VMSS policy: sid=$(az policy set-definition list --query "[?displayName=='Enable allLogs category group resource logging for supported resources to Log Analytics'].name" -o tsv); az policy assignment create --name diag-alllogs-la --policy-set-definition "$sid" --scope <subscription-or-mg-scope> --mi-system-assigned --location <location> --params '{"logAnalytics":{"value":"<workspace-resource-id>"}}', then create a remediation task per included policy to backfill existing resources.
Remediation script · bash
# Turn on the security-relevant App Service logs and send them to a workspace.
WS=$(az monitor log-analytics workspace show \
-g central-logging -n estate-logs --query id -o tsv)
for id in $(az webapp list --query "[].id" -o tsv); do
has=$(az monitor diagnostic-settings list --resource "$id" \
--query "length(value)" -o tsv)
if [ "$has" = "0" ]; then
az monitor diagnostic-settings create \
--name to-log-analytics \
--resource "$id" \
--workspace "$WS" \
--logs '[{"category":"AppServiceHTTPLogs","enabled":true},
{"category":"AppServiceAuditLogs","enabled":true},
{"category":"AppServiceConsoleLogs","enabled":true}]'
echo "$(basename "$id"): diagnostic logging enabled to estate-logs"
fi
done
# Ratchet it shut: built-in policy adds the setting to any new App Service.
az policy assignment create \
--name deploy-appservice-diag \
--policy 0c6cd767-1a1d-484b-a897-68e398c03aeb \
--location uksouth \
--mi-system-assigned \
--scope "/subscriptions/00000000-0000-0000-0000-000000000000" Full walkthrough (console steps, edge cases and verification) in the lesson Turn on diagnostic logging for Azure resources.
Is "Diagnostic logs in Virtual Machine Scale Sets should be enabled" a false positive?
A scale set that intentionally forwards its logs to an event hub or a storage account, rather than to a Log Analytics workspace, is correctly covered but may still surface depending on how the assignment is scoped: the resource is compliant because a diagnostic setting exists and is enabled. Confirm the destination meets your retention and access requirements and document the exception rather than adding a duplicate workspace setting.