name: writing-bicep-templates description: Provides Bicep coding standards for Azure infrastructure in this repository. Use when writing or modifying Bicep files, configuring Container Apps, setting up RBAC, or working with Azure resources.
Bicep Coding Standards
Goal: Create consistent, secure Azure infrastructure
Naming Convention
Use resourceToken from uniqueString():
var token = toLower(uniqueString(subscription().id, environmentName, location))
name: '${abbrs.appContainerApps}web-${token}' // ca-web-abc123
Exception: ACR requires alphanumeric only: cr${resourceToken}
Parameters
Always add @description() and use @allowed() for constrained values:
@description('Environment (dev, prod)')
param environmentName string
@description('Azure region')
@allowed(['eastus2', 'westus2'])
param location string = 'eastus2'
Outputs
Expose key identifiers for azd and other modules:
output containerAppName string = containerApp.name
output webEndpoint string = 'https://${containerApp.properties.configuration.ingress.fqdn}'
output identityPrincipalId string = containerApp.identity.principalId
Managed Identity
Use a user-assigned MI for ACR pull and OBO (avoids circular dependencies). Create it in the infrastructure module so its principalId is available before the Container App:
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2024-11-30' = {
name: '${abbrs.managedIdentityUserAssignedIdentities}web-${resourceToken}'
location: location
properties: { isolationScope: 'Regional' }
}
output managedIdentityPrincipalId string = managedIdentity.properties.principalId
Attach to Container App with identity: { type: 'UserAssigned', userAssignedIdentities: { '${miId}': {} } }. Use MI for ACR pull via registries: [{ server: acr.loginServer, identity: miId }].
RBAC Assignments
Use guid() for names + specify principalType:
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resource.id, principalId, roleId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleId)
principalId: principalId
principalType: 'ServicePrincipal'
}
}
Container Apps
Key settings: System identity + scale-to-zero + HTTPS only:
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
identity: { type: 'UserAssigned', userAssignedIdentities: { '${userAssignedIdentityId}': {} } }
properties: {
configuration: {
ingress: {
external: true
targetPort: 8080
allowInsecure: false
}
}
template: {
scale: { minReplicas: 0, maxReplicas: 3 }
}
}
}
ACR Pull Pattern
Use user-assigned MI for ACR pull (no admin credentials or secrets):
registries: [{
server: containerRegistry.properties.loginServer
identity: userAssignedIdentityId // MI with AcrPull role
}]
Validation
az bicep build --file main.bicep
az deployment group what-if --template-file main.bicep
Project-Specific: Module Hierarchy
main.bicep (subscription scope)
├─ Resource group
├─ main-infrastructure.bicep (ACR + Container Apps Env + Log Analytics + User-Assigned MI)
├─ entra-app.bicep (SPA app + conditional OBO backend app with FIC + admin consent)
├─ main-app.bicep (Container App with MI-based ACR pull)
└─ RBAC (Cognitive Services User role via postprovision CLI)
Project-Specific: Container App Configuration
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
identity: {
type: 'UserAssigned'
userAssignedIdentities: { '${userAssignedIdentityId}': {} }
}
properties: {
managedEnvironmentId: containerAppsEnvironmentId
configuration: {
ingress: {
external: true
targetPort: 8080
allowInsecure: false
}
registries: [{
server: containerRegistry.properties.loginServer
identity: userAssignedIdentityId // MI-based pull, no secrets
}]
}
template: {
containers: [{
name: 'web'
image: containerImage
env: containerEnv // Base env + conditional OBO env
resources: { cpu: json('0.5'), memory: '1Gi' }
}]
scale: { minReplicas: 0, maxReplicas: 3 }
}
}
}
output fqdn string = containerApp.properties.configuration.ingress.fqdn
output identityPrincipalId string = containerApp.identity.principalId
Related Skills
- deploying-to-azure - Deployment commands and hook workflow
- writing-csharp-code - Backend configuration for Container Apps
- troubleshooting-authentication - RBAC and managed identity debugging