**UTILITY SKILL** — Reusable Azure Bicep patterns: hub-spoke, private endpoints, diagnostics, AVM composition. WHEN: "hub-spoke Bicep", "private endpoint module", "diagnostic settings", "AVM Bicep composition". USE FOR: Bicep template design, hub-spoke networking, private endpoint patterns, AVM modules. DO NOT USE FOR: Terraform code (use terraform-patterns), architecture decisions (use azure-adr), troubleshooting, diagram generation (use drawio).
75
92%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Reusable infrastructure patterns for Azure Bicep templates. Complements
iac-bicep-best-practices.instructions.md (style) and azure-defaults skill (naming, tags, regions).
Canonical sources — the security baseline, AVM-first mandate, naming conventions, required tags, and unique-suffix rule live in
azure-defaults/SKILL.mdandiac-policy-compliance.md. This skill restates the rules tersely below for IaC-output convenience only; in conflict, the canonical sources win.
| Pattern | When to Use | Reference |
|---|---|---|
| Hub-Spoke Networking | Multi-workload environments with shared services | hub-spoke-pattern |
| Private Endpoint Wiring | Any PaaS service requiring private connectivity | private-endpoint-pattern |
| Diagnostic Settings | Every deployed resource (mandatory) | common-patterns |
| Conditional Deployment | Optional resources controlled by parameters | common-patterns |
| Module Composition | Breaking main.bicep into reusable modules | common-patterns |
| Managed Identity Binding | Any service-to-service authentication | common-patterns |
| Budget & Cost Monitoring | Every deployment (mandatory) | budget-pattern |
| What-If / AVM Pitfalls | Pre-deployment validation & AVM gotchas | avm-pitfalls |
| Batch Bicep Formatting | After generating/editing the Bicep tree | npm run format:bicep -- infra/bicep/{project} (wraps bicep format) |
Every Bicep module in this repo follows the same input/output contract:
name, location, tags, logAnalyticsWorkspaceNameresourceId, resourceName, principalId (use .?principalId ?? '' so modules without managed identity still expose the output)Full code sample and rationale: references/module-interface.md.
Applying a pattern in a Bicep template:
references/*.md for the chosen pattern; do not load all at oncename/location/tags/logAnalyticsWorkspaceName in; resourceId/resourceName/principalId out)https://mcr.microsoft.com/v2/bicep/avm/res/{path}/tags/list) and pin the highest non-prerelease semver; never reuse a version from training data, a prior project, or references/avm-modules.md. Stale pins require a pin_policy.mode = "exception" block in 04-iac-contract.json (see azure-defaults skill). Enforced by npm run validate:avm-versions:freeze.az deployment group what-if and review for unexpected deletes, SKU downgrades, or auth changesbicep build + bicep lint + npm run validate:iac-security-baselinecategoryGroup: 'allLogs' + AllMetrics; pass workspace name not IDbool params with defaults; guard outputs with ternaryguid() for idempotent role names; principalType: 'ServicePrincipal'; scope narrowlytags/list); wrap modules to override defaults; verify outputs in README. Stale pins require a pin_policy exception block — see azure-defaults skill.mcr.microsoft.com/v2/bicep/{module}/tags/list) is authoritative.
Helpers and doc tables are NOT — they go stale. Validator: npm run validate:avm-versions.mcr.microsoft.com/v2/bicep/{module}/tags/list for authoritative
published versions.scope: ARM ID split indexes — Splitting a full
resource ID (/subscriptions/{sub}/resourceGroups/{rg}/providers/...)
on / yields ['', 'subscriptions', '{sub}', 'resourceGroups', '{rg}', ...].
Subscription is at index 2, RG name is at index 4. Use:
scope: resourceGroup(split(resId, '/')[2], split(resId, '/')[4]).
Indexes [1]/[3] are the literals 'subscriptions'/'resourceGroups'
and only fail at az deployment ... validate time.insights/metric-alert:0.4.1+ requires criteria.allof[].name —
Each entry in criteria.allOf[] needs a name field; omission passes
bicep build but fails az deployment ... validate:
allOf: [{
name: 'HighCpu' // REQUIRED
metricName: 'Percentage CPU'
operator: 'GreaterThan'
threshold: 80
timeAggregation: 'Average'
}]bicep build poisons tree-hash folders — Running bicep build main.bicep
emits main.json next to the source. If the folder is hashed by
validate-iac-handoff.mjs, that compiled output drifts the hash. The
validator now excludes <stem>.json siblings of <stem>.bicep, but if
you must build manually inside a handoff tree, rm -f main.json
immediately after.| File | Content |
|---|---|
| hub-spoke-pattern.md | Hub-spoke VNet orchestration with peering |
| private-endpoint-pattern.md | PE wiring + DNS zone groups + group ID table |
| common-patterns.md | Diagnostics, conditional deploy, module composition, managed identity |
| budget-pattern.md | Consumption budget, forecast alerts, anomaly detection |
| avm-pitfalls.md | What-if interpretation, AVM gotchas, learn more links |
| module-interface.md | Canonical module input/output contract |
| Topic | How to Find |
|---|---|
| AVM module catalog | mcp_azure-mcp_documentation — command: "microsoft_docs_search", query: "Azure Verified Modules registry Bicep" |
| Resource type schema | mcp_azure-mcp_documentation — command: "microsoft_docs_search", query: "{resource-type} Bicep template reference" |
05d7617
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.