coderanger
coderanger

Reputation: 31

ARM Templates - Multiple Linked Templates in a master template not allowed

We are trying to create an ARM template using linked templates. So i started with vnet and subnet and created 2 different linked templates. Now i tried to create a master.json and master.parameters.json . The parameters file has the values for name and address space of network and one subnet. Now, in the master template i tried to use 2 linked templates and the release in azure devops is failing with the following error: Deployment template validation failed: 'The resource 'Microsoft.Resources/deployments/LinkedTemplate' at line '37' and column '5' is defined multiple times in a template. Task failed while creating or updating the template deployment.

networkSubnetTest.json

"{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
    "vnetName": {
        "type": "string",
        "metadata": {
            "description": "Name of the Virtual Network"
        }
    },
    "vnetAddressPrefix": {
        "type": "string",
        "metadata": {
            "description": "The IP Address pool for the virtual network in CIDR format."
            }
    },
    "subnetPrefix": {
        "type": "string",
        "metadata": {
            "description": "The IP Address pool for the Subnet in CIDR format."
        }
    },
      "subnetName": {
        "type": "string",
        "metadata": {
            "description": "Name of the Subnet"
        }
    }
},

"variables": {
"templateBaseUrl": "https://github.com/something/",
"virtualNetworkTemplateUrl": "[concat(variables('templateBaseUrl'), 'VirtualNetwork.json')]",
"subnetTemplateUrl": "[concat(variables('templateBaseUrl'), 'Subnet.json')]",
"parametersUrl": "[concat(variables('templateBaseUrl'), 'networksubnetnsgtest.parameters.json')]"
},

"resources": [
{
   "apiVersion": "2017-05-10",
   "name": "LinkedTemplate",
   "type": "Microsoft.Resources/deployments",
   "properties": {
     "mode": "Incremental",
     "templateLink": {
        "uri":"[parameters('virtualNetworkTemplateUrl')]"
     },
     "parameters": {
      "uri":"[parameters('parametersUrl')]"
      }
   }
},
{
  "apiVersion": "2017-05-10",
  "name": "LinkedTemplate",
  "type": "Microsoft.Resources/deployments",
  "properties": {
    "mode": "Incremental",
    "templateLink": {
       "uri":"[parameters('subnetTemplateUrl')]"
    },
    "parameters": {
      "uri":"[parameters('parametersUrl')]"
     },
     "dependsOn": [
      "LinkedTemplate",
      "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
     ]
    }
},
],

"outputs": {
    "returnedVnetName": {
        "type": "string",
        "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
    },
    "returnedVnetAddressPrefix": {
        "type": "string",
        "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetAddressPrefix'))]"
    }
  }
}

The question here is is it not possible to have one master template and have multiple linked templates? I am aware of having one giant template with everything written in it but we dont want it.

Upvotes: 1

Views: 2775

Answers (2)

Stringfellow
Stringfellow

Reputation: 2908

Here is my version of the ARM template that works. The template name values definitely need to be different during simultaneous deployment. As shown in the deployments record, there are three deployments created by the one master template.

I made three noted changes plus others to handle the URIs. See diff output at bottom.

enter image description here

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vnetName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Virtual Network"
      }
    },
    "vnetAddressPrefix": {
      "type": "string",
      "metadata": {
        "description": "The IP Address pool for the virtual network in CIDR format."
      }
    },
    "subnetPrefix": {
      "type": "string",
      "metadata": {
        "description": "The IP Address pool for the Subnet in CIDR format."
      }
    },
    "subnetName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Subnet"
      }
    }
  },
  "variables": {
    "templateBaseUrl": "[deployment().properties.templateLink.uri]",
    "virtualNetworkTemplateUrl": "[uri(variables('templateBaseUrl'), 'VirtualNetwork.json')]",
    "subnetTemplateUrl": "[uri(variables('templateBaseUrl'), 'Subnet.json')]",
    "parametersUrl": "[uri(variables('templateBaseUrl'), 'networksubnetnsgtest.parameters.json')]"
  },
  "resources": [
    {
      "apiVersion": "2017-05-10",
      "name": "VnetDeployment",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[variables('virtualNetworkTemplateUrl')]"
        },
        "parameters": {
          "uri": {
            "value": "[variables('parametersUrl')]"
          }
        }
      }
    },
    {
      "apiVersion": "2017-05-10",
      "name": "SubnetDeployment",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[variables('subnetTemplateUrl')]"
        },
        "parameters": {
          "uri": {
            "value": "[variables('parametersUrl')]"
          }
        }
      },
      "dependsOn": [
        "VnetDeployment"
      ]
    }
  ],
  "outputs": {
    "returnedVnetName": {
      "type": "string",
      "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
    },
    "returnedVnetAddressPrefix": {
      "type": "string",
      "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetAddressPrefix'))]"
    }
  }
}

Diff Output enter image description here

Parts of the PowerShell used to execute:

$templateUri = 'https://<storageAccountName>.blob.core.windows.net/<containerName>/Lab/Master-Fixed.json'
$parameters = @{ 'vnetName' = 'myvnet'; 'vnetAddressPrefix' = '10.0.0.0/16'; 'subnetPrefix' = '10.0.0.0/24'; 'subnetName' = 'mysubnet'; }
New-AzureRmResourceGroupDeployment -Name "brstring-20190124" -ResourceGroupName $resourceGroupName -TemplateUri $templateUri @parameters

Upvotes: 2

4c74356b41
4c74356b41

Reputation: 72151

names of the deployments have to be different (because it wouldnt be able to tell one from another if they are the same). so just call them something like template1, template2, template3. or by the function - what they do. like deployVnet, deployVm, etc.

Upvotes: 0

Related Questions