Well-Architected Review
Purpose
Perform a structured assessment of Azure resources against the five pillars of the Microsoft Azure Well-Architected Framework. Produce a scored report with prioritized recommendations.
When to use this skill
- User asks "are we following best practices?"
- User asks for a WAF or Well-Architected review
- User wants to assess architecture quality before a launch or audit
- Periodic (quarterly) architecture health check
Pillars and checks
1. Reliability
Run the following checks and report findings:
- Availability design: Check if critical workloads use availability zones or availability sets
az vm list --query "[].{name:name, zones:zones, availabilitySet:availabilitySet.id}" -o table
az appservice plan list --query "[].{name:name, zoneRedundant:zoneRedundant, sku:sku.name}" -o table
- Backup coverage: Verify Recovery Services vaults and backup policies exist for VMs, databases, and file shares
az backup vault list -o table
Then for each vault:az backup item list --vault-name <vault> --resource-group <rg> --backup-management-type AzureIaasVM -o table
- Disaster recovery: Check for paired regions, ASR replication, or geo-redundant storage
- Health probes: Verify App Service health checks, load balancer probes, and Container Apps health endpoints
- Auto-healing: Check if App Service auto-heal rules or AKS pod disruption budgets are configured
2. Security
- Identity: Check for managed identities vs. stored credentials
az webapp identity show --name <app> --resource-group <rg>
az ad app list --query "[].{name:displayName, passwordCredentials:passwordCredentials}" -o table
- Network isolation: Check for private endpoints, NSGs, and service endpoints
az network private-endpoint list -o table
az network nsg list -o table
- Encryption: Verify encryption at rest (storage, databases) and in transit (TLS)
- Key management: Check Key Vault usage and key/secret expiration dates
az keyvault list -o table
az keyvault secret list --vault-name <vault> --query "[].{name:name, expires:attributes.expires}" -o table
- Defender for Cloud: Check Secure Score and outstanding recommendations
3. Cost Optimization
- Rightsizing: Identify underutilized VMs (CPU < 5% average over 14 days)
- Orphaned resources: Find unattached disks, unused public IPs, empty resource groups
az disk list --query "[?managedBy==null].{name:name, size:diskSizeGb, rg:resourceGroup}" -o table
az network public-ip list --query "[?ipConfiguration==null].{name:name, rg:resourceGroup}" -o table
- Reservations: Check if high-usage resources could benefit from reserved instances
- Dev/Test pricing: Verify non-production workloads use Dev/Test subscriptions or B-series VMs
- Storage tiers: Check if cool/archive tiers are used for infrequently accessed data
4. Operational Excellence
- IaC coverage: Check for ARM/Bicep/Terraform templates in connected repos
- Tagging: Verify mandatory tags (environment, owner, cost-center) exist
az resource list --query "[?tags.environment==null].{name:name, type:type, rg:resourceGroup}" -o table
- Monitoring: Check for alert rules, action groups, and diagnostic settings
az monitor metrics alert list -o table
az monitor diagnostic-settings list --resource <id> -o table
- Deployment practices: Check for deployment slots, blue-green, or canary configurations
- Automation: Check for runbooks, Logic Apps, or scheduled tasks for routine operations
5. Performance Efficiency
- Autoscaling: Verify autoscale rules exist for App Service plans, VMSS, and Container Apps
az monitor autoscale list --resource-group <rg> -o table
Note: az monitor autoscale list requires --resource-group. Iterate over relevant resource groups, or use Azure Resource Graph:az graph query -q "resources | where type == 'microsoft.insights/autoscalesettings'" -o table
- Caching: Check for Redis Cache or CDN usage on high-traffic workloads
- Database performance: Check DTU/vCore utilization, index recommendations
- Content delivery: Verify static assets use CDN or Front Door
- Connection pooling: Check for connection string patterns suggesting missing pooling
Scoring model
For each check, assign one of:
- ✅ Pass — follows best practice
- ⚠️ Needs attention — partially implemented or at risk
- ❌ Fail — not implemented, risk exposure
Accepted exceptions (optional)
If the user provides a list of accepted exceptions, do not flag those items. Instead, note them in the report as Accepted Exception with the reason provided.
Example format the user may provide:
| Check |
Reason |
| 1.1 Availability zones |
Single-AZ by design to reduce cost |
| 3.3 Reserved instances |
Short-term workload, reservations not applicable |
| 5.5 Connection pooling |
Legacy app uses persistent connections by design |
When exceptions are provided:
- Skip the flagged checks in scoring
- List them in a separate "Accepted Exceptions" section at the end of the report
- Recalculate the overall score excluding excepted checks
Expected output
Report header (mandatory — use this exact format)
Well-Architected Review Report
| Field |
Value |
| Subscription |
(name + ID) |
| Assessment Date |
YYYY-MM-DD |
| Overall Score |
XX% |
Summary
A table with pillar scores:
| Pillar |
Pass |
Needs Attention |
Fail |
Score |
| Reliability |
X |
Y |
Z |
X/(X+Y+Z) % |
| Security |
... |
... |
... |
... |
| Cost Optimization |
... |
... |
... |
... |
| Operational Excellence |
... |
... |
... |
... |
| Performance Efficiency |
... |
... |
... |
... |
| Overall |
|
|
|
avg % |
Detailed findings
For each pillar, list every check with:
- Status (pass/attention/fail)
- Evidence (command output or observation)
- Recommendation (specific action to take)
- Priority (Critical / High / Medium / Low)
- Reference link to WAF documentation
Top 5 recommendations
Ordered by impact, with estimated effort (hours/days) for each.
Remediation guidance
For each ❌ or ⚠️ finding, include in the output:
- The specific
az CLI command to remediate (suggest only — do not execute)
- Use
GetAzCliHelp to validate the command syntax before suggesting
- The official Microsoft Learn documentation link for the remediation
References
Sample output
The following is a redacted example of what the report looks like when run against a subscription.
Well-Architected Review Report
| Field |
Value |
| Subscription |
contoso-prod-001 (a1b2c3d4-e5f6-7890-abcd-ef1234567890) |
| Assessment Date |
2026-07-15 |
| Overall Score |
68% |
Summary
| Pillar |
Pass |
Needs Attention |
Fail |
Score |
| Reliability |
3 |
1 |
1 |
60% |
| Security |
2 |
2 |
1 |
40% |
| Cost Optimization |
4 |
1 |
0 |
80% |
| Operational Excellence |
3 |
1 |
1 |
60% |
| Performance Efficiency |
4 |
0 |
1 |
80% |
| Overall |
16 |
5 |
4 |
68% |
Detailed findings (sample)
Reliability
| Check |
Status |
Evidence |
Priority |
| 1.1 Availability zones |
❌ Fail |
VMs vm-web-01, vm-web-02 in rg-app-prod have no zones configured |
Critical |
| 1.2 Backup coverage |
✅ Pass |
Recovery Services vault rsv-prod-eastus protects 4/4 VMs |
— |
| 1.3 Disaster recovery |
⚠️ Needs attention |
No ASR replication configured for rg-app-prod |
High |
Security
| Check |
Status |
Evidence |
Priority |
| 2.1 Managed identity |
✅ Pass |
App Service app-api-prod uses System-Assigned MI |
— |
| 2.2 Network isolation |
❌ Fail |
SQL Server sql-contoso-prod has public endpoint enabled |
Critical |
| 2.3 Key management |
⚠️ Needs attention |
2 secrets in kv-contoso-prod expire within 30 days |
High |
Top 5 recommendations
| # |
Recommendation |
Impact |
Effort |
| 1 |
Enable availability zones on production VMs |
Critical |
2 hours |
| 2 |
Disable public endpoint on SQL Server |
Critical |
30 min |
| 3 |
Configure ASR replication for rg-app-prod |
High |
4 hours |
| 4 |
Rotate expiring Key Vault secrets |
High |
1 hour |
| 5 |
Add autoscale rules to App Service plan asp-prod |
Medium |
30 min |
Remediation guidance (sample)
# Enable availability zones on VM (redeploy required)
az vm create --name vm-web-01 --resource-group rg-app-prod --zone 1 ...
# Disable public access on SQL Server
az sql server update --name sql-contoso-prod --resource-group rg-data-prod --set publicNetworkAccess="Disabled"
# Add autoscale rule to App Service plan
az monitor autoscale create --resource-group rg-app-prod --resource asp-prod --resource-type Microsoft.Web/serverfarms --min-count 2 --max-count 10 --count 2
1---2name: well-architected-review3description: Run a Well-Architected Framework (WAF) review against Azure resources in scope. Use when asked about best practices, architecture review, WAF assessment, or pillar compliance (Reliability, Security, Cost, Operational Excellence, Performance Efficiency).4---56# Well-Architected Review78## Purpose9Perform a structured assessment of Azure resources against the five pillars of the Microsoft Azure Well-Architected Framework. Produce a scored report with prioritized recommendations.1011## When to use this skill12- User asks "are we following best practices?"13- User asks for a WAF or Well-Architected review14- User wants to assess architecture quality before a launch or audit15- Periodic (quarterly) architecture health check1617## Pillars and checks1819### 1. Reliability20Run the following checks and report findings:21221. **Availability design**: Check if critical workloads use availability zones or availability sets23 ```bash24 az vm list --query "[].{name:name, zones:zones, availabilitySet:availabilitySet.id}" -o table25 az appservice plan list --query "[].{name:name, zoneRedundant:zoneRedundant, sku:sku.name}" -o table26 ```272. **Backup coverage**: Verify Recovery Services vaults and backup policies exist for VMs, databases, and file shares28 ```bash29 az backup vault list -o table30 ```31 Then for each vault:32 ```bash33 az backup item list --vault-name <vault> --resource-group <rg> --backup-management-type AzureIaasVM -o table34 ```353. **Disaster recovery**: Check for paired regions, ASR replication, or geo-redundant storage364. **Health probes**: Verify App Service health checks, load balancer probes, and Container Apps health endpoints375. **Auto-healing**: Check if App Service auto-heal rules or AKS pod disruption budgets are configured3839### 2. Security401. **Identity**: Check for managed identities vs. stored credentials41 ```bash42 az webapp identity show --name <app> --resource-group <rg>43 az ad app list --query "[].{name:displayName, passwordCredentials:passwordCredentials}" -o table44 ```452. **Network isolation**: Check for private endpoints, NSGs, and service endpoints46 ```bash47 az network private-endpoint list -o table48 az network nsg list -o table49 ```503. **Encryption**: Verify encryption at rest (storage, databases) and in transit (TLS)514. **Key management**: Check Key Vault usage and key/secret expiration dates52 ```bash53 az keyvault list -o table54 az keyvault secret list --vault-name <vault> --query "[].{name:name, expires:attributes.expires}" -o table55 ```565. **Defender for Cloud**: Check Secure Score and outstanding recommendations5758### 3. Cost Optimization591. **Rightsizing**: Identify underutilized VMs (CPU < 5% average over 14 days)602. **Orphaned resources**: Find unattached disks, unused public IPs, empty resource groups61 ```bash62 az disk list --query "[?managedBy==null].{name:name, size:diskSizeGb, rg:resourceGroup}" -o table63 az network public-ip list --query "[?ipConfiguration==null].{name:name, rg:resourceGroup}" -o table64 ```653. **Reservations**: Check if high-usage resources could benefit from reserved instances664. **Dev/Test pricing**: Verify non-production workloads use Dev/Test subscriptions or B-series VMs675. **Storage tiers**: Check if cool/archive tiers are used for infrequently accessed data6869### 4. Operational Excellence701. **IaC coverage**: Check for ARM/Bicep/Terraform templates in connected repos712. **Tagging**: Verify mandatory tags (environment, owner, cost-center) exist72 ```bash73 az resource list --query "[?tags.environment==null].{name:name, type:type, rg:resourceGroup}" -o table74 ```753. **Monitoring**: Check for alert rules, action groups, and diagnostic settings76 ```bash77 az monitor metrics alert list -o table78 az monitor diagnostic-settings list --resource <id> -o table79 ```804. **Deployment practices**: Check for deployment slots, blue-green, or canary configurations815. **Automation**: Check for runbooks, Logic Apps, or scheduled tasks for routine operations8283### 5. Performance Efficiency841. **Autoscaling**: Verify autoscale rules exist for App Service plans, VMSS, and Container Apps85 ```bash86 az monitor autoscale list --resource-group <rg> -o table87 ```88 Note: `az monitor autoscale list` requires `--resource-group`. Iterate over relevant resource groups, or use Azure Resource Graph:89 ```bash90 az graph query -q "resources | where type == 'microsoft.insights/autoscalesettings'" -o table91 ```922. **Caching**: Check for Redis Cache or CDN usage on high-traffic workloads933. **Database performance**: Check DTU/vCore utilization, index recommendations944. **Content delivery**: Verify static assets use CDN or Front Door955. **Connection pooling**: Check for connection string patterns suggesting missing pooling9697## Scoring model9899For each check, assign one of:100- ✅ **Pass** — follows best practice101- ⚠️ **Needs attention** — partially implemented or at risk102- ❌ **Fail** — not implemented, risk exposure103104## Accepted exceptions (optional)105106If the user provides a list of accepted exceptions, do not flag those items. Instead, note them in the report as **Accepted Exception** with the reason provided.107108Example format the user may provide:109110| Check | Reason |111|-------|--------|112| 1.1 Availability zones | Single-AZ by design to reduce cost |113| 3.3 Reserved instances | Short-term workload, reservations not applicable |114| 5.5 Connection pooling | Legacy app uses persistent connections by design |115116When exceptions are provided:117- Skip the flagged checks in scoring118- List them in a separate "Accepted Exceptions" section at the end of the report119- Recalculate the overall score excluding excepted checks120121## Expected output122123### Report header (mandatory — use this exact format)124125## Well-Architected Review Report126127| Field | Value |128|-------|-------|129| Subscription | (name + ID) |130| Assessment Date | YYYY-MM-DD |131| Overall Score | XX% |132133### Summary134A table with pillar scores:135136| Pillar | Pass | Needs Attention | Fail | Score |137|--------|------|----------------|------|-------|138| Reliability | X | Y | Z | X/(X+Y+Z) % |139| Security | ... | ... | ... | ... |140| Cost Optimization | ... | ... | ... | ... |141| Operational Excellence | ... | ... | ... | ... |142| Performance Efficiency | ... | ... | ... | ... |143| **Overall** | | | | **avg %** |144145### Detailed findings146For each pillar, list every check with:147- Status (pass/attention/fail)148- Evidence (command output or observation)149- Recommendation (specific action to take)150- Priority (Critical / High / Medium / Low)151- Reference link to WAF documentation152153### Top 5 recommendations154Ordered by impact, with estimated effort (hours/days) for each.155156### Remediation guidance157For each ❌ or ⚠️ finding, include in the output:1581. The specific `az` CLI command to remediate (suggest only — do not execute)1592. Use `GetAzCliHelp` to validate the command syntax before suggesting1603. The official Microsoft Learn documentation link for the remediation161162### References163- WAF Overview: https://learn.microsoft.com/en-us/azure/well-architected/164- Reliability: https://learn.microsoft.com/en-us/azure/well-architected/reliability/165- Security: https://learn.microsoft.com/en-us/azure/well-architected/security/166- Cost Optimization: https://learn.microsoft.com/en-us/azure/well-architected/cost-optimization/167- Operational Excellence: https://learn.microsoft.com/en-us/azure/well-architected/operational-excellence/168- Performance Efficiency: https://learn.microsoft.com/en-us/azure/well-architected/performance-efficiency/169170## Sample output171172> The following is a redacted example of what the report looks like when run against a subscription.173174## Well-Architected Review Report175176| Field | Value |177|-------|-------|178| Subscription | contoso-prod-001 (a1b2c3d4-e5f6-7890-abcd-ef1234567890) |179| Assessment Date | 2026-07-15 |180| Overall Score | 68% |181182### Summary183184| Pillar | Pass | Needs Attention | Fail | Score |185|--------|------|----------------|------|-------|186| Reliability | 3 | 1 | 1 | 60% |187| Security | 2 | 2 | 1 | 40% |188| Cost Optimization | 4 | 1 | 0 | 80% |189| Operational Excellence | 3 | 1 | 1 | 60% |190| Performance Efficiency | 4 | 0 | 1 | 80% |191| **Overall** | **16** | **5** | **4** | **68%** |192193### Detailed findings (sample)194195#### Reliability196197| Check | Status | Evidence | Priority |198|-------|--------|----------|----------|199| 1.1 Availability zones | ❌ Fail | VMs `vm-web-01`, `vm-web-02` in `rg-app-prod` have no zones configured | Critical |200| 1.2 Backup coverage | ✅ Pass | Recovery Services vault `rsv-prod-eastus` protects 4/4 VMs | — |201| 1.3 Disaster recovery | ⚠️ Needs attention | No ASR replication configured for `rg-app-prod` | High |202203#### Security204205| Check | Status | Evidence | Priority |206|-------|--------|----------|----------|207| 2.1 Managed identity | ✅ Pass | App Service `app-api-prod` uses System-Assigned MI | — |208| 2.2 Network isolation | ❌ Fail | SQL Server `sql-contoso-prod` has public endpoint enabled | Critical |209| 2.3 Key management | ⚠️ Needs attention | 2 secrets in `kv-contoso-prod` expire within 30 days | High |210211### Top 5 recommendations212213| # | Recommendation | Impact | Effort |214|---|---------------|--------|--------|215| 1 | Enable availability zones on production VMs | Critical | 2 hours |216| 2 | Disable public endpoint on SQL Server | Critical | 30 min |217| 3 | Configure ASR replication for `rg-app-prod` | High | 4 hours |218| 4 | Rotate expiring Key Vault secrets | High | 1 hour |219| 5 | Add autoscale rules to App Service plan `asp-prod` | Medium | 30 min |220221### Remediation guidance (sample)222223```bash224# Enable availability zones on VM (redeploy required)225az vm create --name vm-web-01 --resource-group rg-app-prod --zone 1 ...226227# Disable public access on SQL Server228az sql server update --name sql-contoso-prod --resource-group rg-data-prod --set publicNetworkAccess="Disabled"229230# Add autoscale rule to App Service plan231az monitor autoscale create --resource-group rg-app-prod --resource asp-prod --resource-type Microsoft.Web/serverfarms --min-count 2 --max-count 10 --count 2232```