azure-functionsazureservicebusrbac

Azure Function Service Bus Trigger with RBAC - Connection Problem


I have setup Azure Service bus to use RBAC and assigned myself a role of "Azure Service Bus Data Owner". I am able to send a message to a queue with:

ServiceBusClient client = new ServiceBusClient("mynamespace.servicebus.windows.net", new AzureCliCredential());
ServiceBusMessage serviceBusMessage = new ServiceBusMessage("my message");
await client.CreateSender("myqueue").SendMessageAsync(serviceBusMessage);

when the message is there, I am trying to run an Azure Function with Service Bus Trigger, like this:

[Function(nameof(MyTrigger))]
public async Task Run(
    [ServiceBusTrigger("myqueue", Connection = "MyServiceBusNamespace")]
    ServiceBusReceivedMessage message,
    ServiceBusMessageActions messageActions)
{
    _logger.LogInformation("Message Body: {body}", message.Body);
    await messageActions.CompleteMessageAsync(message);
    await Task.CompletedTask;
}

with settings like this:

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "AzureWebJobsSecretStorageType": "Files",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
        "MyServiceBusNamespace": "mynamespace.servicebus.windows.net"
    }
}

Now I get the error upon running the funciton locally:

[2025-02-17T17:22:14.636Z] The listener for function 'Functions.MyTrigger' was unable to start.
[2025-02-17T17:22:14.636Z] The listener for function 'Functions.MyTrigger' was unable to start. Azure.Messaging.ServiceBus: The connection string could not be parsed; either it was malformed or contains no well-known tokens.

How do I use the service bus trigger with Azure Function (not the one with the SAS key but RBAC)?


Solution

  • To use RBAC with Azure Functions, you must set your host configuration to associate a fully qualified namespace name with the connection name that you're assigning to your trigger.

    Using your example:

    [Function(nameof(MyTrigger))]
    public async Task Run(
        [ServiceBusTrigger("myqueue", Connection = "MyServiceBusNamespace")]
        ServiceBusReceivedMessage message,
        ServiceBusMessageActions messageActions)
    {
        _logger.LogInformation("Message Body: {body}", message.Body);
        await messageActions.CompleteMessageAsync(message);
        await Task.CompletedTask;
    }
    

    This would look like:

    {
      "Values": {
        "MyServiceBusNamespace__fullyQualifiedNamespace": "<service_bus_namespace>.servicebus.windows.net"
      }
    }
    

    This is discussed in the trigger docs for identity-based connections.

    Under the covers, this is using a DefaultAzureCredential instance. To configure the identity used, you'll want to take a look at the article: Create Microsoft Entra credential types using configuration files.