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

如何在Bicep中通过应用ID获取服务主体ID?

问题:通过ADO服务连接的应用ID获取服务主体ID用于Bicep角色分配

我想在Bicep中使用ADO管道内服务连接的主体ID创建roleAssignment,但Bicep没有Terraform里的self方法。我尝试用AzureCLI任务获取服务连接信息,任务代码如下:

- task: AzureCLI@2
  displayName: Retrieve principal ID of service connection
  continueOnError: false
  inputs:
    azureSubscription: $(armServiceConnectionName)
    scriptType: bash
    scriptLocation: inlineScript
    addSpnToEnvironment: true
    inlineScript: echo "##vso[task.setvariable variable=servicePrincipalId]$servicePrincipalId"

但这个任务返回的是服务主体的应用ID,不是我需要的主体ID。我试过用这段Bicep代码转换:

armPrincipalId = split(extensionResourceId(armConnectionPrincipalAppId, 'Microsoft.ManagedIdentity/userAssignedIdentities', armServiceConnectionName), '/')[8]

结果报错:

DeploymentOutputEvaluationFailed: The template output 'armPrincipalId' is not valid: Unable to evaluate template language function 'extensionResourceId': the provided parent resource id '***' is not a valid uri

显然这方法无效,因为extensionResourceId需要合法的URI格式资源ID,而我只有一个UID。请问怎么通过应用ID获取对应的主体ID?


解决方案

方法1:在ADO管道中直接获取主体ID

修改AzureCLI任务,用az ad sp show命令通过应用ID直接查询主体ID:

- task: AzureCLI@2
  displayName: Retrieve principal ID of service connection
  continueOnError: false
  inputs:
    azureSubscription: $(armServiceConnectionName)
    scriptType: bash
    scriptLocation: inlineScript
    addSpnToEnvironment: true
    inlineScript: |
      # 通过应用ID查询服务主体,提取主体ID
      principalId=$(az ad sp show --id $servicePrincipalId --query id -o tsv)
      echo "##vso[task.setvariable variable=servicePrincipalObjectId]$principalId"

之后管道里就能直接拿到servicePrincipalObjectId变量,直接传入Bicep使用即可。

方法2:在Bicep内部通过应用ID查询主体ID

如果需要在Bicep里处理,可以使用部署脚本模块调用CLI查询:

param servicePrincipalAppId string

// 部署脚本:通过应用ID查询服务主体ID
resource getSpObjectId 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
  name: 'getSpObjectId'
  location: resourceGroup().location
  kind: 'AzureCLI'
  properties: {
    azCliVersion: '2.45.0'
    scriptContent: "az ad sp show --id ${servicePrincipalAppId} --query id -o tsv"
    retentionInterval: 'PT1H' // 脚本执行结果保留1小时
  }
}

// 导出查询到的主体ID
output servicePrincipalObjectId string = getSpObjectId.properties.outputs

部署时传入应用ID参数,就能得到对应的主体ID用于角色分配。

原方法失败原因

extensionResourceId用于生成扩展资源的ID(比如用户分配托管标识的附属资源),但服务主体不属于托管标识,也不是扩展资源,因此这个函数完全不适用。通过拆分ID推导主体ID的方式,只适用于已知固定URI结构的资源,而服务主体的应用ID和主体ID是独立的标识,无法通过这种方式推导。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:20:25