Log Analytics workspaces, KQL queries, metric and log-based alert rules, VM backup with Recovery Services vault, Azure Site Recovery concepts, and zero-credential Key Vault architecture with full audit logging — observability and security across the stack.
Built the observability layer for the lab environment: a Log Analytics workspace receiving performance and event data from both VMs via Azure Monitor Agent and Data Collection Rules, metric alert rules firing on CPU threshold breaches, a log-based heartbeat alert detecting VM availability, and an Action Group delivering email notifications. Verified end-to-end by stress-testing CPU on the Linux VM and confirming the alert fired and the email arrived.
The legacy Log Analytics agent (MMA) and Azure Diagnostics extension (LAD) were deprecated in March 2026. The current pattern is Azure Monitor Agent with Data Collection Rules. DCRs decouple the definition of what data to collect from the agent — the same DCR can be associated with multiple VMs, and data collection can be changed without touching the agent.
Heartbeat
| summarize LastSeen=max(TimeGenerated) by Computer
| extend MinutesSince=datetime_diff('minute',now(),LastSeen)
| order by MinutesSince asc
Perf
| where CounterName == "% Processor Time"
| where ObjectName == "Processor"
| where InstanceName == "_Total"
| summarize AvgCPU=avg(CounterValue)
by Computer, bin(TimeGenerated, 5m)
| render timechart
az monitor data-collection rule association create does not accept -g. The
resource group is implicit in the --resource ARM ID. Use the full resource ID.
After creating a diagnostic setting, logs take 5–15 minutes to appear in Log Analytics. Trigger a read operation first, wait, then query. Running the KQL query immediately returns zero results and looks like a misconfiguration — it isn't.
Deployed a zero-credential architecture connecting App Service to Key Vault using
system-assigned managed identity. No passwords, no API keys, no service principal secrets anywhere in
code, configuration files, deployment scripts, or git history. The App Service proves its identity to
Microsoft Entra ID, receives a scoped token, and uses that token to resolve Key Vault references at
runtime — surfacing secrets as ordinary environment variables to the application without any Key Vault
dependency in application code. Every secret access is logged to Log Analytics as an
AuditEvent and queryable via KQL.
The traditional approach stores a credential somewhere the app can read it. Every step is a failure point: committed to git, stored in plaintext, forgotten after rotation. Managed identity eliminates the credential entirely. Azure manages the identity lifecycle — when the App Service is deleted, the identity is deleted with it. Nothing to rotate, nothing to leak, nothing to accidentally expose.
AzureDiagnostics
| where ResourceType == "VAULTS"
| where OperationName == "SecretGet"
| project TimeGenerated, CallerIPAddress,
OperationName, ResultType
| order by TimeGenerated desc
@Microsoft.KeyVault(SecretUri=...)) means the application has no Key Vault dependency in
its code. The runtime resolves the reference before surfacing it as an environment variable.
Infrastructure manages secrets; application consumes environment variables.The @ symbol and parentheses in @Microsoft.KeyVault(...) are mishandled by
Git Bash and WSL even inside quotes. All az webapp config appsettings set commands
containing KV references must run from Azure Cloud Shell.
After setting KV references via CLI, output shows "value": null. This is expected — App
Service hides the reference string for security. Verify in the portal under Settings → Environment
variables: correctly resolved references show a green checkmark and "Key vault" in the Source column.
AuditEvent is the Key Vault diagnostic category. App Service exposes
AppServiceHTTPLogs, AppServiceConsoleLogs, and others. Never guess category names
— query them: az monitor diagnostic-settings categories list --resource $RESOURCE_ID returns
exactly what is valid for that specific resource type.