I wrote an ARM template to script the deploy and configuration of ServiceBus. One of the goals of the script was to make it easy to manage topics and subscriptions. In order to accomplish this, the script uses variables that are arrays.
This all works fine, but I'm seeing an issue whenever I try to use the same subscription name for two different topics. Now, I understand that a subscription can only be mapped to a single topic. The script attempts to account for that by joining the subscription name to the topic.
I should also note that the Azure UI will allow you to use the same subscription name beneath two topics. This script was derived from setting up this scenario via the azure console then exporting the ARM.
I have been over this script several dozen times and I'm not seeing the cause. Hoping new eyes will help.
Here is the script:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"envType": {
"type": "string",
"allowedValues": [ "dev", "prod" ],
"defaultValue": "dev",
"metadata": { "description": "The environment type being created" }
},
"sbSku": {
"type": "string",
"allowedValues": [ "Standard", "Premium" ],
"defaultValue": "Standard",
"metadata": { "description": "The messaging tier for service Bus namespace" }
}
},
"variables": {
"defaultSASKeyName": "RootManageSharedAccessKey",
"authRuleResourceId": "[resourceId('Microsoft.ServiceBus/namespaces/authorizationRules', variables('sbNamespaceName'), variables('defaultSASKeyName'))]",
"sbNamespaceName": "[concat(parameters('envType'), 'eventbus')]",
"sbVersion": "2017-04-01",
"sbTopics": [
"mytopic1",
"mytopic2",
"mytopic3",
"mytopic4"
],
"sbSubscriptions": [
{ "Name": "mysubA", "Topic": "mytopic1" },
{ "Name": "mysubB", "Topic": "mytopic2" },
{ "Name": "mysubB", "Topic": "mytopic3" },
{ "Name": "mysubC", "Topic": "mytopic4" }
]
},
"resources": [
{
"apiVersion": "[variables('sbVersion')]",
"location": "[resourceGroup().location]",
"name": "[variables('sbNamespaceName')]",
"properties": {},
"sku": {
"name": "[parameters('sbSku')]"
},
"tags": {},
"type": "Microsoft.ServiceBus/Namespaces"
},
{
"type": "Microsoft.ServiceBus/namespaces/topics",
"name": "[concat(variables('sbNamespaceName'), '/', variables('sbTopics')[copyIndex()])]",
"apiVersion": "[variables('sbVersion')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/', variables('sbNamespaceName'))]"
],
"properties": {
"defaultMessageTimeToLive": "P14D",
"maxSizeInMegabytes": 1024,
"requiresDuplicateDetection": false,
"enablePartitioning": true
},
"copy": {
"name": "topiccopy",
"count": "[length(variables('sbTopics'))]",
"mode": "Serial",
"batchSize": 3
}
},
{
"type": "Microsoft.ServiceBus/namespaces/topics/subscriptions",
"name": "[concat(variables('sbNamespaceName'), '/', variables('sbSubscriptions')[copyIndex()].Topic, '/', variables('sbSubscriptions')[copyIndex()].Name)]",
"apiVersion": "2017-04-01",
"location": "East US",
"dependsOn": [
"[resourceId('Microsoft.ServiceBus/namespaces', variables('sbNamespaceName'))]",
"[resourceId('Microsoft.ServiceBus/namespaces/topics', variables('sbNamespaceName'), variables('sbSubscriptions')[copyIndex()].Topic)]"
],
"properties": {
"maxDeliveryCount": 10
},
"copy": {
"name": "subscriptioncopy",
"count": "[length(variables('sbSubscriptions'))]",
"mode": "Serial",
"batchSize": 1
}
}
],
"outputs": {
"NamespaceConnectionString": {
"type": "string",
"value": "[listkeys(variables('authRuleResourceId'), variables('sbVersion')).primaryConnectionString]"
},
"SharedAccessPolicyPrimaryKey": {
"type": "string",
"value": "[listkeys(variables('authRuleResourceId'), variables('sbVersion')).primaryKey]"
},
"Topics": {
"type": "array",
"value": "[concat(variables('sbTopics'))]"
},
"Subscriptionss": {
"type": "array",
"value": "[concat(variables('sbSubscriptions'))]"
}
}
}
When executed with:
New-AzureRmResourceGroupDeployment -ResourceGroupName {xxx} -TemplateFile arm.servicebus.example.json
It returns:
New-AzureRmResourceGroupDeployment : 2:58:05 PM - Error: Code=InvalidTemplate; Message=Deployment template validation
failed: 'The template resource 'Microsoft.ServiceBus/namespaces/deveventbus/topics/mytopic3/subscriptions/mysubB'
cannot reference itself. Please see https://aka.ms/arm-template-expressions/#reference for usage details.'.
At line:1 char:1
+ New-AzureRmResourceGroupDeployment -ResourceGroupName Wiretappers_Ste ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-AzureRmResourceGroupDeployment], Exception
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.NewAzureResourceGroupDep
loymentCmdlet
New-AzureRmResourceGroupDeployment : The deployment validation failed
At line:1 char:1
+ New-AzureRmResourceGroupDeployment -ResourceGroupName Wiretappers_Ste ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmResourceGroupDeployment], InvalidOperationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.NewAzureResourceGroupDep
loymentCmdlet
The issue is caused by the third entry in the 'sbSubscriptions' array (mysubB/mytopic3). This is being processed in the third object beneath 'resources'.
If anyone can see my oversight, it would be appreciated.
PS. If anyone knows how to get the Azure tools to output the template json after it has expanded the "copy" node and the functions (resourceId, concat) that would be helpful as well.
UPDATE:2018-03-01 Here is a working template for future reference. See all comments below for details.
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"envType": {
"type": "string",
"allowedValues": [ "dev", "prod" ],
"defaultValue": "dev",
"metadata": { "description": "The environment type being created" }
},
"sbSku": {
"type": "string",
"allowedValues": [ "Standard", "Premium" ],
"defaultValue": "Standard",
"metadata": { "description": "The messaging tier for service Bus namespace" }
}
},
"variables": {
"sbNamespaceName": "[concat(parameters('envType'), 'eventbus')]",
"sbVersion": "2017-04-01",
"sbTopics": [
"mytopic1",
"mytopic2",
"mytopic3",
"mytopic4"
],
"sbSubscriptions": [
{ "Name": "mysubA", "Topic": "mytopic1" },
{ "Name": "mysubB", "Topic": "mytopic2" },
{ "Name": "mysubB", "Topic": "mytopic3" },
{ "Name": "mysubC", "Topic": "mytopic4" }
]
},
"resources": [
{
"apiVersion": "[variables('sbVersion')]",
"location": "[resourceGroup().location]",
"name": "[variables('sbNamespaceName')]",
"properties": {},
"sku": {
"name": "[parameters('sbSku')]"
},
"tags": {},
"type": "Microsoft.ServiceBus/Namespaces"
},
{
"type": "Microsoft.ServiceBus/namespaces/topics",
"name": "[concat(variables('sbNamespaceName'), '/', variables('sbTopics')[copyIndex()])]",
"apiVersion": "[variables('sbVersion')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[variables('sbNamespaceName')]"
],
"properties": {
"defaultMessageTimeToLive": "P14D",
"maxSizeInMegabytes": 1024,
"requiresDuplicateDetection": false,
"enablePartitioning": true
},
"copy": {
"name": "topiccopy",
"count": "[length(variables('sbTopics'))]",
"mode": "Serial",
"batchSize": 3
}
},
{
"type": "Microsoft.ServiceBus/namespaces/topics/subscriptions",
"name": "[concat(variables('sbNamespaceName'), '/', variables('sbSubscriptions')[copyIndex()].Topic, '/', variables('sbSubscriptions')[copyIndex()].Name)]",
"apiVersion": "[variables('sbVersion')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.ServiceBus/namespaces', variables('sbNamespaceName'))]",
"[resourceId('Microsoft.ServiceBus/namespaces/topics', variables('sbNamespaceName'), variables('sbSubscriptions')[copyIndex()].Topic)]"
],
"properties": {
"maxDeliveryCount": 10
},
"copy": {
"name": "subscriptioncopy",
"count": "[length(variables('sbSubscriptions'))]"
}
}
],
"outputs": {
"Topics": {
"type": "array",
"value": "[concat(variables('sbTopics'))]"
},
"Subscriptionss": {
"type": "array",
"value": "[concat(variables('sbSubscriptions'))]"
}
}
}
Test-AzureRmResourceGroupDeployment -verbose
or-debug
and it will show you that (most likely) – 4c74356b41