Reputation: 41
I have an ARM template that is giving me some trouble. I have it deploy to the subscription level one Resource Group, then a Service Bus to that newly created Resource Group. The Service Bus itself has 4 authorizationRules, a queue, 4 topics, two of which have their own authorizationRules. This all works fine. I try to add the PrimaryConnectionString for these latter two authorizationRules as secrets to a KeyVault in a different resource group, and this is where I start getting issues. Below is the full ARM template. I am currently only trying to get the PrimaryConnectionString from the SharedCtxListenerServiceAccessKey
authorizationRule from the shared-context
topic.
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"tags": {
"type": "object",
"metadata": {
"description": "Specifies the tags for the Service Bus related Azure Resources."
}
},
"environment": {
"type": "object",
"metadata": {
"description": "Specifies the Team Environment information."
}
},
"serviceBus": {
"type": "object",
"metadata": {
"description": "Specifies the Service Bus information."
}
}
},
"variables": {
"serviceBus": {
"namespace": {
"name": "[concat('team-', toLower(parameters('environment').name),'-sbn')]"
},
"ResourceGroupName": "[concat('Team-ServiceBus-',parameters('environment').suffix)]"
},
"keyVault": {
"Name": "[concat('Team-Utilities-',parameters('environment').suffix, '-kv')]",
"ResourceGroupName": "[concat('Team-Utilities-',parameters('environment').suffix)]"
}
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2019-10-01",
"name": "[variables('serviceBus').ResourceGroupName]",
"location": "[parameters('environment').location]",
"properties": {
},
"tags": {
"Department": "[parameters('tags').Department]",
"Product": "[parameters('tags').Product]",
"Service": "[parameters('tags').Service]",
"Environment": "[parameters('tags').environment]"
}
},
{
"type": "Microsoft.Resources/deployments",
"name": "ServiceBus_Infrastructure",
"apiVersion": "2017-05-10",
"resourceGroup": "[variables('serviceBus').ResourceGroupName]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "[variables('serviceBus').namespace.name]",
"type": "Microsoft.ServiceBus/namespaces",
"apiVersion": "2017-04-01",
"location": "[parameters('environment').location]",
"properties": {
},
"sku": {
"name": "[parameters('serviceBus').namespace.sku.name]",
"tier": "[parameters('serviceBus').namespace.sku.tier]"
},
"tags": {
"Department": "[parameters('tags').Department]",
"Product": "[parameters('tags').Product]",
"Service": "[parameters('tags').Service]",
"Environment": "[parameters('tags').environment]"
},
"resources": [
{
"type": "AuthorizationRules",
"name": "RootManagerSharedAccessKey",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]"
]
},
{
"type": "AuthorizationRules",
"name": "PubSubSharedAccessKey",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Listen",
"Send"
]
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]",
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name, '/authorizationRules/RootManagerSharedAccessKey')]"
]
},
{
"type": "AuthorizationRules",
"name": "PublishSharedAccessKey",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Send"
]
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]",
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name, '/authorizationRules/PubSubSharedAccessKey')]"
]
},
{
"type": "AuthorizationRules",
"name": "ClientSharedAccessKey",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Listen"
]
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]",
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name, '/authorizationRules/PublishSharedAccessKey')]"
]
},
{
"type": "queues",
"name": "activity-log",
"apiVersion": "2017-04-01",
"properties": {
"lockDuration": "PT5M",
"maxSizeInMegabytes": 5120,
"requiresDuplicateDetection": false,
"requiresSession": false,
"defaultMessageTimeToLive": "P10675199DT2H48M5.4775807S",
"deadLetteringOnMessageExpiration": false,
"maxDeliveryCount": 10,
"autoDeleteOnIdle": "P10675199DT2H48M5.4775807S",
"enablePartitioning": false,
"enableExpress": false
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]"
]
},
{
"type": "topics",
"name": "pdf-splitted",
"apiVersion": "2017-04-01",
"properties": {
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]"
]
},
{
"type": "topics",
"name": "platform-admin",
"apiVersion": "2017-04-01",
"properties": {
},
"resources": [
{
"type": "authorizationRules",
"name": "PlatformAdminListenerServiceAccessKey",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Listen"
]
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name, '/topics/platform-admin')]"
]
}
],
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]"
]
},
{
"type": "topics",
"name": "shared-context",
"apiVersion": "2017-04-01",
"properties": {
},
"resources": [
{
"type": "authorizationRules",
"name": "SharedCtxListenerServiceAccessKey",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Listen"
]
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name, '/topics/shared-context')]"
]
}
],
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]"
]
},
{
"type": "topics",
"name": "transaction-audit",
"apiVersion": "2017-04-01",
"properties": {
},
"dependsOn": [
"[concat('Microsoft.ServiceBus/namespaces/',variables('serviceBus').namespace.name)]"
]
}
]
}
],
"outputs": {
"SharedCtxListenerServiceAccessKeyResourceId": {
"type": "string",
"value": "[resourceId('Microsoft.ServiceBus/namespaces/topics/authorizationRules',variables('serviceBus').namespace.name, 'shared-context','SharedCtxListenerServiceAccessKey')]"
}
}
}
},
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', variables('serviceBus').resourceGroupName)]"
]
},
{
"type": "Microsoft.Resources/deployments",
"name": "ServiceBus_Secrets",
"apiVersion": "2017-05-10",
"resourceGroup": "[variables('keyVault').ResourceGroupName]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(variables('keyVault').Name,'/SharedContext-Listener-ConnectionString')]",
"apiVersion": "2016-10-01",
"properties": {
"contentType": "ConnectionString",
"value": "[resourceId('Microsoft.ServiceBus/namespaces/topics/authorizationRules',variables('serviceBus').namespace.name, 'shared-context','SharedCtxListenerServiceAccessKey')]"
}
}
]
}
},
"dependsOn": [
"[concat('Microsoft.Resources/deployments/','ServiceBus_Infrastructure')]"
]
}
]
}
After trying several different approaches, I have managed to use the output of the ServiceBus_Infrastructure deployment to send the resourceId and use that as the secret to the KeyVault, as a way of testing that most of it is functioning as expected. I have tried using the listkey() function in the outputs like so:
"SharedCtxListenerServiceAccessKeyResourceId": {
"type": "string",
"value": "[listkeys(resourceId('Microsoft.ServiceBus/namespaces/topics/authorizationRules',variables('serviceBus').namespace.name, 'shared-context','SharedCtxListenerServiceAccessKey'),'2017-04-01').PrimaryConnectionString]"
}
}
However that gave me this error: {"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"NotFound","message":"{\r\n \"error\": {\r\n \"code\": \"ParentResourceNotFound\",\r\n \"message\": \"Can not perform requested operation on nested resource. Parent resource 'team-development-sbn' not found.\"\r\n }\r\n}"}]}
This is odd because that Service Bus is created in the previous deployment, which this last deployment resource dependsOn. I think I read somewhere that since the service bus resource is in a deployment resource that it doesn't necessarily know that it's actually completed, and this might be why it can't find it?
I have also tried doing the listKeys() function in the value field of the keyvault secret, but than it says that the reference() function is not expected here.
My basic question is this: How can I get the PrimaryConnectionString and deploy it as a secret to a keyvault in a different resource group, ideally in the same template (as this is one of many services that hopefully can follow this pattern where resources are created and the necessary values are stored in a central keyvault) Thanks for any help!
Upvotes: 1
Views: 584
Reputation: 72191
I suppose if you rerun this template it would work. SO what is happening - you are using nested templates and they "render" everything at the same time, so they dont really have dependencies inside the nested templates (well, they do, but its a bit weird). In short I'd suggest you use linked templates (so convert service bus deployment to a linked one) and do it that way.
ps. honestly, just ditch subscription level deployments completely unless you plan to manage subscription level resources with arm templates.
Upvotes: 0