Search code examples
pythonazureazure-active-directoryazure-eventgrid

Creating an Azure Event Grid Topic Error - "does not have authorization to perform action"


I'm writing a python script that is intended to create Event Grid Topics.

I'm following a couple of Microsoft tutorials and Github repos and have written some python code to create topics.


Python samples: https://learn.microsoft.com/en-us/samples/azure-samples/event-grid-python-public-consume-events/event-grid-python-public-consume-events/

Github Repos: https://github.com/Azure-Samples/event-grid-python-public-consume-events

Azure Service Principal: https://azure.microsoft.com/documentation/articles/resource-group-create-service-principal-portal


I've come up with this python code:

def CreateOrUpdateTopics(subscriptionId, clientId, clientSecret,tenantId,resourceGroup,location, topics):   

        credentials = ServicePrincipalCredentials(
            client_id=clientId,
            secret=clientSecret,
            tenant=tenantId
            )

        print("\nCreate event grid management client")
        event_grid_client = EventGridManagementClient(credentials, subscriptionId)

        for topic in topics:
            print(f'\nCreating EventGrid topic {topic}')
            topic_result_poller = event_grid_client.topics.create_or_update(resourceGroup,
                                                                     topic,
                                                                     Topic(
                                                                         location=location,
                                                                         tags={'createdBy': 'MCCC'}
                                                                     ))
            # Blocking call            
            topic_result = topic_result_poller.result()

            ## ERROR SHOWS UP HERE
            print(topic_result)

When I execute the code I receive a message

The client 'zzzz' with object id 'zzzz' does not have authorization to perform action 'Microsoft.EventGrid/topics/write' over scope '/subscriptions/zzz/resourceGroups/MCCC-RG/providers/Microsoft.EventGrid/topics/Temperature' or the scope is invalid. If access was recently granted, please refresh your credentials.

I registered a new app in Azure Active Directory:

enter image description here

I've also assigned a role to the resource group for the SP.

enter image description here

It seems like i'm missing some role access on my service principle though I can't seem to find a reference to what it should be.

Could you please point me in the right direction?


Solution

  • Looking at the role definition of EventGrid EventSubscription Contributor, it does not have the permission to perform Microsoft.EventGrid/topics/write action. Only following actions are allowed:

          "Microsoft.Authorization/*/read",
          "Microsoft.EventGrid/eventSubscriptions/*",
          "Microsoft.EventGrid/topicTypes/eventSubscriptions/read",
          "Microsoft.EventGrid/locations/eventSubscriptions/read",
          "Microsoft.EventGrid/locations/topicTypes/eventSubscriptions/read",
          "Microsoft.Insights/alertRules/*",
          "Microsoft.Resources/deployments/*",
          "Microsoft.Resources/subscriptions/resourceGroups/read",
          "Microsoft.Support/*"
    

    What you would need to do is to create a Custom Role that has Microsoft.EventGrid/topics/write as one of the allowed actions.

    From the same link, here's one definition of custom role that you could create and use:

    {
      "Name": "Event grid contributor role",
      "Id": "4BA6FB33-2955-491B-A74F-53C9126C9514",
      "IsCustom": true,
      "Description": "Event grid contributor role",
      "Actions": [
        "Microsoft.EventGrid/*/write",
        "Microsoft.EventGrid/*/delete",
        "Microsoft.EventGrid/topics/listkeys/action",
        "Microsoft.EventGrid/topics/regenerateKey/action",
        "Microsoft.EventGrid/eventSubscriptions/getFullUrl/action"
      ],
      "NotActions": [],
      "AssignableScopes": [
        "/subscriptions/<Subscription id>"
      ]
    }