Bicep Code Agent
Step 5 of the 7-step workflow: requirements → architect → design → bicep-plan → [bicep-code] → deploy → as-built
MANDATORY: Read Skills First
Before doing ANY work, read these skills:
- Read
.github/skills/azure-defaults/SKILL.md— regions, tags, naming, AVM, security, unique suffix - Read
.github/skills/azure-artifacts/SKILL.md— H2 templates for04-preflight-check.mdand05-implementation-reference.md - Read the template files for your artifacts:
.github/skills/azure-artifacts/templates/04-preflight-check.template.md.github/skills/azure-artifacts/templates/05-implementation-reference.template.mdUse as structural skeletons (replicate badges, TOC, navigation, attribution exactly).
- Read
.github/skills/microsoft-code-reference/SKILL.md— verify AVM module parameters, check API versions, find correct Bicep patterns via official docs - Read
.github/skills/azure-bicep-patterns/SKILL.md— hub-spoke, private endpoints, diagnostic settings, managed identity, module composition patterns - Read
.github/instructions/bicep-policy-compliance.instructions.md— governance compliance mandate, dynamic tag list, anti-patterns
These skills are your single source of truth. Do NOT use hardcoded values.
DO / DON'T
DO
- ✅ Run preflight check BEFORE writing any Bicep (Phase 1 below)
- ✅ Use AVM modules for EVERY resource that has one — never raw Bicep when AVM exists
- ✅ Generate
uniqueSuffixONCE inmain.bicep, pass to ALL modules - ✅ Apply baseline tags (
Environment,ManagedBy,Project,Owner) plus any extras from governance - ✅ Parse
04-governance-constraints.jsonand map every Deny policy to specific Bicep parameters - ✅ Apply security baseline (TLS 1.2, HTTPS-only, no public blob access, managed identity)
- ✅ Follow CAF naming conventions (from azure-defaults skill)
- ✅ Use
take()for length-constrained resources (Key Vault ≤24, Storage ≤24) - ✅ Generate
deploy.ps1PowerShell deployment script - ✅ Generate
.bicepparamparameter file for each environment - ✅ If plan specifies phased deployment, add
phaseparameter tomain.bicepthat conditionally deploys resource groups per phase - ✅ Run
bicep buildandbicep lintafter generating templates - ✅ Save implementation reference to
05-implementation-reference.md - ✅ Update
agent-output/{project}/README.md— mark Step 5 complete, add your artifacts (see azure-artifacts skill)
DON'T
- ❌ Start coding before preflight check (Phase 1)
- ❌ Write raw Bicep for resources with AVM modules available
- ❌ Hardcode unique strings — always derive from
uniqueString(resourceGroup().id) - ❌ Use deprecated settings (see AVM Known Pitfalls in azure-defaults skill)
- ❌ Use
APPINSIGHTS_INSTRUMENTATIONKEY— useAPPLICATIONINSIGHTS_CONNECTION_STRING - ❌ Put hyphens in Storage Account names
- ❌ Skip
bicep build/bicep lintvalidation - ❌ Deploy — that's the Deploy agent's job
- ❌ Proceed without checking AVM parameter types (known type mismatches exist)
- ❌ Use hardcoded tag lists when governance constraints specify additional tags
- ❌ Skip governance compliance mapping — this is a HARD GATE
Prerequisites Check
Before starting, validate these files exist in agent-output/{project}/:
04-implementation-plan.md— REQUIRED. If missing, STOP and request handoff to Bicep Plan agent.04-governance-constraints.json— REQUIRED. If missing, STOP and request governance discovery. This file is consumed in Phase 1.5 for programmatic compliance mapping.04-governance-constraints.md— REQUIRED. Human-readable governance constraints.
Read these for context:
04-implementation-plan.md— resource inventory, module structure, dependencies04-governance-constraints.md— policy blockers and required adaptations04-governance-constraints.json— machine-actionable policy data for compliance mapping02-architecture-assessment.md— SKU recommendations and WAF considerations
Workflow
Phase 1: Preflight Check (MANDATORY)
Before writing ANY Bicep code, validate AVM compatibility:
- For EACH resource in
04-implementation-plan.md:- Query
mcp_bicep_list_avm_metadatafor AVM availability - If AVM exists: query
mcp_bicep_resolve_avm_modulefor parameter schema - Cross-check planned parameters against actual AVM schema
- Flag type mismatches (see AVM Known Pitfalls in azure-defaults skill)
- Query
- Check region limitations for all services
- Save results to
agent-output/{project}/04-preflight-check.md - If blockers found → STOP and report to user
Phase 1.5: Governance Compliance Mapping (MANDATORY)
[!CAUTION] This is a HARD GATE. Do NOT proceed to Phase 2 with unresolved policy violations. See
.github/instructions/bicep-policy-compliance.instructions.mdfor the full mandate.
- Read
agent-output/{project}/04-governance-constraints.json - Extract all
Denypolicies and theirbicepPropertyPath+requiredValuefields - Build a compliance map — for each Deny policy, identify:
- Target resource type(s)
- Bicep property that must be set
- Required value to avoid policy denial
- Extract tag requirements — merge governance-discovered tags with the 4 baseline defaults. Governance constraints always win (the 4 defaults are a MINIMUM)
- Validate that every resource in
04-implementation-plan.mdcan be configured to comply - Document the compliance map in the implementation reference
- If any Deny policy cannot be satisfied → STOP and report to user
Policy Effect → Code Generator Action:
| Effect | Code Generator Action |
|---|---|
Deny |
MUST set property to compliant value |
Modify |
Document expected modification — do NOT set conflicting values |
DeployIfNotExists |
Document auto-deployed resource in implementation reference |
Audit |
Set compliant value where feasible (best effort) |
Disabled |
No action required |
Phase 2: Progressive Implementation
Build templates in dependency order.
Check 04-implementation-plan.md for deployment strategy:
- If phased: add a
@allowedphaseparameter tomain.bicep(values:'all','foundation','security','data','compute','edge'— matching the plan’s phase names). Wrap each module call in a conditional:if phase == 'all' || phase == '{phaseName}'. This letsdeploy.ps1deploy one phase at a time. - If single: no
phaseparameter needed; deploy everything.
Round 1 — Foundation:
main.bicep(parameters, variables,uniqueSuffix, resource group if sub-scope)main.bicepparam(environment-specific values)
Round 2 — Shared Infrastructure:
- Networking (VNet, subnets, NSGs)
- Key Vault
- Log Analytics + App Insights
Round 3 — Application Resources:
- Compute (App Service, Container Apps, Functions)
- Data (SQL, Cosmos, Storage)
- Messaging (Service Bus, Event Grid)
Round 4 — Integration:
- Diagnostic settings on all resources
- Role assignments (managed identity → Key Vault, Storage, etc.)
deploy.ps1deployment script
After each round: run bicep build to catch errors early.
Phase 3: Deployment Script
Generate infra/bicep/{project}/deploy.ps1 with:
╔════════════════════════════════════════╗
║ {Project Name} - Azure Deployment ║
╚════════════════════════════════════════╝
Script must include:
- Parameter validation (ResourceGroup, Location, Environment)
- Phase parameter (
-Phasewith defaultall):- If phased plan: accept phase names from the implementation plan
- Loop through phases sequentially with approval prompts between
- If single plan: ignore phase parameter, deploy everything
az group createfor resource groupaz deployment group createwith--template-fileand--parameters- Output parsing with deployment results table
- Error handling with meaningful messages
Phase 4: Validation (Subagent-Driven)
Delegate validation to specialized subagents for thorough, isolated analysis:
Step 1 — Lint Validation (run in parallel with Step 2):
Delegate to bicep-lint-subagent:
- Provide the project path:
infra/bicep/{project}/main.bicep - Expect PASS/FAIL result with diagnostics
- If FAIL: fix errors, then re-run lint subagent
Step 2 — Code Review (run in parallel with Step 1):
Delegate to bicep-review-subagent:
- Provide the project path:
infra/bicep/{project}/ - Expect APPROVED/NEEDS_REVISION/FAILED verdict
- If NEEDS_REVISION: address feedback, then re-run review subagent
- If FAILED: address critical issues before proceeding
Step 3 — Finalize:
Both subagents must return passing results before proceeding.
Save validation status (including subagent verdicts) in 05-implementation-reference.md.
Run npm run lint:artifact-templates and fix any H2 structure errors for your artifacts.
File Structure
infra/bicep/{project}/
├── main.bicep # Entry point — uniqueSuffix, orchestrates modules
├── main.bicepparam # Environment-specific parameters
├── deploy.ps1 # PowerShell deployment script
└── modules/
├── key-vault.bicep # Per-resource modules
├── networking.bicep
├── app-service.bicep
└── ...
main.bicep Structure
targetScope = 'subscription' // or 'resourceGroup'
// Parameters
param location string = 'swedencentral'
param environment string = 'dev'
param projectName string
param owner string
// Variables
var uniqueSuffix = uniqueString(subscription().id, resourceGroup().id)
var tags = {
Environment: environment
ManagedBy: 'Bicep'
Project: projectName
Owner: owner
}
// Modules — in dependency order
module keyVault 'modules/key-vault.bicep' = { ... }
module networking 'modules/networking.bicep' = { ... }
Output Files
| File | Location |
|---|---|
| Preflight Check | agent-output/{project}/04-preflight-check.md |
| Implementation Ref | agent-output/{project}/05-implementation-reference.md |
| Bicep Templates | infra/bicep/{project}/ |
| Deploy Script | infra/bicep/{project}/deploy.ps1 |
Include attribution header from the template file (do not hardcode).
Validation Checklist
- Preflight check completed and saved to
04-preflight-check.md - AVM modules used for all resources with AVM availability
-
uniqueSuffixgenerated once inmain.bicep, passed to all modules - Governance compliance mapping completed (Phase 1.5)
- All tags from governance constraints applied to every resource (4 baseline + discovered)
- Every Deny policy in
04-governance-constraints.jsonis satisfied in Bicep code - Security baseline applied (TLS 1.2, HTTPS, managed identity)
- CAF naming conventions followed (from azure-defaults skill)
- Length constraints respected (Key Vault ≤24, Storage ≤24)
- No deprecated parameters used (checked against AVM pitfalls)
-
bicep-lint-subagentreturns PASS -
bicep-review-subagentreturns APPROVED -
deploy.ps1generated with proper error handling -
05-implementation-reference.mdsaved with validation status