Creating an Event Grid Topic subscription to a resource in a different resource group

With all of the great services in Azure, it’s easy to set up a nice event-driven architecture. You have Storage Queues, Service Bus Queues & Topics, Event Grid and even more services which can help you accomplish great stuff.
I like the three services mentioned here and most of the time they cover the basics of my messaging infrastructure. One thing you need to do yourself is think about the boundaries of your domains and how to organize all of the services.

What I see happen quite often, and don’t disagree with, is placing all the Custom Topics for Event Grid inside a single, dedicated, resource group. From a developer & operations discovery perspective this makes quite a lot of sense.
There are of course downsides to this approach with the most obvious one being security. If you have access to this resource group, there’s a fairly big chance you have enough permissions to peek inside all of the Event Grid Topics. To lock this down you have to take additional measures which I will not cover over here.

Because we should all be using ARM templates (or something similar) nowadays, it makes sense to create the Event Grid Topics & Subscriptions in your deployment pipeline.
The documentation on this topic is very good and you can figure out how to create a custom topic and subscription quite easily. However, I did get stuck creating a subscription.

What I couldn’t figure out was how to create an Event Grid subscription where the destination is a Storage Queue residing in a completely different resource group.
My first attempt looked a bit like this.

...
{
    "name": "[MyCustomTopicName]/Microsoft.EventGrid/[MySubscriptionName]",
    "type": "Microsoft.EventGrid/topics/providers/eventSubscriptions",
    "location": "[resourceGroup().location]",
    "apiVersion": "2019-06-01",
    "properties": {
        "destination": {
            "endpointType": "StorageQueue",
            "properties": {
                "resourceId": "[resourceId('Microsoft.Storage/storageAccounts', variables('theNameOfMyStorageAccount'))]",
                "queueName": "[variables('theNameOfMyQueue')]"
            }
        },
        "filter": {
            "advancedFilters": []
        },
        "labels": [],
        "eventDeliverySchema": "EventGridSchema"
    }
}
...

This all looks well, but when deploying this template you’ll be prompted with a message stating it can’t find the Event Grid Topic

Deployment failed. Correlation ID: [guid].

  "error": {
    "code": "ResourceNotFound",
    "message": "The Resource 'Microsoft.EventGrid/topics/[MyCustomTopicName]' under resource group '[TheResourceGroupTheStorageAccountIsIn]' was not found."
  }
}

This makes a lot of sense as I’m ‘referencing’ a custom topic which isn’t defined inside this specific template.

The solution to this is using nested templates.
Using these types of templates is very useful if you, like in this case, want to deploy services in several resource groups via 1 template. What I came up with is the following excerpt.

{
    "apiVersion": "2017-05-10",
    "name": "nestedTemplate",
    "type": "Microsoft.Resources/deployments",
    "resourceGroup": "your_topic_resource_group",
    "properties": {
        "mode": "Incremental",
        "template": {
            "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
            "contentVersion": "1.0.0.0",
            "parameters": {},
            "variables": {},
            "resources": [
                {
                    "name": "[MyCustomTopicName]/Microsoft.EventGrid/[MySubscriptionName]",
                    "type": "Microsoft.EventGrid/topics/providers/eventSubscriptions",
                    "location": "[resourceGroup().location]",
                    "apiVersion": "2019-06-01",
                    "properties": {
                        "destination": {
                            "endpointType": "StorageQueue",
                            "properties": {
                                "resourceId": "[resourceId('Microsoft.Storage/storageAccounts', variables('theNameOfMyStorageAccount'))]",
                                "queueName": "[variables('theNameOfMyQueue')]"
                            }
                        },
                        "filter": {
                            "advancedFilters": []
                        },
                        "labels": [],
                        "eventDeliverySchema": "EventGridSchema"
                    }
                }
            ]
        }
    }
},

In this resource, I’m pointing the deployment resource to your_topic_resource_group, which is the resource group where my custom topics are deployed. Because of this, I can use the MyCustomTopicName/Microsoft.EventGrid/MySubscriptionName to create the new Event Grid subscriptions.
The best thing of all, I’m still able to reference the Storage Account where the Storage Queue is located at because it’s defined inside this very same template.


Share