Azure 二头肌 - 角色分配 - 目录中不存在主体

我创建了一个二头肌模板。在其中,我创建了一个用户分配的身份并在其他资源中引用它,例如

var identityName = 'mid-dd-test'
var roleName = 'TestRole'
var roleDescription = 'Some test'
var roleScopes = [
    resourceGroup().id
]
var resolvedActions = [
    'Microsoft.Resources/subscriptions/resourcegroups/*'
  'Microsoft.Compute/sshPublicKeys/*'
]
var permittedDataActions = []

resource userId 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
  name: identityName
  location: resourceGroup().location  
}

resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
  name: guid(subscription().id, 'bicep', 'dsadsd')  
  properties: {
    roleName: roleName
    description: roleDescription
    type: 'customRole'    
    assignableScopes: roleScopes
    permissions: [
      {        
        actions: resolvedActions
        dataActions: permittedDataActions
      }
    ]
  }
}

resource roles 'Microsoft.Authorization/roleAssignments@2018-09-01-preview' = {
  name: guid(subscription().id, 'bicep-roleassignments', 'dsddsd')  
  properties: {
    principalId: userId.properties.principalId
    roleDefinitionId: roleDef.id
  }
}

每当我部署它时,我都需要运行 2 次。第一次运行以错误消息结束:

Principal XXX does not exist in the directory YYY

其中 XXX 将是用户分配的身份具有的主体 ID,而 YYY 是我的租户 ID。如果我现在查看门户,则会创建身份并且 XXX 是正确的 ID。

所以当我现在简单地重新运行部署时它可以工作

我认为它是 dependsOn 中的一个错误,它应该与 ARM 模板相关,而不是二头肌。我找不到任何可以向 Microsoft 报告 ARM 模板问题的地方。

我要求确保我不会在这里错过其他任何东西。

编辑:添加了显示错误的完整工作示例。要使用它,请将脚本内容复制到本地的 test.bicep 中。然后创建一个资源组(我们称之为“rg-test”),确保您的本地 POSH 上下文设置正确,并在您存储二头肌的文件夹中执行以下行:

New-AzResourceGroupDeployment -Name deploy -Mode Incremental -TemplateFile .test.bicep -ResourceGroupName rg-test
stack overflow Azure Bicep - Role assignment - Principal does not exist in the directory
原文答案
author avatar

接受的答案

在角色分配中,您需要将 principalType 指定为 ServicePrincipal 并使用大于或等于 2018-09-01-preview 的 api 版本。

创建服务主体时,它是在 Azure AD 中创建的。全球复制服务主体需要一些时间。通过将 principalType 设置为 ServicePrincipal ,它告诉 ARM API t0 等待复制。

resource roles 'Microsoft.Authorization/roleAssignments@2018-09-01-preview' = {
  name: guid(subscription().id, 'bicep-roleassignments', 'dsddsd')  
  properties: {
    principalId: userId.properties.principalId
    roleDefinitionId: roleDef.id
    principalType: 'ServicePrincipal'
  }
}

答案:

作者头像

您需要在目标资源的 identity 属性中引用新创建的身份。 dependsOn 是多余的,因为 bicep 根据实际使用情况以正确的顺序创建资源:

resource userId 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
  name: 'myidentity'
  location: resourceGroup().location
}

resource appService 'Microsoft.Web/sites@2021-02-01' = {
  name: 'appserviceName'
  location: resourceGroup().location
  properties: {
    //...
  }
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '/subscriptions/{your_subscription_id}/resourceGroups/${resourceGroup().name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${userId.name}': {}
    }
  }  
}

documentation 不建议在没有充分理由的情况下使用 dependsOn

在大多数情况下,您可以使用符号名称来暗示资源之间的依赖关系。如果您发现自己设置了显式依赖项,则应考虑是否有办法将其删除。

作者头像

因此,如果正确引用属性,二头肌不需要 dependsOn 段。

需要引用资源块中userId的 properties.principalId

所以看起来像:

userId.properties.principalId

这是一个工作示例中的 quickstart that calls ,这是如何工作的。