-
-
Save johndowns/ea7aeec923e008d7b340815d054bfc0c to your computer and use it in GitHub Desktop.
param keyVaultName string = uniqueString(resourceGroup().id) | |
param location string = resourceGroup().location | |
var managedIdentityName = 'my-mi' | |
resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = { | |
name: keyVaultName | |
location: location | |
properties: { | |
enableRbacAuthorization: true | |
tenantId: tenant().tenantId | |
sku: { | |
name: 'standard' | |
family: 'A' | |
} | |
} | |
} | |
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { | |
name: managedIdentityName | |
location: location | |
} | |
@description('This is the built-in Key Vault Administrator role. See https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#key-vault-administrator') | |
resource keyVaultAdministratorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { | |
scope: subscription() | |
name: '00482a5a-887f-4fb3-b363-3b7fe8e74483' | |
} | |
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { | |
name: guid(resourceGroup().id, managedIdentityName, keyVaultAdministratorRoleDefinition.id) | |
properties: { | |
roleDefinitionId: keyVaultAdministratorRoleDefinition.id | |
principalId: managedIdentity.properties.principalId | |
principalType: 'ServicePrincipal' | |
} | |
} |
@gsuttie Yes, this is unfortunately the behaviour of role assignments. The issue is that, after you delete the managed identity and then redeploy the template, the role assignment resource definition ends up with the same name - the GUID is created using the same seed values for the guid()
function. Because you can't update some of the role assignment properties after it's deployed, it unfortunately puts it into an orphaned state. Azure doesn't have do any "cleanup" of orphaned resources like this.
This isn't an issue with Bicep, it's more of a role assignment issue/behaviour, but I certainly have run into it myself in the past.
There are a couple of workarounds:
- You can add another seed value to the
guid()
function on line 32, which means you'll get a new GUID, and therefore end up with a new role assignment when you redeploy. - You can also change the
guid()
function's seed values so that they use the managed identity's principal ID, which will be different for each new managed identity even if they have the same name or resource ID. However, because of a limitation in Bicep/ARM templates, where resources must have names that are available when the deployment starts, you'd need to do this with a module. Here's an example:
main.bicep
param keyVaultName string = uniqueString(resourceGroup().id)
param location string = resourceGroup().location
var managedIdentityName = 'my-mi'
resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = {
name: keyVaultName
location: location
properties: {
enableRbacAuthorization: true
tenantId: tenant().tenantId
sku: {
name: 'standard'
family: 'A'
}
}
}
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
name: managedIdentityName
location: location
}
@description('This is the built-in Key Vault Administrator role. See https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#key-vault-administrator')
resource keyVaultAdministratorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = {
scope: subscription()
name: '00482a5a-887f-4fb3-b363-3b7fe8e74483'
}
module roleAssignment 'role-assignment.bicep' = {
name: 'role-assignment'
params: {
roleAssignmentName: guid(resourceGroup().id, managedIdentity.properties.principalId, keyVaultAdministratorRoleDefinition.id)
roleDefinitionId: keyVaultAdministratorRoleDefinition.id
principalId: managedIdentity.properties.principalId
}
}
role-assignment.bicep
param roleAssignmentName string
param roleDefinitionId string
param principalId string
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
name: roleAssignmentName
properties: {
roleDefinitionId: roleDefinitionId
principalId: principalId
principalType: 'ServicePrincipal'
}
}
I know this is hard - role assignments are one of the trickier resources and require quite a lot of understanding of what's going on before you can make them work :(
Hi John
There appears to be a bug here - If I run this in and then remove the Managed Identity - the Role assignments are orphaned - they still exist at the subscription level.
If I then try to recreate the managed identity with the role Assignment and it doesn't work.
If I then delete the orphaned role assignments (from the subscription level) it then works again.
I think the bug is in the Azure Role assignments but not sure.