Search code examples
azureazure-functionsazureservicebusazure-managed-identityazure-bicep

How to assign correct roles on Service Bus entities to Azure functions managed identity with Bicep?


I have an Azure Functions project, with a Function that uses a Service Bus binding (that is used to Listen on a subscription and to Send to a topic).

The Azure functions deployment is running under a managed identity. And as we want to deploy everything automatically, using Azure Bicep, I want to automatically give the correct role assignment on the Service Bus namespace (or entities) for that managed identity, in an Azure Bicep file.

But I don't seem to find out how to do that. Would someone be able to indicate the correct bicep snippet to create the role assignments Azure Service Bus Data Receiver and Azure Service Bus Data Sender on a Service Bus entity for a specific managed identity?

(and even better : how can I find that out for myself, knowing that I am rather new to bicep)

Best regards


Solution

  • Documentation to create RBAC using Bicep can be found here.
    Azure built-in roles can be found here

    So for ServiceBus and managed identity, you could create a module that looks like that

    // servicebus-role-assignment.bicep
    
    param serviceBusName string
    param principalId string
    
    @allowed([
      '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' // Azure Service Bus Data Receiver
      '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39' // Azure Service Bus Data Sender
    ])
    param roleId string
    
    
    // Get a reference to servicebus namespace
    resource servicebus 'Microsoft.ServiceBus/namespaces@2022-01-01-preview' existing = {
      name: serviceBusName
    }
    
    // Grant permissions to the principalID to specific role to servicebus
    resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
      name: guid(servicebus.id, roleId, principalId)
      scope: servicebus
      properties: {
        roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleId)
        principalId: principalId
        principalType: 'ServicePrincipal'
      }
    }
    

    If you are using a user-assigned identity, you could invoke this module once the identity has been created:

    param location string = resourceGroup().location
    param identityName string
    param serviceBusName string
    
    // Create the identity
    resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = {
      name: identityName
      location:location
    }
    
    // Do the role assignment
    module serviceBusRoleAssignment 'servicebus-role-assignment.bicep' = {
      name: 'servicebus-role-assignment'
      params: {
        serviceBusName: serviceBusName
        roleId: '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' // Azure Service Bus Data Receiver    
        principalId: identity.properties.principalId
      }
    }
    

    If you are using a system-assigned identity, you would need to first create the function app:

    param location string = resourceGroup().location
    param functionAppName string
    param serviceBusName string
    ...
    
    // Create the function app
    resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
      name: functionAppName
      identity: {
        type: 'SystemAssigned'
      }
      ...
    }
    
    // Do the role assignment
    module serviceBusRoleAssignment 'servicebus-role-assignment.bicep' = {
      name: 'servicebus-role-assignment'
      params: {
        serviceBusName: serviceBusName
        roleId: '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' // Azure Service Bus Data Receiver    
        principalId: functionApp.identity.principalId
      }
    }