Azure角色分配报BadRequestFormat错误及服务主体ID获取问题
问题
我想要创建存储账户,并为Azure DevOps管道服务连接的服务主体添加角色分配,使其能够读取Blob存储中的文件。我已有一个在注册表中广泛使用的Bicep模块用于创建存储账户,这部分无问题。我的Bicep代码如下:
var storageAccountName = 'st${baseResourceNameAlpha}' module storageAccount 'br:urlhere.azurecr.io/bicep/modules/storageaccount:v22.10.03.02' = { name: 'storageAccountDeployment' params: { name: storageAccountName } } resource storageAc 'Microsoft.Storage/storageAccounts@2022-05-01' existing = { name: storageAccountName } //corrected blobReaderRole thanks to comment from Thomas // var blobReaderRole = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' var blobReaderRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1') var principalId = 'principal id of my dev ops svc conn' resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { scope: storageAc name: guid(storageAc.id, principalId, blobReaderRole) properties: { roleDefinitionId: blobReaderRole principalId: principalId principalType: 'ServicePrincipal' } }
执行时出现错误:
BadRequestFormat The request was incorrectly formatted
请问我哪里出错了?另外,我目前从Azure门户的企业应用页面获取服务连接的主体ID,Get-AzADUser -UserPrincipalName对服务主体无效,是否有其他方法?
解答
一、Bicep角色分配代码错误修正
你的错误主要源于API版本选择和角色分配参数的细节问题,具体修正点如下:
- 更换为稳定版API:避免使用预览版
2020-04-01-preview,改用Microsoft.Authorization/roleAssignments的稳定版2022-04-01,预览版容易存在格式兼容性问题。 - 简化角色定义ID写法:可以直接使用Bicep内置的
BuiltInRole.StorageBlobDataReader常量替代手动拼接的角色ID,既简洁又避免拼写错误;如果坚持使用ID,确保subscriptionResourceId生成的是当前订阅下的有效角色定义ID。 - 优化GUID生成逻辑:在
guid函数中添加额外的标识字符串(如'BlobReaderAssignment'),确保角色分配名称的唯一性,避免冲突。
修正后的代码示例:
var storageAccountName = 'st${baseResourceNameAlpha}' module storageAccount 'br:urlhere.azurecr.io/bicep/modules/storageaccount:v22.10.03.02' = { name: 'storageAccountDeployment' params: { name: storageAccountName } } resource storageAc 'Microsoft.Storage/storageAccounts@2022-05-01' existing = { name: storageAccountName } // 使用内置常量更简洁推荐 var blobReaderRole = BuiltInRole.StorageBlobDataReader // 若需手动指定ID,确保格式正确 // var blobReaderRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1') var principalId = '你的DevOps服务连接主体ID' resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: storageAc name: guid(storageAc.id, principalId, blobReaderRole, 'BlobReaderAssignment') properties: { roleDefinitionId: blobReaderRole principalId: principalId principalType: 'ServicePrincipal' } }
另外,若存储账户启用了Data Lake Storage Gen2(分层命名空间),需确认角色分配的scope是否需要细化到容器级别,不过给整个存储账户分配Blob Reader权限时,当前scope设置是正确的。
二、获取服务主体ID的方法
服务主体不属于用户范畴,因此Get-AzADUser命令无效,可通过以下方式获取其主体ID:
PowerShell命令
- 按显示名称查询:
Get-AzADServicePrincipal -DisplayName "你的服务主体显示名称"
返回结果中的Id字段即为目标主体ID。
- 按应用ID查询:
若已知服务主体对应的应用注册ID,可执行:
Get-AzADServicePrincipal -ApplicationId "应用ID"
Azure CLI命令
- 按显示名称查询:
az ad sp list --display-name "你的服务主体显示名称" --query "[0].id" -o tsv
- 按应用ID查询:
az ad sp show --id "应用ID" --query "id" -o tsv
其他方式
在Azure DevOps项目的项目设置 > 服务连接中,找到目标连接,点击「管理服务主体」可直接跳转至Azure门户的服务主体详情页,查看其ID。
内容的提问来源于stack exchange,提问作者Rob Bowman
相关产品推荐
相关产品推荐

