Fast reference for Microsoft Azure Administrator (AZ-104): RBAC scopes, Policy vs Locks, storage redundancy & tiers, private access patterns, load-balancing choices, VM/VMSS tips, monitoring/KQL snippets, backup/restore gotchas.
Use this as your last-mile cram sheet. Pair with the Syllabus for coverage and Practice to validate speed/accuracy.
Scope order: Management Group → Subscription → Resource Group → Resource
Inheritance: Most assignments flow down unless explicitly denied/overridden.
Feature | What it controls | Where you assign | Typical use | Notes |
---|---|---|---|---|
RBAC | Who can do which actions | Any scope | Grant least-privilege access | Use built-in roles first; custom JSON as last resort |
Policy | Compliance/config drift | Any scope | Enforce allowed regions/SKUs/tags | Effects: Deny , Audit , Append , Modify , DeployIfNotExists |
Locks | Delete vs change protection | RG/Resource | Guardrails for prod assets | Types: CanNotDelete , ReadOnly ; can break automation if overused |
Tags | Metadata for cost/ops | Resource & RG | Owner/Env/CostCenter | Inherit via Policy (Append/Modify) |
Quick checks:
Redundancy | Scope | Zone-aware | Cross-region | Notes |
---|---|---|---|---|
LRS | Single datacenter | ✖ | ✖ | Cheapest; no zone resilience |
ZRS | Multiple zones in region | ✔ | ✖ | Zone outage tolerance |
GRS | Region pair (async) | ✖ | ✔ | Secondary read blocked (unless RA) |
GZRS | Zones + region pair | ✔ | ✔ | Highest durability in GA regions |
RA-GRS / RA-GZRS | Adds read access to secondary | — | ✔ | App can read from secondary endpoint |
Tier | Optimized for | Billing | Typical use |
---|---|---|---|
Hot | Frequent access | Higher storage, lower access | Active data |
Cool | Infrequent (≥30 days) | Lower storage, higher access | Logs, backups |
Archive | Rare (≥180 days) | Lowest storage, highest access; rehydrate | Compliance retention |
A
records in Private DNS Zone; link to VNet (consider split-horizon)CLI snippets
1# Private Endpoint + Private DNS zone for a storage account
2az network private-dns zone create -g RG -n privatelink.blob.core.windows.net
3az network private-endpoint create -g RG -n pe-stg --vnet-name VNET --subnet SUBNET \
4 --private-connection-resource-id "/subscriptions/<sub>/resourceGroups/RG/providers/Microsoft.Storage/storageAccounts/<name>" \
5 --group-id blob --connection-name pe-stg-conn
6# Link zone and add auto-registration if needed (for PaaS zones, usually manual records)
7az network private-dns link vnet create -g RG -n link-stg --virtual-network VNET \
8 --zone-name privatelink.blob.core.windows.net --registration-enabled false
Need | Pick | Why |
---|---|---|
L4/TCP-UDP inside a VNet | Load Balancer | SNAT, HA, health probes |
L7/WAF, path-based, TLS offload | Application Gateway | App-aware, WAF, rewrite |
Global anycast + CDN + WAF | Front Door | Global edge, caching, smart routing |
Availability & resilience
Images & extensions
1# Create image from a generalized VM and publish to a gallery
2az image create -g RG -n baseImage --source VMNAME
3az sig create -g RG -r MyGallery
4az sig image-definition create -g RG -r MyGallery -i webImage --os-type linux
5az sig image-version create -g RG -r MyGallery -i webImage -e 1.0.0 --target-regions "eastus=2" "westus2=1" --managed-image "/subscriptions/<sub>/resourceGroups/RG/providers/Microsoft.Compute/images/baseImage"
6
7# Run Command (quick script)
8az vm run-command invoke -g RG -n VMNAME --command-id RunShellScript --scripts "sudo apt-get update -y"
Scale set autoscale
1az monitor autoscale create -g RG --resource "/subscriptions/<sub>/resourceGroups/RG/providers/Microsoft.Compute/virtualMachineScaleSets/vmss1" \
2 --min-count 2 --max-count 10 --count 2
3az monitor autoscale rule create -g RG --autoscale-name vmss1 \
4 --condition "Percentage CPU > 70 avg 5m" --scale out 2
5az monitor autoscale rule create -g RG --autoscale-name vmss1 \
6 --condition "Percentage CPU < 30 avg 10m" --scale in 1
Metric alert → Action Group
1az monitor action-group create -g RG -n ops-ag --action email Ops ops@example.com
2az monitor metrics alert create -g RG -n cpu-high --scopes "/subscriptions/<sub>/resourceGroups/RG/providers/Microsoft.Compute/virtualMachines/VMNAME" \
3 --condition "avg Percentage CPU > 80" --window-size 5m --evaluation-frequency 1m \
4 --action-group ops-ag
KQL quickies
// VM CPU > 80% in last 24h
Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time" and TimeGenerated > ago(24h)
| summarize AvgCPU=avg(CounterValue) by Computer
| where AvgCPU > 80
| order by AvgCPU desc
// NSG denied flows (NSG flow logs sent to LA via NSG Flow Logs v2)
AzureDiagnostics
| where Category == "NetworkSecurityGroupFlowEvent"
| where msg_s contains "Deny"
| summarize count() by bin(TimeGenerated, 1h), srcIp_s, dstIp_s, l4Protocol_s
| order by TimeGenerated desc
// Storage 403s by account
AzureDiagnostics
| where Category == "StorageBlobLogs" or Category == "StorageRead"
| where httpStatusCode_s == "403"
| summarize Count403=count() by StorageAccount=Resource, bin(TimeGenerated, 1h)
| order by TimeGenerated desc
CLI
1# Enable VM backup
2az backup vault create -g RG -n Vault01 -l eastus
3az backup protection enable-for-vm -g RG -v Vault01 --vm VMNAME --policy-name DefaultPolicy
4
5# Restore to a new VM
6az backup restore restore-disks --vault-name Vault01 -g RG --container-name VM;Compute;VMNAME \
7 --item-name VMNAME --rp-name "RecoveryPoint_2025-09-10T01-00-00Z" --storage-account SADEST
A
record; check privatelink.*
zone link to VNet.Service | Default Ports | Notes |
---|---|---|
RDP (Windows) | 3389/TCP | Prefer Bastion or JIT access |
SSH (Linux) | 22/TCP | Prefer Bastion or JIT access |
HTTP/HTTPS | 80/443 | Offload TLS at App Gateway/Front Door when possible |
DNS (Private DNS) | 53/UDP/TCP | Forwarders for hybrid name resolution |
Probe (LB/AppGW) | Custom | Ensure NSG allows health probe source ranges |