8

Azure Resource Manager (ARM) Templates have the ability to use Linked Templates. These linked templates can define additional resources to create during an ARM template deployment.

ARM templates support dependencies which ensure some resources are created before others are.

I would like to specify a dependency in a linked template for a resource created in the master template. If I include the dependency in the Linked Template, it looks like this:

"resources": [
    {
        "apiVersion": "2015-08-01",
        "type": "Microsoft.Web/sites/hostNameBindings",
        "name": "[concat(parameters('siteName'),'/', parameters('fqdn'))]",
        "dependsOn": [
            "[concat('Microsoft.Web/sites/', parameters('siteName'))]"
        ],
        "properties": {
            "siteName": "[parameters('siteName')]"
        }
    }
]

While the dependsOn appears correct, the a resource is created at Microsoft.Web/sites/{siteNameParameter}, deploying the ARM template outputs the following error message:

InvalidTemplate : Deployment template validation failed: 'The resource 'Microsoft.Web/sites/blahblahblahblah' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'.

I am currently defining this dependency in the master template when I define the linked template call. This seems brittle and easy to break. Is there a better way than defining dependencies in the master ARM template?

{
    "apiVersion": "2015-01-01",
    "name": "SomeName",
    "type": "Microsoft.Resources/deployments",
    "dependsOn": [
        "[concat('Microsoft.Web/sites/', parameters('siteName'))]"
    ],
    "properties": {
        "mode": "Incremental",
        "templateLink": {
            "uri": "https://tempuri.org/supersecrettemplatepath/azuredeploy.json",
            "contentVersion": "1.0.0.0"
        },
        "parameters":
        {
            "fqdn": {
                "value": "www.tempuri.org"
            },
            "siteName": {
                "value": "[parameters('siteName')]"
            }
        }
    }
}
Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
Dustin Venegas
  • 760
  • 1
  • 7
  • 16

3 Answers3

6

You can define the dependency either way - both are valid. Putting the dependency on the deployment resource (your second approach) will mean that the entire nested deployment is not started until the web site is provisioned. If you wanted to kick some things off in parallel, then you would put the dependency in the nested template (your first approach). That may or may not matter for your scenario, but that's a key difference.

dependsOn requires a resourceId - and as the error is trying to say, if the resource is not defined in the template you need more detail in the resourceId, in this case, you need the resourceGroup (maybe the subscription, but I doubt it). So for example you can use:

"dependsOn": [
    "[resourceId(resourceGroup().name, 'Microsoft.Web/sites', parameters('siteName'))]"
],
Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
bmoore-msft
  • 8,376
  • 20
  • 22
  • Interesting! I will have to give this a roll. It was my understanding @bmore-msft that the resourceGroup().name should be automatically populated in all `dependsOn` calls by default though. Is that not the case for nested-templates? – Dustin Venegas Sep 07 '16 at 18:40
  • Sort of - if it's not supplied, it's assumed to be in the same template - nested templates are actually separate/independent deployments in AzureRM. – bmoore-msft Sep 09 '16 at 15:40
  • 2
    Regretfully, this output the same error message as before. ```"Deployment template validation failed: 'The resource 'Microsoft.Web/sites/somesite' is not defined in the template. ``` – Dustin Venegas Sep 20 '16 at 20:39
  • Probably need to see the entire template(s) - if you can post those somewhere I can take a look... – bmoore-msft Sep 22 '16 at 22:07
  • without the subscription, I was still getting the error. even with the subscription, it was not waiting. I was trying to wait for storage to complete and then grab the access key, but it kept saying ResourceNotFound. How extremely annoying :) – MPavlak Jun 26 '17 at 18:48
  • @MPavlak - using listKeys on a storageAccount is a pretty common pattern - if it's not working for you kick off a thread with your template... https://gist.github.com/bmoore-msft/73246e41659206be031e8b2fe78eef1c – bmoore-msft Jun 27 '17 at 16:18
  • I think the problem is that I'm using Deployment resources and one sub resource depends on a resource in a different deployment. i cannot get it to wait no matter what I do. I'll move it over there when I get a second to pull up that work again. I aborted and just made one giant template without deployment resources to get past that problem. – MPavlak Jun 27 '17 at 17:22
  • You did find the problem... dependsOn only works with resources in the same deployment. A resource in a "child" deployment is in a different deployment than it's "parent". In that case you have to use the deployment resource itself as the dependency. – bmoore-msft Jun 28 '17 at 14:54
  • It's not working with resource defined in parent template and dependency on the nested template – user2323308 Aug 08 '20 at 19:31
5

The dependsOn needs the name of the linked deployment, not one of the resources in it.

e.g.:

dependsOn: "Microsoft.Resources/deployments/myExternalTemplate"

-1
"dependsOn": [
    "[resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Web/sites', parameters('siteName'))]"
],
juvchan
  • 6,113
  • 2
  • 22
  • 35