AgentSkillsCN

avm-bicep-rules

Bicep 基础设施生成的强制性规则。优先从 Bicep 公共注册表中使用 Azure Verified Modules(AVM),而非直接声明原始资源。建议优先采用 azd 模式下的模块,再考虑资源模块,仅在万不得已时才使用原始资源声明。 适用场景:每次 Bicep 生成、每次创建 infra/ 文件夹、每次 IaC 任务。 由 azure-manager、azure-architect 以及 azure-devops 代理自动调用。

SKILL.md
--- frontmatter
name: avm-bicep-rules
description: |
  MANDATORY rules for Bicep infrastructure generation. Enforces Azure Verified Modules (AVM)
  from the Bicep public registry instead of raw resource declarations. Prefer azd pattern
  modules first, then resource modules, raw declarations only as last resort.
  USE FOR: Every Bicep generation, every infra/ folder creation, every IaC task.
  INVOKED AUTOMATICALLY by azure-manager, azure-architect, and azure-devops agents.

AVM Bicep Rules

MANDATORY COMPLIANCE — These rules apply to ALL Bicep infrastructure generation. When generating Bicep, you MUST use Azure Verified Modules (AVM) from the public registry instead of writing raw resource declarations. This document is the authoritative source for module selection priority and usage patterns.

When to Apply

Apply these rules every time you:

  • Generate Bicep infrastructure (infra/main.bicep, modules)
  • Create new Azure resources in Bicep
  • Modify existing Bicep templates
  • Create infra/ folder for any project

Module Priority (Mandatory)

PriorityModule TypeRegistry PrefixWhen to Use
1️⃣ FirstAZD Pattern Modulesbr/public:avm/ptn/azd/<name>:<version>Preferred for azd projects — pre-composed, opinionated, secure-by-default
2️⃣ SecondPattern Modulesbr/public:avm/ptn/<area>/<name>:<version>Multi-resource patterns (e.g., hub networking, AI platform)
3️⃣ ThirdResource Modulesbr/public:avm/res/<provider>/<type>:<version>Individual resources with best-practice defaults
4️⃣ Last resortRaw resourceN/AOnly when NO AVM module exists for the resource type

NEVER write raw resource declarations when an AVM module exists for that resource type.


Key AZD Pattern Modules

These are preferred for azd projects because they are pre-composed, opinionated stacks:

ModuleRegistry PathUse For
Container Apps Stackavm/ptn/azd/container-apps-stackContainer Apps Environment + ACR + Log Analytics
ACR Container Appavm/ptn/azd/acr-container-appSingle Container App with ACR integration
Container App Upsertavm/ptn/azd/container-app-upsertCreate or update a Container App
AKSavm/ptn/azd/aksAKS cluster for azd projects
AKS Automaticavm/ptn/azd/aks-automatic-clusterAKS Automatic cluster
Monitoringavm/ptn/azd/monitoringLog Analytics + App Insights for azd
Insights Dashboardavm/ptn/azd/insights-dashboardApp Insights dashboard
APIM APIavm/ptn/azd/apim-apiAPI Management API for azd

Key Resource Modules

Use these when no AZD pattern module fits:

ModuleRegistry PathUse For
Container Appavm/res/app/container-appContainer App
Managed Environmentavm/res/app/managed-environmentContainer Apps Environment
Web App / Function Appavm/res/web/siteApp Service / Function App
App Service Planavm/res/web/serverfarmApp Service Plan
Container Registryavm/res/container-registry/registryACR
Key Vaultavm/res/key-vault/vaultKey Vault
Storage Accountavm/res/storage/storage-accountStorage
Cognitive Servicesavm/res/cognitive-services/accountAzure OpenAI / Cognitive Services
Cosmos DBavm/res/document-db/database-accountCosmos DB
SQL Serveravm/res/sql/serverAzure SQL Server
PostgreSQLavm/res/db-for-postgre-sql/flexible-serverPostgreSQL Flexible Server
AKSavm/res/container-service/managed-clusterAKS
Log Analyticsavm/res/operational-insights/workspaceLog Analytics Workspace
App Insightsavm/res/insights/componentApplication Insights
Redisavm/res/cache/redisAzure Cache for Redis
Service Busavm/res/service-bus/namespaceService Bus Namespace
Event Gridavm/res/event-grid/topicEvent Grid Topic

Usage Examples

Container Apps (AZD Pattern — Preferred)

bicep
// ✅ PREFERRED: AZD pattern module for the full Container Apps stack
module containerAppsStack 'br/public:avm/ptn/azd/container-apps-stack:0.1.0' = {
  name: 'container-apps-stack'
  scope: rg
  params: {
    containerAppsEnvironmentName: 'cae-${resourceToken}'
    containerRegistryName: 'cr${resourceToken}'
    logAnalyticsWorkspaceResourceId: monitoring.outputs.logAnalyticsWorkspaceResourceId
    location: location
  }
}

Monitoring (AZD Pattern — Preferred)

bicep
// ✅ PREFERRED: AZD pattern module for monitoring stack
module monitoring 'br/public:avm/ptn/azd/monitoring:0.1.0' = {
  name: 'monitoring'
  scope: rg
  params: {
    logAnalyticsName: 'log-${resourceToken}'
    applicationInsightsName: 'appi-${resourceToken}'
    location: location
    tags: tags
  }
}

AKS (AZD Pattern — Preferred)

