Reputation: 978
If I use Azure Pipelines to do an 'Incremental' 'Resource Group' scoped deployment of an ARM template containing Role Assignments, it seems I can't rerun/redeploy the pipeline without receiving an error on the Role Assignment resource:
RoleAssignmentUpdateNotPermitted: Tenant ID, application ID, principal ID, and scope are not allowed to be updated.
This looks like an obvious issue that must have a common workaround? I'm I expected to break-out the Role Assignments into a separate template, and perhaps delete and re-create the role assignments on each deployment?
Upvotes: 4
Views: 5547
Reputation: 36
You have asked about incremental updates, this troubleshooting article helps some of the way: https://learn.microsoft.com/en-us/azure/role-based-access-control/troubleshooting?tabs=bicep#symptom---arm-template-role-assignment-returns-badrequest-status
But how I understand it, if you are re-creating the role assignment again with the same GUID, it will try and replace the one that is there. This is generally what we want in an incremental update. However, if any of the other 3 parameters (Tenant ID, application ID, principal ID) have changed and you use the same GUID - it will be seen as an update and you will recieve this error.
Tenant ID, application ID, principal ID, and scope are not allowed to be updated. (code: RoleAssignmentUpdateNotPermitted)
As the error states - these properties cannot be changed.
So what if we want a different assignement, e.g. if the PrincipleID has changed for this deployment? Well then we can use a new GUID, it won't be seen as a change and a new roleAssignment will be made. (The previous one would have to be removed by another means).
If however you use a new GUID and the other 3 properties do remain the same, it will be seen as a duplicate role assignment and also throw an error!
So this is why, we should use the GUID() function to create a guid ID that is based off the other 3 parameters. This way in an incremental update, if we are re-deploying the EXACT same roleAssignment, we use the same GUID. And if we are deploying something different (e.g. the PrincipleID has changed) then we would get a new GUID and it would be seen as a new roleAssignment rather than an update.
In the Azure doc above, the example they give is this:
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
name: guid(resourceGroup().id, principalId, roleDefinitionId)
properties: {
roleDefinitionId: roleDefinitionId
principalId: principalId
principalType: principalType
}
}
Upvotes: 0
Reputation: 76790
Incremental redeployment of an ARM Template with Role Assignments throws an error
Just as you said, this is an obvious issue. For the same scope or resource, you can only assign the same role to a service principal once.
So, there is existing role assignment with the same name that you are trying to create through this template and it ends up giving the error for "RoleAssignmentUpdateNotPermitted
".
To resolve this issue, we need ensure that each deployment to a different resource group uses a different GUID for the role assignment, but at the same time, ensure that the same one is used when deploying to the same resource group.
We could use the guid
function! It takes one or more strings that are used to calculate a hash, very much like the uniquestring function; only this one generates a string in GUID format instead:
{
"type": "Microsoft.Authorization/roleAssignments",
"name": "[guid(resourceGroup().id, 'monitoringUsers')]"
}
You could refer the document Defining RBAC Role Assignments in ARM Templates for some more details.
Upvotes: 7