In an attempt to make life easier (in the long run), I'm trying to use properties.template, as opposed to the well documented properties.templateLink. The former has very little documentation by passing the contents of child.json template file into the parent.json template, as a template' parameter.
From the MS documentation for Microsoft.Resources/deployments:
The template content. You use this element when you want to pass the template syntax directly in the request rather than link to an existing template. It can be a JObject or well-formed JSON string. Use either the templateLink property or the template property, but not both.
In my parent template, I am declaring the parameter childTemplates
and referencing it in properties.template:
"parameters": {
"childTemplates": {
"type": "object",
"metadata": {
"description": "Child template"
}
}
}
other stuff...
"resources": [
{
"name": "[concat('linkedTemplate-VM-Net-',copyIndex(1))]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-06-01",
"dependsOn": [],
"copy": {
"name": "interate",
"count": "[parameters('vmQty')]"
},
"properties": {
"mode": "Incremental",
"template": "[parameters('childTemplates')]",
"parameters": {
"sharedVariables": { "value": "[variables('sharedVariables')]" },
"sharedTemplate": { "value": "[variables('sharedTemplate')]" },
"artifactsLocationSasToken": { "value": "[parameters('artifactsLocationSasToken')]" },
"adminPassword": { "value": "[parameters('adminPassword')]" },
"copyIndexValue": { "value": "[copyIndex(1)]" }
},
"debugSetting": {
"detailLevel": "both"
}
}
}
],
I then pass the child template to New-AzureRmResourceGroupDeployment -TemplateParameterObject
to deploy the parent template:
$TemplateFileLocation = "C:\Temp\templates\parent.json"
$JsonChildTemplate = Get-Content -Raw (Join-Path ($TemplateFileLocation | Split-Path -Parent) "nestedtemplates\child.json") | ConvertFrom-Json
$TemplateParameters = @{
childTemplates = $JsonChildTemplate
...Other parameters...
}
New-AzureRmResourceGroupDeployment -TemplateParameterObject $TemplateParameters
This produces the following error:
Code : InvalidTemplate
Message : The nested deployment 'linkedTemplate-VM-Net-1' failed validation: 'Required property '$schema' not found in JSON. Path 'properties.template'.'.
Target :
Details :
If I look at $JsonChildTemplate
, it gives me:
$schema : https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#
contentVersion : 1.0.0.0
parameters : @{sharedVariables=; sharedTemplate=; vhdStorageAccountName=; artifactsLocationSasToken=; adminPassword=; copyIndexValue=}
variables : @{seqNo=[padleft(add(parameters('copyIndexValue'),3),3,'0')]; nicName=[concat('NIC-',parameters('sharedVariables').role,'-', variables('seqNo'),'-01')];
subnetRef=[parameters('sharedVariables').network.subnetRef]; ipConfigName=[concat('ipconfig-', variables('seqNo'))]}
resources : {@{apiVersion=2016-03-30; type=Microsoft.Network/networkInterfaces; name=[variables('nicName')]; location=[resourceGroup().location]; tags=; dependsOn=System.Object[];
properties=}}
outputs : @{nicObject=; vmPrivateIp=; vmNameSuffix=; vmPrivateIpArray=}
To me, it looks like the $schema
is there.
I have also tried removing | ConvertFrom-Json
with the same error.
Above, I am showing the latest API version, but I have tried with others such as 2016-09-01, just in case there's a bug.
In my search for a solution, I found this issue on GitHub. The recomendation is to remove $schema
and contentVersion
, although this flies in the face of the error. I tried this with the following:
Function Get-ChildTemplate
{
$TemplateFileLocation = "C:\Temp\templates\nestedtemplates\child.json"
$json = Get-Content -Raw -Path $TemplateFileLocation | ConvertFrom-Json
$NewJson = @()
$NewJson += $json.parameters
$NewJson += $json.variables
$NewJson += $json.resources
$NewJson += $json.outputs
Return $NewJson | ConvertTo-Json
}
$JsonChildTemplate = Get-ChildTemplate
$TemplateParameters = @{
childTemplates = $JsonChildTemplate
...Other parameters...
}
$JsonChildTemplate
returns:
[
{
"sharedVariables": {
"type": "object",
"metadata": "@{description=Object of variables from master template}"
}...
My guess is that I have done something wrong passing child.json's contents to New-AzureRmResourceGroupDeployment
. That or it's not actually possible to do what I'm trying to do.
P.S.
get-command New-AzureRmResourceGroupDeployment
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet New-AzureRmResourceGroupDeployment 4.1.0 AzureRM.Resources
First of all, what you are doing makes 0 sense what so ever, that being said, lets try to help you.
New-AzureRmResourceGroupDeployment ... @TemplateParameters
instead of what you are doing. (no idea, but somehow it works better in my experience)-Debug
switch and see where that goes.smarthacky enough. I have no idea what you are trying to achieve but I can bet my life on it you don't need that monstrosity you are trying to createsmall template example:
EDIT: I dug a bit more and found a solution. one way to do it would be using the
json()
function of the arm template that accepts a string and converts to valid json.To deploy use something like this:
This is a bit of a hack, but the problem lies with how powershell converts your input to what it passes to the template, and you cannot really control that.
Another way to do that: (if you need output you can add another parameter)
and deploying like so:
ps. don't mind walter, each time he says something can't be done or is impossible it actually is possible.