Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Prepare Azure environments for new workloads—subscriptions, networking, identity, and landing zones
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/container-apps/bicep.md
1# Container Apps Bicep Patterns23> **⚠️ Container Registry Naming:** If using Azure Container Registry, names must be alphanumeric only (5-50 characters). Use `replace()` to remove hyphens: `replace('cr${environmentName}${resourceSuffix}', '-', '')`45> **⚠️ Two-Phase Deployment (Mandatory):** To avoid a circular dependency when scoping the AcrPull role assignment to a Bicep module, use the two-phase pattern below:6> - **Phase 1:** Deploy ACR and Container App with a public placeholder image and **no** `registries` block.7> - **Phase 2:** Deploy the AcrPull role assignment as a **separate module** using outputs from Phase 1.8>9> The Bicep template does **not** need a `registries` block. `azd deploy` handles the registry/identity link by calling `az containerapp registry set --server <acr-server> --identity system` via the Azure API before updating the container image. If you are not using AZD, you must run this command manually before switching the image to an ACR-hosted image; otherwise the app will hit image pull failures.1011## Phase 1: Container App Module (No Registry Link)1213```bicep14// Placeholder image allows provisioning before app image exists in ACR.15// No registries block in Bicep — azd deploy configures the registry/identity link16// (az containerapp registry set --identity system) and updates the image via the Azure API.17// If not using AZD, run that command manually before switching to an ACR-hosted image.18param containerImageName string = 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'1920resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {21name: appName22location: location23identity: {24type: 'SystemAssigned'25}26properties: {27environmentId: containerAppsEnvironment.id28configuration: {29ingress: {30external: true31targetPort: 808032transport: 'auto'33}34// No registries block in Bicep. azd deploy sets the registry/identity link via35// 'az containerapp registry set --identity system' before pushing the real image.36// Without this step (or its manual equivalent), the app will fail to pull from ACR.37}38template: {39containers: [40{41name: serviceName42image: containerImageName43resources: {44cpu: json('0.5')45memory: '1Gi'46}47}48]49}50}51}5253output systemAssignedMIPrincipalId string = containerApp.identity.principalId54```5556## Phase 2: AcrPull Role Assignment Module (acr-pull-role.bicep)5758Place this in a **separate module file** so neither the ACR module nor the Container App module depends on it, eliminating the circular dependency.5960```bicep61// acr-pull-role.bicep62param acrName string63param principalId string6465resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = {66name: acrName67}6869resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {70name: guid(containerRegistry.id, principalId, 'acrpull')71scope: containerRegistry72properties: {73roleDefinitionId: subscriptionResourceId(74'Microsoft.Authorization/roleDefinitions',75'7f951dda-4ed3-4680-a7ca-43fe172d538d'76)77principalId: principalId78principalType: 'ServicePrincipal'79}80}81```8283> 💡 **Tip:** Always set `principalType: 'ServicePrincipal'` for managed identities. This avoids a Graph API lookup and speeds up role assignment propagation.8485## Wiring Phase 1 and Phase 2 in main.bicep8687```bicep88// Phase 1: ACR and Container App — neither module depends on the role assignment89module containerRegistry './modules/container-registry.bicep' = {90name: 'containerRegistry'91scope: rg92params: { /* ... */ }93}9495module api './modules/container-app.bicep' = {96name: 'api'97scope: rg98params: {99containerImageName: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'100// No registries param in Bicep — azd deploy configures the registry/identity link101// and updates the image via the Azure API after provisioning.102/* ... */103}104}105106// Phase 2: Role assignment depends on outputs of both Phase 1 modules,107// but neither Phase 1 module depends on this — no circular dependency.108module acrPullRole './modules/acr-pull-role.bicep' = {109name: 'acrPullRole'110scope: rg111params: {112acrName: containerRegistry.outputs.name113principalId: api.outputs.systemAssignedMIPrincipalId114}115}116```117118## Container Apps Environment119120```bicep121resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = {122name: '${resourcePrefix}-env'123location: location124properties: {125appLogsConfiguration: {126destination: 'log-analytics'127logAnalyticsConfiguration: {128customerId: logAnalyticsWorkspace.properties.customerId129sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey130}131}132}133}134```135