1
votes

We want to have two resource group, 1- shared-resource group for shared resources like app service plan, ... 2- another resource-group for other resources like web-app. We are using nested link template which contains three level:

  1. highest level is main deployment template file which contains everything.
  2. next level is for calling all resource templates for each resource-group, e.g we have two template file in this level one for shared resource-group and two other resource-group, so for-example first file will call some link template to create app service plan, elastic pool and .... second file will call link templates for deploying web-app, network and ....
  3. last level is our generic resource templates, in this level for each resource we have a template file e.g for web-app we have a generic template which deploy web-app with some parameters. Now the question is how we can use 'dependson' to create all shared-Resources first after that deploy all other resources?

*please note: shared resources are in different resource-group and other resources are in another resource-group so we have two resource-group which both and all included resources are deploying in main template file.

My main deployment template file is this:

    // Include rg-CockpitShared and app specific resources - and share parameters
   {
     "$schema": "https://schema.management.azure.com/schemas/2018-05- 
  01/subscriptionDeploymentTemplate.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
       "location": {
      "type": "string"
    },
    "cockpitEnvironment": {
      "type": "string"
    }
  },
  "variables": {
    "currentTemplateUri": "[deployment().properties.templateLink.uri]",
    "rgCockpitSharedUrl": "[concat(uri(variables('currentTemplateUri'), 'rg-CockpitShared/rg-CockpitShared.json'))]",
    "rgCockpitSharedParametersUrl": "[concat(uri(variables('currentTemplateUri'), concat('rg-CockpitShared/rg-CockpitShared.parameters.', parameters('cockpitEnvironment'), '.json')))]",
    "rgClientCmdbTemplateUrl": "[concat(uri(variables('currentTemplateUri'), 'rg-ClientCmdb/rg-ClientCmdb.json'))]",
    "rgClientCmdbParametersUrl": "[concat(uri(variables('currentTemplateUri'), concat('rg-ClientCmdb/rg-ClientCmdb.parameters.', parameters('cockpitEnvironment'), '.json')))]"

  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "location": "[parameters('location')]",
      "apiVersion": "2019-10-01",
      "name": "CockpitShared",
      "tags": {
        "devOwner": "aspBuild"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[variables('rgCockpitSharedUrl')]",
           "contentVersion": "1.0.0.0"
        },
        "parametersLink": {
          "uri": "[variables('rgCockpitSharedParametersUrl')]",
           "contentVersion": "1.0.0.0"
        }
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "location": "[parameters('location')]",
      "apiVersion": "2019-10-01",
      "name": "otherResources",
      "tags": {
        "devOwner": "aspBuild"
      },
      "dependsOn": [
        "CockpitShared"
      ],
      "properties": {
        "mode": "Incremental",     
        "templateLink": {
          "uri": "[variables('rgClientCmdbTemplateUrl')]",
           "contentVersion": "1.0.0.0"
        },
        "parametersLink": {
          "uri": "[variables('rgClientCmdbParametersUrl')]",
           "contentVersion": "1.0.0.0"
        }
      }
    }
  ],

  "outputs": {
    "rgCockpitSharedUrl": {
      "type": "string",
      "value": "[variables('rgCockpitSharedUrl')]"
    },
    "rgCockpitSharedParametersUrl": {
      "type": "string",
      "value": "[variables('rgCockpitSharedParametersUrl')]"
    }
  }
}

So What I have done here is using dependsOn = "CockpitShared" and expected that first it deploys shared resources and after that start to deploy 'otherResources', but I got error that app-service-plan is not found which means it's not wait to shared resources be deployed and I don't understand why? :(

1
I think you should save the resource ID of app service plan as output of first template and the pass it to second template. - Jagrati Modi
I used something similar to what you said and it works, I used reference and output. Thank you. - S.Cheginy
You can add your solution as answer so that it will be useful to others. - Jagrati Modi
Sure, I'll do it - S.Cheginy

1 Answers

0
votes

Finally I found a solution: I used 'reference' instead of 'dependson'. So in my shared-Resources arm template I return app service plan name as output and used it from my main deployment file so it wait for finishing shared resources deployment first and after that start to deploy web app ... for more detail see below code:

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string"
    },
    "cockpitEnvironment": {
      "type": "string"
    },
    "storageAccountUri": {
      "type": "string"
    }
  },
  "variables": {
    "rgCockpitSharedUrl": "[concat(uri(parameters('storageAccountUri'), 'rg-CockpitShared/rg-CockpitShared.json'))]",
    "rgClientCmdbTemplateUrl": "[concat(uri(parameters('storageAccountUri'), 'ClientCmdb/rg-ClientCmdb/rg-ClientCmdb.json'))]"

  },
  "functions": [
    {
      "namespace": "ClientCmdb",
      "members": {
        "SelectValueByEnv": {
          "parameters": [
            {
              "name": "Environment",
              "type": "string"
            },
            {
              "name": "prodValue",
              "type": "string"
            },
            {
              "name": "devValue",
              "type": "string"
            },
            {
              "name": "testValue",
              "type": "string"
            }
          ],
          "output": {
            "type": "string",
            "value": "[if(equals(parameters('Environment'),'prod'),parameters('prodValue'),if(equals(parameters('Environment'),'dev'),parameters('devValue'),parameters('testValue')))]"
          }
        }
      }
    }
  ],
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "location": "[parameters('location')]",
      "apiVersion": "2019-10-01",
      "name": "CockpitShared",
      "tags": {
        "devOwner": "aspBuild"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[variables('rgCockpitSharedUrl')]"
        },
        "parameters": {
          "rgName": {
            "value": "[ClientCmdb.SelectValueByEnv(parameters('cockpitEnvironment'),'rg-CockpitShared','rg-CockpitShared','rg-CockpitShared')]"
          },
          "location": {
            "value": "[parameters('location')]"
          },
          "cockpitEnvironment": {
            "value": "[parameters('cockpitEnvironment')]"
          }
        }
      }

    },
    {
      "type": "Microsoft.Resources/deployments",
      "location": "[parameters('location')]",
      "apiVersion": "2019-10-01",
      "name": "ClientCmdb",
      "tags": {
        "devOwner": "aspBuild"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[variables('rgClientCmdbTemplateUrl')]"
        },
        "parameters": {
          "rgName": {
            "value": "[ClientCmdb.SelectValueByEnv(parameters('cockpitEnvironment'),'rg-ClientCmdb','rg-ClientCmdb','rg-ClientCmdb')]"
          },
          "location": {
            "value": "[ClientCmdb.SelectValueByEnv(parameters('cockpitEnvironment'),'northeurope','northeurope','northeurope')]"
          },
          "cockpitEnvironment": {
            "value": "[parameters('cockpitEnvironment')]"
          },
          "planName": {


// Here__________________________________________________________________________________
            "value": "[reference('CockpitShared').outputs.planName.value]"
          }
        }
      }
    }
  ],

 
}

so basically I pass my app service plan name from shared resource template to main template and main template gets it by 'reference' and pass it to other resources template via parameter. Regarding to do that I had to use inline params as I was using params in seperated files...

Hope it's useful for someone else :)