如何在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
相关产品推荐
相关产品推荐

