Search code examples
azureazure-resource-managerazure-bicep

Azure Bicep - Role assignment - Principal does not exist in the directory


I've created a Bicep template. In it I create a user-assigned identity and reference it in other resources like this

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
  }
}

Whenever I deploy this I need 2 runs. The first run ends in the error message:

Principal XXX does not exist in the directory YYY

where XXX would be a principal id the user-assigned identity has and YYY is my tenant id. If I now look into the portal the identity is created and XXX is the correct id.

So when I now simply re-run the deployment it works.

I consider it a bug in dependsOn which should relate to ARM templates and not Bicep. I could not find any place where I can report ARM template issues to Microsoft.

I'm asking to assure that I do not miss something else here.

Edit: Added complete working sample which shows the bug. To use it, copy the script content into a test.bicep locally. Then create a resource group (lets call it "rg-test"), ensure that your local POSH context is set correctly and execute the following line in the folder where you stored the bicep in:

New-AzResourceGroupDeployment -Name deploy -Mode Incremental -TemplateFile .\test.bicep -ResourceGroupName rg-test

Solution

  • In the role assignment, you need to specify the principalType to ServicePrincipal and also use an api version greater or equal than: 2018-09-01-preview.

    When you create a service principal, it is created in Azure AD. It takes some time for the service principal to be replicated globally. By setting the principalType to ServicePrincipal, it tells the ARM API to wait for the replication.

    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'
      }
    }