You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bicep配置跨订阅托管身份实现Container App拉取ACR镜像

用托管身份实现Container Apps跨订阅从ACR拉取镜像的Bicep部署方案

可行性确认

完全可以通过给Container App配置系统托管身份或用户分配托管身份并授予ACR的AcrPull角色实现需求,不需要启用ACR管理员账户,也无需Azure DevOps等中间工具中转镜像拉取流程。

解决"鸡生蛋"问题

不存在必须先部署Container App再配置身份的矛盾。Bicep支持在同一个部署脚本中完成所有操作:

  • 系统托管身份:启用身份的同时部署Container App,再关联ACR权限
  • 用户分配身份:先创建身份,再部署Container App并关联该身份,同步配置ACR权限

Bicep脚本示例

方案1:使用系统托管身份

// 管理订阅中的ACR资源参数(跨订阅引用需确保部署身份有权限读取)
param acrName string
param acrSubscriptionId string
param acrResourceGroupName string

// 当前订阅的Container Apps环境参数
param containerAppEnvName string
param containerAppName string
param imageName string // 格式:acrName.azurecr.io/your-image:tag

// 获取ACR资源ID
var acrId = resourceId(acrSubscriptionId, acrResourceGroupName, 'Microsoft.ContainerRegistry/registries', acrName)

// 部署Container App并启用系统托管身份
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  name: containerAppName
  location: resourceGroup().location
  properties: {
    managedEnvironmentId: resourceId('Microsoft.App/managedEnvironments', containerAppEnvName)
    configuration: {
      // 无需配置registries的用户名/密码,留空数组即可
      registries: []
    }
    template: {
      containers: [
        {
          name: containerAppName
          image: imageName
          resources: {
            cpu: 0.5
            memory: '1Gi'
          }
        }
      ]
    }
    identity: {
      type: 'SystemAssigned'
    }
  }
}

// 给系统托管身份授予ACR的AcrPull角色(跨订阅权限分配)
resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(acrId, containerApp.id, 'AcrPull')
  scope: acrId
  properties: {
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // AcrPull角色固定ID
    principalId: containerApp.identity.principalId
    principalType: 'ServicePrincipal'
  }
}

方案2:使用用户分配托管身份

如果需要多个Container App共享同一身份,推荐使用此方案:

// 管理订阅中的ACR资源参数
param acrName string
param acrSubscriptionId string
param acrResourceGroupName string

// 当前订阅的参数
param containerAppEnvName string
param containerAppName string
param imageName string
param userAssignedIdentityName string

// 创建用户分配托管身份
resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: userAssignedIdentityName
  location: resourceGroup().location
}

// 获取ACR资源ID
var acrId = resourceId(acrSubscriptionId, acrResourceGroupName, 'Microsoft.ContainerRegistry/registries', acrName)

// 部署Container App并关联用户分配身份
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  name: containerAppName
  location: resourceGroup().location
  properties: {
    managedEnvironmentId: resourceId('Microsoft.App/managedEnvironments', containerAppEnvName)
    configuration: {
      registries: []
    }
    template: {
      containers: [
        {
          name: containerAppName
          image: imageName
          resources: {
            cpu: 0.5
            memory: '1Gi'
          }
        }
      ]
    }
    identity: {
      type: 'UserAssigned'
      userAssignedIdentities: {
        '${userAssignedIdentity.id}': {}
      }
    }
  }
}

// 给用户分配身份授予ACR的AcrPull角色
resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(acrId, userAssignedIdentity.id, 'AcrPull')
  scope: acrId
  properties: {
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
    principalId: userAssignedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
  }
}

关键说明

  • 无需配置registries项:托管身份会自动与ACR完成身份验证,因此configuration.registries无需填写用户名和密码,留空数组即可。
  • 跨订阅权限要求:执行部署脚本的身份需具备双权限:在ACR所在订阅能创建角色分配,在Container App所在订阅能创建Container App和托管身份。
  • 镜像地址规范:直接使用ACR完整镜像地址(如myacr.azurecr.io/myapp:v1),无需额外配置。

内容的提问来源于stack exchange,提问作者The Senator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:10:34