skip to Main Content

Got a storage account in a different subscription and resource group, trying to use bicep to assign rbac roles and so far the results are somewhat confusing.

assign_role.bicep

param storageAccountName string
param principalId string
  @allowed([
      'Device'
      'ForeignGroup'
      'Group'
      'ServicePrincipal'
      'User'
      ''
  ])
param principalType string = ''
@allowed([
    'Storage Blob Data Contributor'
    'Storage Blob Data Reader'
])
param roleDefinition string

var roles = {
    // See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for these mappings and more.
    'Storage Blob Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe'
    'Storage Blob Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
}

var roleDefinitionId = roles[roleDefinition]

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = {
    name: storageAccountName
}

resource roleAuthorization 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
    // Generate a unique but deterministic resource name
    name: guid('storage-rbac', storageAccount.id, resourceGroup().id, principalId, roleDefinitionId)
    scope: storageAccount
    properties: {
        principalId: principalId
        roleDefinitionId: roleDefinitionId
        principalType: empty(principalType) ? null : principalType
    }
}

From main.bicep

module roleAuthorization './modules/assign_sa_role.bicep' = {
  name: 'roleAuthorization'
  scope: resourceGroup('my-sub','my-rg')
  params: {
      principalId: '6bcedc96-f01a-41a4-9c62xxxxxxxx' 
      principalType: 'ServicePrincipal'
      storageAccountName: 'xxxxx'
      roleDefinition: 'Storage Blob Data Contributor'
  }
  dependsOn:[CreateManagedIdentity,CreateSQLAudit]
}

Here is what happens, in the above example I have hard coded the principal ID, I still get the error below.

"The resource write operation failed to complete successfully, because it reached terminal provisioning state 'Failed'.","details":[{"code":"BlobAuditingInsufficientStorageAccountPermissions","message":"Insufficient read or write permissions on storage account 'my_storage_account'. Add permissions to the server Identity to the storage account."}]}]}]}]}}

If I then go onto the portal to manually add the role assignment to the principal and the code is executed a second time I get the error below.

At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details.","details":[{"code":"RoleAssignmentExists","message":"The role assignment already exists."}]}]}]}}

Makes me wonder, what is going on here ?
If I use the output of a resource, its no different.

identityIDs[0].properties.principalId

Not sure what is wrong here or how to assign roles correctly via bicep modules.

2

Answers


  1. "BlobAuditingInsufficientStorageAccountPermissions", "message": "Insufficient read or write permissions on storage account ‘my_storage_account’. Add permissions to the server Identity to the storage account.

    According to this SO-Answer by Jim Xu, that error occurs because the server identity does not have sufficient permissions to access the storage account.

    Either you need to pass the storageAccountAccessKey or enable identity on Azure SQL server and assign Storage Blob Data Contributor to the identity on the storage account level.

    "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details.", "details": [{"code": "RoleAssignmentExists", "message": "The role assignment already exists."}]}}]}}

    I agree with Thomas’s comment; the above line indicates that the role assignment is already assigned. If you need to reassign, delete and reassign to the storage account using bicep.

    In my environment, I tried the same code below with identity to assign rbac role.

    Code:

    param sname string = 'testvenkatmi'
    param location string = resourceGroup().location
    resource sample 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = {
      name: sname
      location: location
    }
    
    module roleAuthorization './assign_role.bicep' = {
      name: 'roleAuthorization'
      scope: resourceGroup('<subid>', '<resource grp name>')
      params: {
          principalId: sample.properties.principalId
          principalType: 'ServicePrincipal'
          storageAccountName: 'venkat678'
          roleDefinition: 'Storage Blob Data Contributor'
      }
    }
    

    Output:
    enter image description here

    enter image description here

    Reference:

    Microsoft.Sql/servers/auditingSettings – Bicep, ARM template & Terraform AzAPI reference | Microsoft Learn

    Login or Signup to reply.
  2. I have just test it, it works, this circumstance is about across subsription deployment. you login in sub1 and deploy role assignment to sub2, your account should be the following permissions:

    1. deployment in sub1
    2. owner in sub2 or the storage account resource.

    I have copy your code and make some finely modify

    assign_sa_role.bicep

    param storageAccountName string
    param principalId string
    @allowed([
        'Device'
        'ForeignGroup'
        'Group'
        'ServicePrincipal'
        'User'
        ''
    ])
    param principalType string = ''
    @allowed([
        'Storage Blob Data Contributor'
        'Storage Blob Data Reader'
    ])
    param roleDefinition string
    
    var roles = {
        // See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for these mappings and more.
        'Storage Blob Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe'
        'Storage Blob Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
    }
    
    var roleDefinitionId = roles[roleDefinition]
    
    resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = {
        name: storageAccountName
    }
    
    resource roleAuthorization 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
        // Generate a unique but deterministic resource name
        name: guid('storage-rbac', storageAccount.id, resourceGroup().id, principalId, roleDefinitionId)
        scope: storageAccount
        properties: {
            principalId: principalId
            roleDefinitionId: roleDefinitionId
            principalType: empty(principalType) ? null : principalType
        }
    }
    

    main.bicep

    param otherSubscriptionId string = 'sub2 subid'
    param otherResourceGroupName string = 'sub2 rg'
    param storageAccountName string = 'xx'
    param principalid string = 'xxx'
    
    module roleAuthorization './modules/assign_sa_role.bicep' = {
      name: 'roleAuthorization'
      scope: resourceGroup(otherSubscriptionId, otherResourceGroupName)
      params: {
          principalId: principalid
          principalType: 'ServicePrincipal'
          storageAccountName: storageAccountName
          roleDefinition: 'Storage Blob Data Contributor'
      }
    }
    
    

    deploy.ps1

    ## you should log into sub1
    $rgName = "sub1 rg"
    
    $templateFile = "main.bicep"
    
    New-AzResourceGroupDeployment `
      -Name 'wbtestacrosssubscription' `
      -ResourceGroupName $rgName `
      -TemplateFile $templateFile
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search