azureazure-resource-managerazure-bicepazure-resource-group

ARM resource group deployment showing modification for new deployments eventhough there are no chnages


I am using below Bicep file for Azure role assignments . So here I have a Azuredevops pipeline which wil build the bicepfile to arm template and from pipeline variables, the paramaters.json file will be getting updated.

main.bicep

targetScope = 'resourceGroup' 

@description('Principal type of the assignee.')
@allowed([
  'Device'
  'ForeignGroup'
  'Group'
  'ServicePrincipal'
  'User'
])
param principalType string

@description('the id for the role defintion, to define what permission should be assigned')
param RoleDefinitionId string

@description('the id of the principal that would get the permission')
param principalId string

@description('the role deffinition is collected')
resource roleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = {
  scope: resourceGroup()
  name: RoleDefinitionId
}

resource RoleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
  name: guid(resourceGroup().id, RoleDefinitionId, principalId)
  properties: {
    roleDefinitionId: roleDefinition.id
    principalId: principalId
    principalType: principalType
  }
}

paramters.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
     "principalType": {
         "value": "#{principalType}#"
     },
     "RoleDefinitionId": {
       "value": "#{RoleDefinitionId}#"          
     },     
     "principalId": {
       "value": "#{principalId}#"
     }
  } 
}

pipeline build task for creation deployment.

'az deployment group create --resource-group $(resourceGroup) --template-file $(System.DefaultWorkingDirectory)/template/main.json --parameters $(System.DefaultWorkingDirectory)/template/parameters.json' 

When I triggered the pipeline firstime, i got output summary as below.

The deployment will update the following scope:

Scope: /subscriptions/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXXXXX-rg

  + Microsoft.Authorization/roleAssignments/xxxxxxxxxxxxxxxx [2020-10-01-preview]

      apiVersion:                  "2020-10-01-preview"
      id:                          "/subscriptions/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXXXXX-rg/providers/Microsoft.Authorization/roleAssignments/xxxxxxxxxxxxxxxxx"
      name:                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      properties.principalId:      "xxxxxxxxxxxxx"
      properties.roleDefinitionId: "/subscriptions/XXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXXXXX-rg/providers/Microsoft.Authorization/roleDefinitions/xxxxxxxxxxxxxxxxxxxxxxx"
      type:                        "Microsoft.Authorization/roleAssignments"

And after that, if I retrigger the pipeline again without any change to the templates. Its showing as 1 to modify, but expected that the output will show as "no change". Because we havenet made any changes to the resource either from pipeline side or manually.

Scope: /subscriptions/xxxxxxxxxxxxxxxxxx/resourceGroups/xxxxxxxxxxxxxxxx-rg

  ~ Microsoft.Authorization/roleAssignments/xxxxxxxxxxxxxxxxxxxxxxx [2020-10-01-preview]
    ~ properties.roleDefinitionId: "/subscriptions/xxxxxxxxxxxxxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/xxxxxxxxxxxxxxxxxxxxxxxxx" => "/subscriptions/xxxxxxxxxxxxxxxxxxxx/resourceGroups/xxxxxxxxxxxxxxx-rg/providers/Microsoft.Authorization/roleDefinitions/xxxxxxxxxxxxxxxxxxx"
    x properties.principalType:    "Group"

Resource changes: 1 to modify

iF i again deploy also, the next time again will show the same output as 1 to modify

What is the issue here, Why ARM deployment is showing changes eventhough there are no changes.


Solution

  • Azure built-in role definitions are defined at the subscription level unless it is a custom role that you've created at the another scope.

    In your bicep file, you can change the scope of the roleDefinition resource:

    @description('the role deffinition is collected')
    resource roleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = {
      scope: subscription()
      name: RoleDefinitionId
    }
    

    or you could also use subscriptionResourceId:

    resource RoleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
      name: guid(resourceGroup().id, RoleDefinitionId, principalId)
      properties: {
        roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', RoleDefinitionId)
        principalId: principalId
        principalType: principalType
      }
    }