bicep
// ✅ PREFERRED: AZD pattern module for AKS
module aks 'br/public:avm/ptn/azd/aks:0.1.0' = {
  name: 'aks-cluster'
  scope: rg
  params: {
    clusterName: 'aks-${resourceToken}'
    containerRegistryName: containerRegistry.outputs.name
    logAnalyticsName: monitoring.outputs.logAnalyticsWorkspaceName
    location: location
    tags: tags
  }
}

Key Vault (Resource Module)

bicep
// ✅ AVM resource module (when no pattern module fits)
module keyVault 'br/public:avm/res/key-vault/vault:0.11.0' = {
  name: 'key-vault'
  scope: rg
  params: {
    name: 'kv-${resourceToken}'
    location: location
    enableRbacAuthorization: true
    tags: tags
  }
}

App Service (Resource Module)

bicep
// ✅ AVM resource module for App Service Plan
module appServicePlan 'br/public:avm/res/web/serverfarm:0.4.0' = {
  name: 'app-service-plan'
  scope: rg
  params: {
    name: 'plan-${resourceToken}'
    location: location
    sku: { name: 'B1', tier: 'Basic' }
    reserved: true
    tags: tags
  }
}

// ✅ AVM resource module for Web App
module webApp 'br/public:avm/res/web/site:0.15.0' = {
  name: 'web-app'
  scope: rg
  params: {
    name: 'app-${resourceToken}'
    kind: 'app,linux'
    serverFarmResourceId: appServicePlan.outputs.resourceId
    location: location
    managedIdentities: { systemAssigned: true }
    httpsOnly: true
    tags: tags
  }
}

❌ WRONG: Raw resource when AVM exists

bicep
// ❌ WRONG: Raw resource declaration when AVM module exists
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: 'kv-${resourceToken}'
  location: location
  properties: {
    sku: { family: 'A', name: 'standard' }
    tenantId: subscription().tenantId
    enableRbacAuthorization: true
  }
}

main.bicep Template

bicep
targetScope = 'subscription'

@description('Name of the environment')
param environmentName string

@description('Location for all resources')
param location string

var resourceToken = take(uniqueString(subscription().id, environmentName, location), 6)
var tags = { 'azd-env-name': environmentName }

resource rg 'Microsoft.Resources/resourceGroups@2023-07-01' = {
  name: 'rg-${environmentName}'
  location: location
  tags: tags
}

// ✅ Use AZD pattern module for monitoring stack
module monitoring 'br/public:avm/ptn/azd/monitoring:0.1.0' = {
  name: 'monitoring'
  scope: rg
  params: {
    logAnalyticsName: 'log-${resourceToken}'
    applicationInsightsName: 'appi-${resourceToken}'
    location: location
    tags: tags
  }
}

// ✅ Use AZD pattern module for Container Apps stack
module containerAppsStack 'br/public:avm/ptn/azd/container-apps-stack:0.1.0' = {
  name: 'container-apps-stack'
  scope: rg
  params: {
    containerAppsEnvironmentName: 'cae-${resourceToken}'
    containerRegistryName: 'cr${resourceToken}'
    logAnalyticsWorkspaceResourceId: monitoring.outputs.logAnalyticsWorkspaceResourceId
    location: location
  }
}

File Structure

code
infra/
├── main.bicep              # Main orchestration (uses AVM modules from Bicep registry)
├── main.parameters.json    # Environment parameters
├── abbreviations.json      # Resource naming conventions
└── modules/                # Only for custom logic not covered by AVM
    └── ...

Prefer AVM modules from br/public:avm/... over local modules in ./modules/. Only create local modules for custom orchestration logic that no AVM module covers.


Discovering Modules

Common Pitfalls

Container App + ACR Authentication

  • The acr-container-app module output for the app URL is .outputs.uri — NOT .outputs.fqdn. Using fqdn causes a Bicep compile error.
  • container-apps-stack defaults to zoneRedundant: true, which requires a delegated subnet. Set zoneRedundant: false for simple apps without a VNet.
  • ACR pull auth is NOT configured by azd deploy — your Bicep must set it up during provisioning (managed identity + AcrPull role, or ACR admin credentials).
  • When using managed identity for ACR pull, there's a circular dependency: the Container App's principal ID isn't known until after creation, but the AcrPull role needs it. Solution: create CA first with a placeholder image, then assign the role using dependsOn.
  • For the full ACR auth pattern, invoke the container-app-acr-auth skill.

File Placement

  • main.parameters.json MUST be in the infra/ directory, not the project root. azd expects it at infra/main.parameters.json.

Module Output Discovery

  • When unsure about a module's output names, use web_search or context7 to look up the AVM module documentation. Do NOT guess output names — wrong names cause Bicep compile errors that waste multiple deploy cycles.

Dockerfile Generation

  • Always use npm install (NOT npm ci) in generated Dockerfiles unless a package-lock.json is already committed in the repo. npm ci requires a lockfile and will fail without one.
  • If generating both a Dockerfile and package.json in the same session, also run npm install --package-lock-only to generate the lockfile before deploying.
  • For the container-app-acr-auth skill, invoke it BEFORE writing Container App Bicep — it has the complete ACR auth patterns.

Validation Checklist

Before proceeding to azure-validate or azure-deploy, verify:

  • Every resource with an AVM module uses the AVM module (not raw resource)
  • AZD pattern modules used where available (checked before avm/res/*)
  • No local ./modules/ duplicating what AVM already provides
  • Module versions are pinned (e.g., :0.1.0, not :latest)
  • Container App + ACR: pull authentication is configured in Bicep (not left to azd deploy)
  • main.parameters.json is in infra/ directory (not project root)