Azure Defaults Skill
Single source of truth for all Azure infrastructure configuration used across agents.
Replaces individual _shared/ file lookups with one consolidated reference.
Quick Reference (Load First)
Default Regions
| Service |
Default Region |
Reason |
| All resources |
swedencentral |
EU GDPR-compliant |
| Static Web Apps |
westeurope |
Not available in swedencentral |
| Azure OpenAI |
swedencentral |
Limited availability — verify first |
| Failover |
germanywestcentral |
EU paired alternative |
Required Tags (Azure Policy Enforced)
[!IMPORTANT]
These 4 tags are the MINIMUM baseline. Azure Policy in your subscription may enforce
additional tags. Always defer to 04-governance-constraints.md for the actual required tag list.
| Tag |
Required |
Example Values |
Environment |
Yes |
dev, staging, prod |
ManagedBy |
Yes |
Bicep |
Project |
Yes |
Project identifier |
Owner |
Yes |
Team or individual name |
Bicep pattern:
tags: {
Environment: environment
ManagedBy: 'Bicep'
Project: projectName
Owner: owner
}
Unique Suffix Pattern
Generate ONCE in main.bicep, pass to ALL modules:
// main.bicep
var uniqueSuffix = uniqueString(resourceGroup().id)
module keyVault 'modules/key-vault.bicep' = {
params: { uniqueSuffix: uniqueSuffix }
}
Security Baseline
| Setting |
Value |
Applies To |
supportsHttpsTrafficOnly |
true |
Storage accounts |
minimumTlsVersion |
'TLS1_2' |
All services |
allowBlobPublicAccess |
false |
Storage accounts |
publicNetworkAccess |
'Disabled' (prod) |
Data services |
| Authentication |
Managed Identity |
Prefer over keys/strings |
| SQL Auth |
Azure AD-only |
azureADOnlyAuthentication: true |
CAF Naming Conventions
Standard Abbreviations
| Resource |
Abbreviation |
Name Pattern |
Max Length |
| Resource Group |
rg |
rg-{project}-{env} |
90 |
| Virtual Network |
vnet |
vnet-{project}-{env} |
64 |
| Subnet |
snet |
snet-{purpose}-{env} |
80 |
| NSG |
nsg |
nsg-{purpose}-{env} |
80 |
| Key Vault |
kv |
kv-{short}-{env}-{suffix} |
24 |
| Storage Account |
st |
st{short}{env}{suffix} |
24 |
| App Service Plan |
asp |
asp-{project}-{env} |
40 |
| App Service |
app |
app-{project}-{env} |
60 |
| SQL Server |
sql |
sql-{project}-{env} |
63 |
| SQL Database |
sqldb |
sqldb-{project}-{env} |
128 |
| Static Web App |
stapp |
stapp-{project}-{env} |
40 |
| CDN / Front Door |
fd |
fd-{project}-{env} |
64 |
| Log Analytics |
log |
log-{project}-{env} |
63 |
| App Insights |
appi |
appi-{project}-{env} |
255 |
| Container App |
ca |
ca-{project}-{env} |
32 |
| Container Env |
cae |
cae-{project}-{env} |
60 |
| Cosmos DB |
cosmos |
cosmos-{project}-{env} |
44 |
| Service Bus |
sb |
sb-{project}-{env} |
50 |
Length-Constrained Resources
Key Vault and Storage Account have 24-char limits. Always include uniqueSuffix:
// Key Vault: kv-{8chars}-{3chars}-{6chars} = 21 chars max
var kvName = 'kv-${take(projectName, 8)}-${take(environment, 3)}-${take(uniqueSuffix, 6)}'
// Storage: st{8chars}{3chars}{6chars} = 19 chars max (no hyphens!)
var stName = 'st${take(replace(projectName, '-', ''), 8)}${take(environment, 3)}${take(uniqueSuffix, 6)}'
Naming Rules
- DO: Use lowercase with hyphens (
kv-myapp-dev-abc123)
- DO: Include
uniqueSuffix in globally unique names (Key Vault, Storage, SQL Server)
- DO: Use
take() to truncate long names within limits
- DON'T: Use hyphens in Storage Account names (only lowercase + numbers)
- DON'T: Hardcode unique values — always derive from
uniqueString(resourceGroup().id)
- DON'T: Exceed max length — Bicep won't warn, deployment will fail
Azure Verified Modules (AVM)
AVM-First Policy
- ALWAYS check AVM availability first via
mcp_bicep_list_avm_metadata
- Use AVM module defaults for SKUs when available
- If custom SKU needed, require live deprecation research
- NEVER hardcode SKUs without validation
- NEVER write raw Bicep for a resource that has an AVM module
Common AVM Modules
| Resource |
Module Path |
Min Version |
| Key Vault |
br/public:avm/res/key-vault/vault |
0.11.0 |
| Virtual Network |
br/public:avm/res/network/virtual-network |
0.5.0 |
| Storage Account |
br/public:avm/res/storage/storage-account |
0.14.0 |
| App Service Plan |
br/public:avm/res/web/serverfarm |
0.4.0 |
| App Service |
br/public:avm/res/web/site |
0.12.0 |
| SQL Server |
br/public:avm/res/sql/server |
0.10.0 |
| Log Analytics |
br/public:avm/res/operational-insights/workspace |
0.9.0 |
| App Insights |
br/public:avm/res/insights/component |
0.4.0 |
| NSG |
br/public:avm/res/network/network-security-group |
0.5.0 |
| Static Web App |
br/public:avm/res/web/static-site |
0.4.0 |
| Container App |
br/public:avm/res/app/container-app |
0.11.0 |
| Container Env |
br/public:avm/res/app/managed-environment |
0.8.0 |
| Cosmos DB |
br/public:avm/res/document-db/database-account |
0.10.0 |
| Front Door |
br/public:avm/res/cdn/profile |
0.7.0 |
| Service Bus |
br/public:avm/res/service-bus/namespace |
0.10.0 |
| Container Registry |
br/public:avm/res/container-registry/registry |
0.6.0 |
Finding Latest AVM Version
// Use Bicep MCP tool:
mcp_bicep_list_avm_metadata → filter by resource type → use latest version
// Or check: https://aka.ms/avm/index
AVM Usage Pattern
module keyVault 'br/public:avm/res/key-vault/vault:0.11.0' = {
name: '${kvName}-deploy'
params: {
name: kvName
location: location
tags: tags
enableRbacAuthorization: true
enablePurgeProtection: true
}
}
AVM Known Pitfalls
Region Limitations
| Service |
Limitation |
Workaround |
| Static Web Apps |
Only 5 regions: westus2, centralus, eastus2, westeurope, eastasia |
Use westeurope for EU |
| Azure OpenAI |
Limited regions per model |
Check availability before planning |
| Container Apps |
Most regions but not all |
Verify cae environment in target region |
Parameter Type Mismatches
Known issues when using AVM modules — verify before coding:
Log Analytics Workspace (operational-insights/workspace):
dailyQuotaGb is int in AVM, not string
- DO:
dailyQuotaGb: 5
- DON'T:
dailyQuotaGb: '5'
Container Apps Managed Environment (app/managed-environment):
appLogsConfiguration deprecated in newer versions
- DO: Use
logsConfiguration with destination object
- DON'T: Use
appLogsConfiguration.destination: 'log-analytics'
Container Apps (app/container-app):
scaleSettings is an object, not array of rules
- DO: Check AVM schema for exact object shape
- DON'T: Assume
scaleRules: [...] array format
SQL Server (sql/server):
sku parameter is a typed object {name, tier, capacity}
- DO: Pass full SKU object matching schema
- DON'T: Pass just string
'S0'
availabilityZone requires specific format per region
App Service (web/site):
APPINSIGHTS_INSTRUMENTATIONKEY deprecated
- DO: Use
APPLICATIONINSIGHTS_CONNECTION_STRING instead
- DON'T: Set instrumentation key directly
Key Vault (key-vault/vault):
softDeleteRetentionInDays is immutable after creation
- DO: Set correctly on first deploy (default: 90)
- DON'T: Try to change after vault exists
Static Web App (web/static-site):
- Free SKU may not be deployable via ARM in all regions
- DO: Use
Standard SKU for reliable ARM deployment
- DON'T: Assume Free tier works everywhere via Bicep
WAF Assessment Criteria
Scoring Scale
| Score |
Definition |
| 9-10 |
Exceeds best practices, production-ready |
| 7-8 |
Meets best practices with minor gaps |
| 5-6 |
Adequate but improvements needed |
| 3-4 |
Significant gaps, address before production |
| 1-2 |
Critical deficiencies, not production-ready |
Pillar Definitions
| Pillar |
Icon |
Focus Areas |
| Security |
🔒 |
Identity, network, data protection, threat detection |
| Reliability |
🔄 |
SLA, redundancy, disaster recovery, health monitoring |
| Performance |
⚡ |
Response time, scalability, caching, load testing |
| Cost |
💰 |
Right-sizing, reserved instances, monitoring spend |
| Operations |
🔧 |
IaC, CI/CD, monitoring, incident response, documentation |
Assessment Rules
- DO: Score each pillar 1-10 with confidence level (High/Medium/Low)
- DO: Identify specific gaps with remediation recommendations
- DO: Calculate composite WAF score as average of all pillars
- DON'T: Give perfect 10/10 scores without exceptional justification
- DON'T: Skip any pillar even if requirements seem light
- DON'T: Provide generic recommendations — be specific to the workload
Azure Pricing MCP Service Names
Exact names for the Azure Pricing MCP tool. Using wrong names returns 0 results.
| Azure Service |
Correct service_name |
Common SKUs |
| AKS |
Azure Kubernetes Service |
Free, Standard, Premium |
| API Management |
API Management |
Consumption, Developer, Standard |
| App Insights |
Application Insights |
Enterprise, Basic |
| App Service |
Azure App Service |
B1, S1, P1v3, P1v4 |
| Application Gateway |
Application Gateway |
Standard_v2, WAF_v2 |
| Azure Bastion |
Azure Bastion |
Basic, Standard |
| Azure DNS |
Azure DNS |
Public, Private |
| Azure Firewall |
Azure Firewall |
Standard, Premium |
| Azure Functions |
Functions |
Consumption, Premium |
| Azure Monitor |
Azure Monitor |
Logs, Metrics |
| Container Apps |
Azure Container Apps |
Consumption |
| Container Instances |
Container Instances |
Standard |
| Container Registry |
Container Registry |
Basic, Standard, Premium |
| Cosmos DB |
Azure Cosmos DB |
Serverless, Provisioned |
| Data Factory |
Azure Data Factory v2 |
Data Flow, Pipeline |
| Event Grid |
Event Grid |
Basic |
| Event Hubs |
Event Hubs |
Basic, Standard, Premium |
| Front Door |
Azure Front Door |
Standard, Premium |
| Key Vault |
Key Vault |
Standard |
| Load Balancer |
Load Balancer |
Basic, Standard |
| Log Analytics |
Log Analytics |
Per GB, Commitment Tier |
| Logic Apps |
Logic Apps |
Consumption, Standard |
| MySQL Flexible |
Azure Database for MySQL |
B1ms, D2ds_v4, E2ds_v4 |
| NAT Gateway |
NAT Gateway |
Standard |
| PostgreSQL Flexible |
Azure Database for PostgreSQL |
B1ms, D2ds_v4, E2ds_v4 |
| Redis Cache |
Azure Cache for Redis |
Basic, Standard, Premium |
| SQL Database |
SQL Database |
Basic, Standard, S0, S1, Premium |
| Service Bus |
Service Bus |
Basic, Standard, Premium |
| Static Web Apps |
Azure Static Web Apps |
Free, Standard |
| Storage |
Storage |
Standard, Premium, LRS, GRS |
| VPN Gateway |
VPN Gateway |
Basic, VpnGw1, VpnGw2 |
| Virtual Machines |
Virtual Machines |
D4s_v5, B2s, E4s_v5 |
- DO: Use exact names from the table above
- DON'T: Use "Azure SQL" (returns 0 results) — use "SQL Database"
- DON'T: Use "Web App" — use "Azure App Service"
Bulk Estimates
For multi-resource cost estimates, prefer azure_bulk_estimate over calling azure_cost_estimate
per resource. It accepts a resources array and returns aggregated totals.
Each resource supports a quantity parameter (default: 1) for multi-instance scenarios.
Use output_format: "compact" to reduce response size when detailed metadata is not needed.
Service Recommendation Matrix
Workload Patterns
| Pattern |
Cost-Optimized Tier |
Balanced Tier |
Enterprise Tier |
| Static Site |
SWA Free + Blob |
SWA Std + CDN + KV |
SWA Std + FD + KV + Monitor |
| API-First |
App Svc B1 + SQL Basic |
App Svc S1 + SQL S1 + KV |
App Svc P1v3 + SQL Premium + APIM |
| N-Tier Web |
App Svc B1 + SQL Basic |
App Svc S1 + SQL S1 + Redis + KV |
App Svc P1v4 + SQL Premium + Redis + FD |
| Serverless |
Functions Consumption |
Functions Premium + CosmosDB |
Functions Premium + CosmosDB + APIM |
| Container |
Container Apps Consumption |
Container Apps + ACR + KV |
AKS + ACR + KV + Monitor |
| Data Platform |
SQL Basic + Blob |
Synapse Serverless + ADLS |
Synapse Dedicated + ADLS + Purview |
Detection Signals
Map user language to workload pattern:
| User Says |
Likely Pattern |
| "website", "landing page", "blog" |
Static Site |
| "REST API", "microservices", "backend" |
API-First |
| "web app", "portal", "dashboard" |
N-Tier Web |
| "event-driven", "triggers", "webhooks" |
Serverless |
| "Docker", "Kubernetes", "containers" |
Container |
| "analytics", "data warehouse", "ETL" |
Data Platform |
Business Domain Signals
| Industry |
Common Compliance |
Default Security |
| Healthcare |
HIPAA |
Private endpoints, encryption at rest |
| Financial |
PCI-DSS, SOC 2 |
WAF, private endpoints, audit logging |
| Government |
FedRAMP, IL4/5 |
Azure Gov, private endpoints |
| Retail/E-commerce |
PCI-DSS |
WAF, DDoS protection |
| Education |
FERPA |
Data residency, access controls |
Company Size Heuristics
| Size |
Budget Signal |
Default Tier |
Security Posture |
| Startup (<50) |
"$50-200/mo" |
Cost-Optimized |
Basic managed identity |
| Mid-Market (50-500) |
"$500-2000/mo" |
Balanced |
Private endpoints, KV |
| Enterprise (500+) |
"$2000+/mo" |
Enterprise |
Full WAF compliance |
Industry Compliance Pre-Selection
| Industry |
Auto-Select |
| Healthcare |
HIPAA checkbox, private endpoints |
| Finance |
PCI-DSS + SOC 2, WAF required |
| Government |
Data residency, enhanced audit |
| Retail |
PCI-DSS if payments, DDoS |
Governance Discovery
MANDATORY Gate
Governance discovery is a hard gate. If Azure connectivity is unavailable or policies cannot
be fully retrieved (including management group-inherited), STOP and inform the user.
Do NOT proceed to implementation planning with incomplete policy data.
Discovery Commands (Ordered by Completeness)
1. REST API (MANDATORY — includes management group-inherited policies):
SUB_ID=$(az account show --query id -o tsv)
az rest --method GET \
--url "https://management.azure.com/subscriptions/\
${SUB_ID}/providers/Microsoft.Authorization/\
policyAssignments?api-version=2022-06-01" \
--query "value[].{name:name, \
displayName:properties.displayName, \
scope:properties.scope, \
enforcementMode:properties.enforcementMode, \
policyDefinitionId:properties.policyDefinitionId}" \
-o json
[!CAUTION]
az policy assignment list only returns subscription-scoped assignments.
Management group policies (often Deny/tag enforcement) are invisible to it.
ALWAYS use the REST API above as the primary discovery method.
2. Policy Definition Drill-Down (for each Deny/DeployIfNotExists):
# For built-in or subscription-scoped policies
az policy definition show --name "{guid}" \
--query "{displayName:displayName, \
effect:policyRule.then.effect, \
conditions:policyRule.if}" -o json
# For management-group-scoped custom policies
az policy definition show --name "{guid}" \
--management-group "{mgId}" \
--query "{displayName:displayName, \
effect:policyRule.then.effect}" -o json
# For policy set definitions (initiatives)
az policy set-definition show --name "{guid}" \
--query "{displayName:displayName, \
policyCount:policyDefinitions | length(@)}" -o json
3. ARG KQL (supplemental — subscription-scoped only):
PolicyResources
| where type == 'microsoft.authorization/policyassignments'
| where properties.enforcementMode == 'Default'
| project name, displayName=properties.displayName,
effect=properties.parameters.effect.value,
scope=properties.scope
| order by name asc
Azure Policy Discovery Workflow
Before creating implementation plans, discover active policies:
1. Verify Azure connectivity: az account show
2. REST API: Get ALL effective policy assignments (subscription + MG inherited)
3. Compare count with Azure Portal (Policy > Assignments) — must match
4. For each Deny/DeployIfNotExists: drill into policy definition JSON
5. Check tag enforcement policies (names containing 'tag' or 'Tag')
6. Check allowed resource types and locations
7. Document ALL findings in 04-governance-constraints.md
Common Policy Constraints
[!NOTE]
The governance constraints JSON output schema must include bicepPropertyPath and
requiredValue fields for each Deny policy to enable downstream programmatic consumption
by the Code Generator and review subagent.
| Policy |
Impact |
Solution |
| Required tags |
Deployment fails without tags |
Include all 4 required tags |
| Allowed locations |
Resources rejected outside list |
Use swedencentral default |
| SQL AAD-only auth |
SQL password auth blocked |
Use azureADOnlyAuthentication: true |
| Storage shared key |
Shared key access denied |
Use managed identity RBAC |
| Zone redundancy |
Non-zonal SKUs rejected |
Use P1v4+ for App Service Plans |
Research Workflow (All Agents)
Standard 4-Step Pattern
- Validate Prerequisites — Confirm previous artifact exists. If missing, STOP.
- Read Agent Context — Read previous artifact for context. Read template for H2 structure.
- Domain-Specific Research — Query ONLY for NEW information not in artifacts.
- Confidence Gate (80% Rule) — Proceed at 80%+ confidence. Below 80%, ASK user.
Confidence Levels
| Level |
Indicators |
Action |
| High (80-100%) |
All critical info available |
Proceed |
| Medium (60-79%) |
Some assumptions needed |
Document assumptions, ask for critical gaps |
| Low (0-59%) |
Major gaps |
STOP — request clarification |
Context Reuse Rules
- DO: Read previous agent's artifact for context
- DO: Cache shared defaults (read once per session)
- DO: Query external sources only for NEW information
- DON'T: Re-query Azure docs for resources already in artifacts
- DON'T: Search workspace repeatedly (context flows via artifacts)
- DON'T: Re-validate previous agent's work (trust artifact chain)
Agent-Specific Research Focus
| Agent |
Primary Research |
Skip (Already in Artifacts) |
| Requirements |
User needs, business context |
— |
| Architect |
WAF gaps, SKU comparisons, pricing |
Service list (from 01) |
| Bicep Plan |
AVM availability, governance policies |
Architecture decisions (from 02) |
| Bicep Code |
AVM schemas, parameter types |
Resource list (from 04). NOTE: Governance constraints from 04-governance-constraints.md MUST still be read and enforced — "trust artifact chain" means accepting decisions, not skipping compliance checks. |
| Deploy |
Azure state (what-if), credentials |
Template structure (from 05) |
Service Lifecycle Validation
AVM Default Trust
When using AVM modules with default SKU parameters:
- Trust the AVM default — Microsoft maintains these
- No additional deprecation research needed for defaults
- If overriding SKU parameter, run deprecation research
Deprecation Research (For Non-AVM or Custom SKUs)
| Source |
Query Pattern |
Reliability |
| Azure Updates |
azure.microsoft.com/updates/?query={service}+deprecated |
High |
| Microsoft Learn |
Check "Important" / "Note" callouts on service pages |
High |
| Azure CLI |
az provider show --namespace {provider} for API versions |
Medium |
| Resource Provider |
Check available SKUs in target region |
High |
Known Deprecation Patterns
| Pattern |
Status |
Replacement |
| "Classic" anything |
DEPRECATED |
ARM equivalents |
CDN Standard_Microsoft |
DEPRECATED 2027 |
Azure Front Door |
| App Gateway v1 |
DEPRECATED |
App Gateway v2 |
| "v1" suffix services |
Likely deprecated |
Check for v2 |
| Old API versions (2020-xx) |
Outdated |
Use latest stable API |
What-If Deprecation Signals
Deploy agent should scan what-if output for:
deprecated|sunset|end.of.life|no.longer.supported|classic.*not.*supported|retiring
If detected, STOP and report before deployment.
Template-First Output Rules
Mandatory Compliance
| Rule |
Requirement |
| Exact text |
Use template H2 text verbatim |
| Exact order |
Required H2s appear in template-defined order |
| Anchor rule |
Extra sections allowed only AFTER last required H2 |
| No omissions |
All template H2s must appear in output |
| Attribution |
Include > Generated by {agent} agent | {YYYY-MM-DD} |
Output Location
All agent outputs go to agent-output/{project}/:
| Step |
Output File |
Agent |
| 1 |
01-requirements.md |
Requirements |
| 2 |
02-architecture-assessment.md |
Architect |
| 3 |
03-des-*.{py,md} |
Design |
| 4 |
04-implementation-plan.md |
Bicep Plan |
| 4 |
04-governance-constraints.md |
Bicep Plan |
| 4 |
04-preflight-check.md |
Bicep Code (pre-flight) |
| 5 |
05-implementation-reference.md |
Bicep Code |
| 6 |
06-deployment-summary.md |
Deploy |
| 7 |
07-*.md (7 documents) |
azure-artifacts skill |
Header Format
# Step {N}: {Title} - {project-name}
> Generated by {agent} agent | {YYYY-MM-DD}
Validation Checklist
Before completing any agent task, verify:
1---2name: azure-defaults-23description: Provides Azure defaults for naming, regions, tags, AVM-first modules, security baselines, WAF criteria, governance discovery, and pricing guidance across all agents.4license: MIT5---67# Azure Defaults Skill89Single source of truth for all Azure infrastructure configuration used across agents.10Replaces individual `_shared/` file lookups with one consolidated reference.1112---1314## Quick Reference (Load First)1516### Default Regions1718| Service | Default Region | Reason |19| ------------------- | -------------------- | ----------------------------------- |20| **All resources** | `swedencentral` | EU GDPR-compliant |21| **Static Web Apps** | `westeurope` | Not available in swedencentral |22| **Azure OpenAI** | `swedencentral` | Limited availability — verify first |23| **Failover** | `germanywestcentral` | EU paired alternative |2425### Required Tags (Azure Policy Enforced)2627> [!IMPORTANT]28> These 4 tags are the MINIMUM baseline. Azure Policy in your subscription may enforce29> additional tags. Always defer to `04-governance-constraints.md` for the actual required tag list.3031| Tag | Required | Example Values |32| ------------- | -------- | ------------------------ |33| `Environment` | Yes | `dev`, `staging`, `prod` |34| `ManagedBy` | Yes | `Bicep` |35| `Project` | Yes | Project identifier |36| `Owner` | Yes | Team or individual name |3738Bicep pattern:3940```bicep41tags: {42 Environment: environment43 ManagedBy: 'Bicep'44 Project: projectName45 Owner: owner46}47```4849### Unique Suffix Pattern5051Generate ONCE in `main.bicep`, pass to ALL modules:5253```bicep54// main.bicep55var uniqueSuffix = uniqueString(resourceGroup().id)5657module keyVault 'modules/key-vault.bicep' = {58 params: { uniqueSuffix: uniqueSuffix }59}60```6162### Security Baseline6364| Setting | Value | Applies To |65| -------------------------- | ------------------- | --------------------------------- |66| `supportsHttpsTrafficOnly` | `true` | Storage accounts |67| `minimumTlsVersion` | `'TLS1_2'` | All services |68| `allowBlobPublicAccess` | `false` | Storage accounts |69| `publicNetworkAccess` | `'Disabled'` (prod) | Data services |70| Authentication | Managed Identity | Prefer over keys/strings |71| SQL Auth | Azure AD-only | `azureADOnlyAuthentication: true` |7273---7475## CAF Naming Conventions7677### Standard Abbreviations7879| Resource | Abbreviation | Name Pattern | Max Length |80| ---------------- | ------------ | --------------------------- | ---------- |81| Resource Group | `rg` | `rg-{project}-{env}` | 90 |82| Virtual Network | `vnet` | `vnet-{project}-{env}` | 64 |83| Subnet | `snet` | `snet-{purpose}-{env}` | 80 |84| NSG | `nsg` | `nsg-{purpose}-{env}` | 80 |85| Key Vault | `kv` | `kv-{short}-{env}-{suffix}` | **24** |86| Storage Account | `st` | `st{short}{env}{suffix}` | **24** |87| App Service Plan | `asp` | `asp-{project}-{env}` | 40 |88| App Service | `app` | `app-{project}-{env}` | 60 |89| SQL Server | `sql` | `sql-{project}-{env}` | 63 |90| SQL Database | `sqldb` | `sqldb-{project}-{env}` | 128 |91| Static Web App | `stapp` | `stapp-{project}-{env}` | 40 |92| CDN / Front Door | `fd` | `fd-{project}-{env}` | 64 |93| Log Analytics | `log` | `log-{project}-{env}` | 63 |94| App Insights | `appi` | `appi-{project}-{env}` | 255 |95| Container App | `ca` | `ca-{project}-{env}` | 32 |96| Container Env | `cae` | `cae-{project}-{env}` | 60 |97| Cosmos DB | `cosmos` | `cosmos-{project}-{env}` | 44 |98| Service Bus | `sb` | `sb-{project}-{env}` | 50 |99100### Length-Constrained Resources101102Key Vault and Storage Account have 24-char limits. Always include `uniqueSuffix`:103104```bicep105// Key Vault: kv-{8chars}-{3chars}-{6chars} = 21 chars max106var kvName = 'kv-${take(projectName, 8)}-${take(environment, 3)}-${take(uniqueSuffix, 6)}'107108// Storage: st{8chars}{3chars}{6chars} = 19 chars max (no hyphens!)109var stName = 'st${take(replace(projectName, '-', ''), 8)}${take(environment, 3)}${take(uniqueSuffix, 6)}'110```111112### Naming Rules113114- **DO**: Use lowercase with hyphens (`kv-myapp-dev-abc123`)115- **DO**: Include `uniqueSuffix` in globally unique names (Key Vault, Storage, SQL Server)116- **DO**: Use `take()` to truncate long names within limits117- **DON'T**: Use hyphens in Storage Account names (only lowercase + numbers)118- **DON'T**: Hardcode unique values — always derive from `uniqueString(resourceGroup().id)`119- **DON'T**: Exceed max length — Bicep won't warn, deployment will fail120121---122123## Azure Verified Modules (AVM)124125### AVM-First Policy1261271. **ALWAYS** check AVM availability first via `mcp_bicep_list_avm_metadata`1282. Use AVM module defaults for SKUs when available1293. If custom SKU needed, require live deprecation research1304. **NEVER** hardcode SKUs without validation1315. **NEVER** write raw Bicep for a resource that has an AVM module132133### Common AVM Modules134135| Resource | Module Path | Min Version |136| ------------------ | -------------------------------------------------- | ----------- |137| Key Vault | `br/public:avm/res/key-vault/vault` | `0.11.0` |138| Virtual Network | `br/public:avm/res/network/virtual-network` | `0.5.0` |139| Storage Account | `br/public:avm/res/storage/storage-account` | `0.14.0` |140| App Service Plan | `br/public:avm/res/web/serverfarm` | `0.4.0` |141| App Service | `br/public:avm/res/web/site` | `0.12.0` |142| SQL Server | `br/public:avm/res/sql/server` | `0.10.0` |143| Log Analytics | `br/public:avm/res/operational-insights/workspace` | `0.9.0` |144| App Insights | `br/public:avm/res/insights/component` | `0.4.0` |145| NSG | `br/public:avm/res/network/network-security-group` | `0.5.0` |146| Static Web App | `br/public:avm/res/web/static-site` | `0.4.0` |147| Container App | `br/public:avm/res/app/container-app` | `0.11.0` |148| Container Env | `br/public:avm/res/app/managed-environment` | `0.8.0` |149| Cosmos DB | `br/public:avm/res/document-db/database-account` | `0.10.0` |150| Front Door | `br/public:avm/res/cdn/profile` | `0.7.0` |151| Service Bus | `br/public:avm/res/service-bus/namespace` | `0.10.0` |152| Container Registry | `br/public:avm/res/container-registry/registry` | `0.6.0` |153154### Finding Latest AVM Version155156```text157// Use Bicep MCP tool:158mcp_bicep_list_avm_metadata → filter by resource type → use latest version159160// Or check: https://aka.ms/avm/index161```162163### AVM Usage Pattern164165```bicep166module keyVault 'br/public:avm/res/key-vault/vault:0.11.0' = {167 name: '${kvName}-deploy'168 params: {169 name: kvName170 location: location171 tags: tags172 enableRbacAuthorization: true173 enablePurgeProtection: true174 }175}176```177178---179180## AVM Known Pitfalls181182### Region Limitations183184| Service | Limitation | Workaround |185| --------------- | --------------------------------------------------------------------------- | ----------------------------------------- |186| Static Web Apps | Only 5 regions: `westus2`, `centralus`, `eastus2`, `westeurope`, `eastasia` | Use `westeurope` for EU |187| Azure OpenAI | Limited regions per model | Check availability before planning |188| Container Apps | Most regions but not all | Verify `cae` environment in target region |189190### Parameter Type Mismatches191192Known issues when using AVM modules — verify before coding:193194**Log Analytics Workspace** (`operational-insights/workspace`):195196- `dailyQuotaGb` is `int` in AVM, not `string`197- **DO**: `dailyQuotaGb: 5`198- **DON'T**: `dailyQuotaGb: '5'`199200**Container Apps Managed Environment** (`app/managed-environment`):201202- `appLogsConfiguration` deprecated in newer versions203- **DO**: Use `logsConfiguration` with destination object204- **DON'T**: Use `appLogsConfiguration.destination: 'log-analytics'`205206**Container Apps** (`app/container-app`):207208- `scaleSettings` is an object, not array of rules209- **DO**: Check AVM schema for exact object shape210- **DON'T**: Assume `scaleRules: [...]` array format211212**SQL Server** (`sql/server`):213214- `sku` parameter is a typed object `{name, tier, capacity}`215- **DO**: Pass full SKU object matching schema216- **DON'T**: Pass just string `'S0'`217- `availabilityZone` requires specific format per region218219**App Service** (`web/site`):220221- `APPINSIGHTS_INSTRUMENTATIONKEY` deprecated222- **DO**: Use `APPLICATIONINSIGHTS_CONNECTION_STRING` instead223- **DON'T**: Set instrumentation key directly224225**Key Vault** (`key-vault/vault`):226227- `softDeleteRetentionInDays` is immutable after creation228- **DO**: Set correctly on first deploy (default: 90)229- **DON'T**: Try to change after vault exists230231**Static Web App** (`web/static-site`):232233- Free SKU may not be deployable via ARM in all regions234- **DO**: Use `Standard` SKU for reliable ARM deployment235- **DON'T**: Assume Free tier works everywhere via Bicep236237---238239## WAF Assessment Criteria240241### Scoring Scale242243| Score | Definition |244| ----- | ------------------------------------------- |245| 9-10 | Exceeds best practices, production-ready |246| 7-8 | Meets best practices with minor gaps |247| 5-6 | Adequate but improvements needed |248| 3-4 | Significant gaps, address before production |249| 1-2 | Critical deficiencies, not production-ready |250251### Pillar Definitions252253| Pillar | Icon | Focus Areas |254| ----------- | ---- | -------------------------------------------------------- |255| Security | 🔒 | Identity, network, data protection, threat detection |256| Reliability | 🔄 | SLA, redundancy, disaster recovery, health monitoring |257| Performance | ⚡ | Response time, scalability, caching, load testing |258| Cost | 💰 | Right-sizing, reserved instances, monitoring spend |259| Operations | 🔧 | IaC, CI/CD, monitoring, incident response, documentation |260261### Assessment Rules262263- **DO**: Score each pillar 1-10 with confidence level (High/Medium/Low)264- **DO**: Identify specific gaps with remediation recommendations265- **DO**: Calculate composite WAF score as average of all pillars266- **DON'T**: Give perfect 10/10 scores without exceptional justification267- **DON'T**: Skip any pillar even if requirements seem light268- **DON'T**: Provide generic recommendations — be specific to the workload269270---271272## Azure Pricing MCP Service Names273274Exact names for the Azure Pricing MCP tool. Using wrong names returns 0 results.275276| Azure Service | Correct `service_name` | Common SKUs |277| ------------------- | ------------------------------- | ------------------------------------------ |278| AKS | `Azure Kubernetes Service` | `Free`, `Standard`, `Premium` |279| API Management | `API Management` | `Consumption`, `Developer`, `Standard` |280| App Insights | `Application Insights` | `Enterprise`, `Basic` |281| App Service | `Azure App Service` | `B1`, `S1`, `P1v3`, `P1v4` |282| Application Gateway | `Application Gateway` | `Standard_v2`, `WAF_v2` |283| Azure Bastion | `Azure Bastion` | `Basic`, `Standard` |284| Azure DNS | `Azure DNS` | `Public`, `Private` |285| Azure Firewall | `Azure Firewall` | `Standard`, `Premium` |286| Azure Functions | `Functions` | `Consumption`, `Premium` |287| Azure Monitor | `Azure Monitor` | `Logs`, `Metrics` |288| Container Apps | `Azure Container Apps` | `Consumption` |289| Container Instances | `Container Instances` | `Standard` |290| Container Registry | `Container Registry` | `Basic`, `Standard`, `Premium` |291| Cosmos DB | `Azure Cosmos DB` | `Serverless`, `Provisioned` |292| Data Factory | `Azure Data Factory v2` | `Data Flow`, `Pipeline` |293| Event Grid | `Event Grid` | `Basic` |294| Event Hubs | `Event Hubs` | `Basic`, `Standard`, `Premium` |295| Front Door | `Azure Front Door` | `Standard`, `Premium` |296| Key Vault | `Key Vault` | `Standard` |297| Load Balancer | `Load Balancer` | `Basic`, `Standard` |298| Log Analytics | `Log Analytics` | `Per GB`, `Commitment Tier` |299| Logic Apps | `Logic Apps` | `Consumption`, `Standard` |300| MySQL Flexible | `Azure Database for MySQL` | `B1ms`, `D2ds_v4`, `E2ds_v4` |301| NAT Gateway | `NAT Gateway` | `Standard` |302| PostgreSQL Flexible | `Azure Database for PostgreSQL` | `B1ms`, `D2ds_v4`, `E2ds_v4` |303| Redis Cache | `Azure Cache for Redis` | `Basic`, `Standard`, `Premium` |304| SQL Database | `SQL Database` | `Basic`, `Standard`, `S0`, `S1`, `Premium` |305| Service Bus | `Service Bus` | `Basic`, `Standard`, `Premium` |306| Static Web Apps | `Azure Static Web Apps` | `Free`, `Standard` |307| Storage | `Storage` | `Standard`, `Premium`, `LRS`, `GRS` |308| VPN Gateway | `VPN Gateway` | `Basic`, `VpnGw1`, `VpnGw2` |309| Virtual Machines | `Virtual Machines` | `D4s_v5`, `B2s`, `E4s_v5` |310311- **DO**: Use exact names from the table above312- **DON'T**: Use "Azure SQL" (returns 0 results) — use "SQL Database"313- **DON'T**: Use "Web App" — use "Azure App Service"314315### Bulk Estimates316317For multi-resource cost estimates, prefer `azure_bulk_estimate` over calling `azure_cost_estimate`318per resource. It accepts a `resources` array and returns aggregated totals.319320Each resource supports a `quantity` parameter (default: 1) for multi-instance scenarios.321Use `output_format: "compact"` to reduce response size when detailed metadata is not needed.322323---324325## Service Recommendation Matrix326327### Workload Patterns328329| Pattern | Cost-Optimized Tier | Balanced Tier | Enterprise Tier |330| ----------------- | -------------------------- | -------------------------------- | --------------------------------------- |331| **Static Site** | SWA Free + Blob | SWA Std + CDN + KV | SWA Std + FD + KV + Monitor |332| **API-First** | App Svc B1 + SQL Basic | App Svc S1 + SQL S1 + KV | App Svc P1v3 + SQL Premium + APIM |333| **N-Tier Web** | App Svc B1 + SQL Basic | App Svc S1 + SQL S1 + Redis + KV | App Svc P1v4 + SQL Premium + Redis + FD |334| **Serverless** | Functions Consumption | Functions Premium + CosmosDB | Functions Premium + CosmosDB + APIM |335| **Container** | Container Apps Consumption | Container Apps + ACR + KV | AKS + ACR + KV + Monitor |336| **Data Platform** | SQL Basic + Blob | Synapse Serverless + ADLS | Synapse Dedicated + ADLS + Purview |337338### Detection Signals339340Map user language to workload pattern:341342| User Says | Likely Pattern |343| -------------------------------------- | -------------- |344| "website", "landing page", "blog" | Static Site |345| "REST API", "microservices", "backend" | API-First |346| "web app", "portal", "dashboard" | N-Tier Web |347| "event-driven", "triggers", "webhooks" | Serverless |348| "Docker", "Kubernetes", "containers" | Container |349| "analytics", "data warehouse", "ETL" | Data Platform |350351### Business Domain Signals352353| Industry | Common Compliance | Default Security |354| ----------------- | ----------------- | ------------------------------------- |355| Healthcare | HIPAA | Private endpoints, encryption at rest |356| Financial | PCI-DSS, SOC 2 | WAF, private endpoints, audit logging |357| Government | FedRAMP, IL4/5 | Azure Gov, private endpoints |358| Retail/E-commerce | PCI-DSS | WAF, DDoS protection |359| Education | FERPA | Data residency, access controls |360361### Company Size Heuristics362363| Size | Budget Signal | Default Tier | Security Posture |364| ------------------- | -------------- | -------------- | ---------------------- |365| Startup (<50) | "$50-200/mo" | Cost-Optimized | Basic managed identity |366| Mid-Market (50-500) | "$500-2000/mo" | Balanced | Private endpoints, KV |367| Enterprise (500+) | "$2000+/mo" | Enterprise | Full WAF compliance |368369### Industry Compliance Pre-Selection370371| Industry | Auto-Select |372| ---------- | --------------------------------- |373| Healthcare | HIPAA checkbox, private endpoints |374| Finance | PCI-DSS + SOC 2, WAF required |375| Government | Data residency, enhanced audit |376| Retail | PCI-DSS if payments, DDoS |377378---379380## Governance Discovery381382### MANDATORY Gate383384Governance discovery is a **hard gate**. If Azure connectivity is unavailable or policies cannot385be fully retrieved (including management group-inherited), STOP and inform the user.386Do NOT proceed to implementation planning with incomplete policy data.387388### Discovery Commands (Ordered by Completeness)389390**1. REST API (MANDATORY — includes management group-inherited policies)**:391392```bash393SUB_ID=$(az account show --query id -o tsv)394az rest --method GET \395 --url "https://management.azure.com/subscriptions/\396${SUB_ID}/providers/Microsoft.Authorization/\397policyAssignments?api-version=2022-06-01" \398 --query "value[].{name:name, \399displayName:properties.displayName, \400scope:properties.scope, \401enforcementMode:properties.enforcementMode, \402policyDefinitionId:properties.policyDefinitionId}" \403 -o json404```405406> [!CAUTION]407> `az policy assignment list` only returns subscription-scoped assignments.408> Management group policies (often Deny/tag enforcement) are invisible to it.409> **ALWAYS use the REST API above as the primary discovery method.**410411**2. Policy Definition Drill-Down (for each Deny/DeployIfNotExists)**:412413```bash414# For built-in or subscription-scoped policies415az policy definition show --name "{guid}" \416 --query "{displayName:displayName, \417effect:policyRule.then.effect, \418conditions:policyRule.if}" -o json419420# For management-group-scoped custom policies421az policy definition show --name "{guid}" \422 --management-group "{mgId}" \423 --query "{displayName:displayName, \424effect:policyRule.then.effect}" -o json425426# For policy set definitions (initiatives)427az policy set-definition show --name "{guid}" \428 --query "{displayName:displayName, \429policyCount:policyDefinitions | length(@)}" -o json430```431432**3. ARG KQL (supplemental — subscription-scoped only)**:433434```kusto435PolicyResources436| where type == 'microsoft.authorization/policyassignments'437| where properties.enforcementMode == 'Default'438| project name, displayName=properties.displayName,439 effect=properties.parameters.effect.value,440 scope=properties.scope441| order by name asc442```443444### Azure Policy Discovery Workflow445446Before creating implementation plans, discover active policies:447448```text4491. Verify Azure connectivity: az account show4502. REST API: Get ALL effective policy assignments (subscription + MG inherited)4513. Compare count with Azure Portal (Policy > Assignments) — must match4524. For each Deny/DeployIfNotExists: drill into policy definition JSON4535. Check tag enforcement policies (names containing 'tag' or 'Tag')4546. Check allowed resource types and locations4557. Document ALL findings in 04-governance-constraints.md456```457458### Common Policy Constraints459460> [!NOTE]461> The governance constraints JSON output schema must include `bicepPropertyPath` and462> `requiredValue` fields for each Deny policy to enable downstream programmatic consumption463> by the Code Generator and review subagent.464465| Policy | Impact | Solution |466| ------------------ | ------------------------------- | ------------------------------------- |467| Required tags | Deployment fails without tags | Include all 4 required tags |468| Allowed locations | Resources rejected outside list | Use `swedencentral` default |469| SQL AAD-only auth | SQL password auth blocked | Use `azureADOnlyAuthentication: true` |470| Storage shared key | Shared key access denied | Use managed identity RBAC |471| Zone redundancy | Non-zonal SKUs rejected | Use P1v4+ for App Service Plans |472473---474475## Research Workflow (All Agents)476477### Standard 4-Step Pattern4784791. **Validate Prerequisites** — Confirm previous artifact exists. If missing, STOP.4802. **Read Agent Context** — Read previous artifact for context. Read template for H2 structure.4813. **Domain-Specific Research** — Query ONLY for NEW information not in artifacts.4824. **Confidence Gate (80% Rule)** — Proceed at 80%+ confidence. Below 80%, ASK user.483484### Confidence Levels485486| Level | Indicators | Action |487| --------------- | --------------------------- | ------------------------------------------- |488| High (80-100%) | All critical info available | Proceed |489| Medium (60-79%) | Some assumptions needed | Document assumptions, ask for critical gaps |490| Low (0-59%) | Major gaps | STOP — request clarification |491492### Context Reuse Rules493494- **DO**: Read previous agent's artifact for context495- **DO**: Cache shared defaults (read once per session)496- **DO**: Query external sources only for NEW information497- **DON'T**: Re-query Azure docs for resources already in artifacts498- **DON'T**: Search workspace repeatedly (context flows via artifacts)499- **DON'T**: Re-validate previous agent's work (trust artifact chain)500501### Agent-Specific Research Focus502503| Agent | Primary Research | Skip (Already in Artifacts) |504| ------------ | ------------------------------------- | -------------------------------- |505| Requirements | User needs, business context | — |506| Architect | WAF gaps, SKU comparisons, pricing | Service list (from 01) |507| Bicep Plan | AVM availability, governance policies | Architecture decisions (from 02) |508| Bicep Code | AVM schemas, parameter types | Resource list (from 04). NOTE: Governance constraints from `04-governance-constraints.md` MUST still be read and enforced — "trust artifact chain" means accepting decisions, not skipping compliance checks. |509| Deploy | Azure state (what-if), credentials | Template structure (from 05) |510511---512513## Service Lifecycle Validation514515### AVM Default Trust516517When using AVM modules with default SKU parameters:518519- Trust the AVM default — Microsoft maintains these520- No additional deprecation research needed for defaults521- If overriding SKU parameter, run deprecation research522523### Deprecation Research (For Non-AVM or Custom SKUs)524525| Source | Query Pattern | Reliability |526| ----------------- | ---------------------------------------------------------- | ----------- |527| Azure Updates | `azure.microsoft.com/updates/?query={service}+deprecated` | High |528| Microsoft Learn | Check "Important" / "Note" callouts on service pages | High |529| Azure CLI | `az provider show --namespace {provider}` for API versions | Medium |530| Resource Provider | Check available SKUs in target region | High |531532### Known Deprecation Patterns533534| Pattern | Status | Replacement |535| -------------------------- | ----------------- | --------------------- |536| "Classic" anything | DEPRECATED | ARM equivalents |537| CDN `Standard_Microsoft` | DEPRECATED 2027 | Azure Front Door |538| App Gateway v1 | DEPRECATED | App Gateway v2 |539| "v1" suffix services | Likely deprecated | Check for v2 |540| Old API versions (2020-xx) | Outdated | Use latest stable API |541542### What-If Deprecation Signals543544Deploy agent should scan what-if output for:545`deprecated|sunset|end.of.life|no.longer.supported|classic.*not.*supported|retiring`546547If detected, STOP and report before deployment.548549---550551## Template-First Output Rules552553### Mandatory Compliance554555| Rule | Requirement |556| ------------ | ------------------------------------------------------ |557| Exact text | Use template H2 text verbatim |558| Exact order | Required H2s appear in template-defined order |559| Anchor rule | Extra sections allowed only AFTER last required H2 |560| No omissions | All template H2s must appear in output |561| Attribution | Include `> Generated by {agent} agent \| {YYYY-MM-DD}` |562563### Output Location564565All agent outputs go to `agent-output/{project}/`:566567| Step | Output File | Agent |568| ---- | -------------------------------- | ----------------------- |569| 1 | `01-requirements.md` | Requirements |570| 2 | `02-architecture-assessment.md` | Architect |571| 3 | `03-des-*.{py,md}` | Design |572| 4 | `04-implementation-plan.md` | Bicep Plan |573| 4 | `04-governance-constraints.md` | Bicep Plan |574| 4 | `04-preflight-check.md` | Bicep Code (pre-flight) |575| 5 | `05-implementation-reference.md` | Bicep Code |576| 6 | `06-deployment-summary.md` | Deploy |577| 7 | `07-*.md` (7 documents) | azure-artifacts skill |578579### Header Format580581```markdown582# Step {N}: {Title} - {project-name}583584> Generated by {agent} agent | {YYYY-MM-DD}585```586587---588589## Validation Checklist590591Before completing any agent task, verify:592593- [ ] Output file saved to `agent-output/{project}/`594- [ ] All required H2 headings from template are present595- [ ] H2 headings match template text exactly596- [ ] All 4 required tags included in resource definitions597- [ ] Unique suffix used for globally unique names598- [ ] Security baseline settings applied599- [ ] Region defaults correct (swedencentral, or exception documented)600- [ ] Attribution header included with agent name and date