Microsoft Azure Resource Management (ARM) Templates, Service Bus, Topics and Subscriptions


If you've logged into the Azure Management Portal recently, you might've noticed that we are now able to export templates from our resource groups! That's absolutely amazing and is something that surely will save us a lot of time throughout our Azure careers. If you have any Service Bus resources, you might've also noticed, however, that those are not included in the template!

Furthermore, the Service Bus templates are not available in Visual Studio's Add Resources ARM tooling. Bummer! Here's how you add the necessary nodes into your JSON deployment template:

Ok, so what's with all the parameters and variables? Let's go through them together:

sbVersion is set to the first available API version within the service bus namespace:
"sbVersion": "[providers('Microsoft.ServiceBus', 'namespaces').apiVersions[0]]"

sbNamespace depends on the deployEnvironment parameter. In our case, that is either 'test' or 'prod':
"sbNamespace": "[concat('wp-business-events-', parameters('deployEnvironment'))]"

It's always a good idea to associate your resource's location with the location of your resource group (since that'll save you money in transfer costs between data centers and will lower latency between your resources):
"location": "[resourceGroup().location]"

messagingSku? To quote a fellow blogger
The messagingSku here defines if you want a Basic (1), Standard (2) or Premium (3) namespace, since we are going to use topics we must at least be on Standard.

A service bus namespace can have child queues, topics, relays and event hubs (see Microsoft's new Service Bus Learning Path). For this post, we're interested in topics. Therefore, we create a new sub-resource (of type Topics) in our namespace and pass along our topic name:
"name": "[parameters('my-service-bus-topic']"

And inside our Topic, we create another sub-resource (of type Subscriptions), giving it the name passed along from our parameters.

What about access? We can define namespace-level access rules by adding a sub-resource of type Microsoft.ServiceBus/namespaces/authorizationRules. In this example, I've named my rules Enqueue and Dequeue. Enqueue is a SendShareAccessKey with the rights Send (DRY anyone?) meaning it can only write to the topic. Dequeue is a Receive....

The primary and secondary keys passed into the rules, are a base64-encoded GUID (generated from Visual Studio's nguid-snippet).

ARM templates are wonderful after they've been written: Provisioning an entire environment in a couple of clicks is a huge productivity booster. As icing on the cake, they can provide us with ready-to-use connection strings as output, if we author them correctly:

In the example above, I've included a storage node as well, so that you can see how that works. When you publish this template, you will get three outputs with ready-to-use connection string keys that you can paste into your configs files. There are some more variables though:

enqueueAuthRuleResourceId is the full Id to the Enqueue rule:
"[resourceId('Microsoft.ServiceBus/namespaces/authorizationRules', variables('sbNamespace'), 'Enqueue')]"

dequeueAuthRuleResourceId follows the same pattern.

The astute reader will notice that we set up shared access keys for the entire namespace. In a future post, I'm considering exploring how to associate the keys with the individual topic.

There we go - this should be enough for you to get started! If you have any questions, go ahead and post them below. Have fun decoupling your systems! ;-)


Comments

Popular posts from this blog

Auto Mapper and Record Types - will they blend?

Unit testing your Azure functions - part 2: Queues and Blobs

Testing WCF services with user credentials and binary endpoints