1
votes

I plan to create two resources in my resource groups: one web app and one service bus. The web app is going to have a connection string to point to the service bus. So, I need to first create the service bus and then add web app with its connection string. For both web app and the service bus, I'm using linked templates. My simplified azuredeploy.json looks like this:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "name": "myWebAppDeploy",
      "apiVersion": "2017-05-10",
      "type": "Microsoft.Resources/deployments",
      "dependsOn": [
        "UNKNOWN-DEPENDENCY"
      ],
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "link/to/webapp.azuredeploy.json",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "name": {
            "value": "myWebApp"
          },
          "connectionStrings": {
            "value": {
              "serviceBusConnectionString": "[listKeys(resourceId('Microsoft.ServiceBus/namespaces/authorizationRules', 'myServiceBus', 'RootManageSharedAccessKey'), '2017-04-01').primaryConnectionString]"
            }
          }
        }
      }
    },
    {
      "name": "myServiceBusDeploy",
      "apiVersion": "2017-05-10",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "link/to/servicebus.azuredeploy.json",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "name": {
            "value": "myServiceBus"
          }
        }
      }
    }
  ]
}

No matter what I put in UNKNOWN-DEPENDENCY section, I receive the following error:

Template deployment returned the following errors:10:02:23 AM - Resource Microsoft.ServiceBus/namespaces/authorizationRules 'myServiceBus/RootManageSharedAccessKey' failed with message '{
  "error": {
    "code": "ParentResourceNotFound",
    "message": "Can not perform requested operation on nested resource. Parent resource 'myServiceBus' not found."
  }
}'

Looks like it's trying to deploy the web app before the service bus. I have tried the followings, but no luck:

"myServiceBus"
"myServiceBusDeploy",
"[concat('Microsoft.Resources/deployments/', 'myServiceBusDeploy')]",
"[concat('Microsoft.ServiceBus/namespaces', 'myServiceBus')]"
"[resourceId('Microsoft.Resources/deployments', 'myServiceBusDeploy')]"
"[resourceId('Microsoft.ServiceBus/namespaces', 'myServiceBus')]"

I'm out of ideas and don't know how to set up the dependencies between these two linked templates.

UPDATE: If I deploy my template again after receiving the error, it will work since the service bus is already deployed in the first deploy. So, I'm pretty sure that the nested/linked templates are OK.

2

2 Answers

2
votes

The problem here as Gleb noted is that listKeys is being evaluated immediately (design limitation in ARM which we're trying to fix).

To get around this you can do one of two things:

1) instead of passing the connstr to the template, just pass in the resourceId and perform the listKeys() in the web app deployment.

2) use a deployment output (of the connstr) in the service bus deployment and reference() that deployment output. This will work, but it also short-circuits /validation on the nested deployment, so #1 is a better overall approach.

HTH

1
votes

You can use the name of the resource you want to depend on ONLY if its UNIQUE, which, looking at the simplified version, it is. But if you want to be really sure you need to use resourceId() function:

"[resourceId('Microsoft.Resources/deployments', 'myServiceBusDeploy')]"

you can also use concat() function, but you need to assemble resourceId string exactly:

/subscriptions/guid/resourceGroups/rg_name/providers/Microsoft.Network/networkInterfaces/resource_name

Having said that, I dont see why this wouldn't work with your simplified version of the template. Might be the non simplified version has something that might interfere with dependsOn\resourceId.

If you are using subscription level deployment you might need to construct something like this:

/subscriptions/guid/resourceGroups/rg_name/providers/Microsoft.Resources/deployments/myServiceBusDeploy

yeah, like I always tell people here: "nested inline templates are crap, never use them unless you know what you are doing". the error doesnt come from the dependsOn property, error comes from the listKeys() function. because you are using nested inline deployment, listkeys() is being evaluated when the deployment starts, it is not a resource, so it doesnt honour the dependsOn property. you need to either move this to a nested template (deployed from url) or use listkeys() together with reference() function (it implies dependency and waits for the resource to be created).