I have a problem I can't find a solution for, it's when I try to use copy to create multiple parts dynamically in my dashboard ARM template.
I get the error when I try to use "[copyIndex()]" in one of the keys, as I understand from the error message this will not work. But I'm not sure how I can get around the issue, so any ideas would be appreciated.
"copy": [
{
"name": "servers",
"count": "[length(parameters('locationKeys'))]",
"input": {
"[copyIndex('servers')]": {
"position": {
"x": "[mul(copyIndex('servers'), 4)]",
"y": 1,
"colSpan": 2,
"rowSpan": 1
}
}
}
}
]
As you can see in the example above this is what fails
"[copyIndex('servers')]": {
And I get this error
Error: Code=InvalidTemplate; Message=Deployment template validation failed:
'Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.'.
The structure to create the dashboard looks like this
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": {
"0": {},
"1": {},
...
And I have the copy function under the "parts" key.
The way around this would be to remove the copy function and duplicate the code, but then I have a hard time to get it to work with any given number of "locations" since I need to hard code them.
Basically this is what I want to get in the end.
Are there any other good solutions to get around this problem?
UPDATE
These are the two templates I reference from my Azure DevOps task in the pipeline. Note that I now need to do parameters('locationKeys')[0] and duplicate all the blocks instead of doing a copy with parameters('locationKeys')[copyIndex()].
parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"locationNames": {
"value": "#{locationNames}"
}
}
}
deploy.json
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"defaultValue" : "myApp"
},
"locationNames": {
"type": "array"
}
},
"variables": {
"dashboardName": "[concat(parameters('appName'), '-dashboard')]"
},
"resources": [
{
"name": "[variables('dashboardName')]",
"type": "Microsoft.Portal/dashboards",
"apiVersion": "2015-08-01-preview",
"location": "westeurope",
"tags": {
"hidden-title": "24/7 Operations"
},
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": {
"0": {
"position": {
"x": 0,
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[0])]",
"title": "",
"subtitle": ""
}
}
}
}
},
"1": {
"position": {
"x": 4,
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[1])]",
"title": "",
"subtitle": ""
}
}
}
}
},
"2": {
"position": {
"x": 8,
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[2])]",
"title": "",
"subtitle": ""
}
}
}
}
}
}
}
}
},
"dependsOn": []
}
],
"outputs": {
"resourceGroupId": {
"type": "string",
"value": "[resourceGroup().id]"
}
}
}
UPDATE 2
This is the working example with objects instead of an array. I verified it locally with PowerShell by uploading the collector.json and transform.json to http://myjson.com and include them as properties when running the deploy.
parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"azureEnvironment": {
"value": "#{azureEnvironment}"
},
"locationKeys": {
"value": "#{locationKeys}"
},
"locationNames": {
"value": "#{locationNames}"
},
"transformTemplateLink": {
"value": "#{transform}"
},
"collectorTemplateLink": {
"value": "#{collector}"
}
}
}
deploy.json
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"defaultValue": "myApp"
},
"azureEnvironment": {
"type": "string"
},
"locationKeys": {
"type": "array"
},
"locationNames": {
"type": "array"
},
"transformTemplateLink": {
"type": "string",
"defaultValue": "[uri(deployment().properties.templateLink.uri, 'transform.json')]"
},
"collectorTemplateLink": {
"type": "string",
"defaultValue": "[uri(deployment().properties.templateLink.uri, 'collector.json')]"
}
},
"resources": [
{
"apiVersion": "2015-01-01",
"name": "collector",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[parameters('collectorTemplateLink')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"transformTemplateUri": {
"value": "[parameters('transformTemplateLink')]"
},
"locationNames": {
"value": "[parameters('locationNames')]"
}
}
}
},
{
"name": "[concat(parameters('appName'), '-dash-', parameters('azureEnvironment'))]",
"type": "Microsoft.Portal/dashboards",
"apiVersion": "2015-08-01-preview",
"location": "westeurope",
"tags": {
"hidden-title": "[concat('24/7 Operations - (', parameters('azureEnvironment'), ')')]"
},
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": "[reference('collector').outputs.result.value]"
}
}
},
"dependsOn": [
"collector"
]
}
],
"outputs": {
"resourceGroupId": {
"type": "string",
"value": "[resourceGroup().id]"
}
}
}
collector.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"transformTemplateUri": {
"type": "string"
},
"locationNames": {
"type": "array"
}
},
"variables": {
"count": "[length(parameters('locationNames'))]"
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"name": "loop-0",
"properties": {
"mode": "Incremental",
"parameters": {},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [],
"outputs": {
"collection": {
"type": "object",
"value": {}
}
}
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"name": "[concat('loop-', copyIndex(1))]",
"copy": {
"name": "iterator",
"count": "[variables('count')]",
"mode": "serial"
},
"dependsOn": [
"[concat('loop-', copyIndex())]"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[parameters('transformTemplateUri')]"
},
"parameters": {
"state": {
"value": "[reference(concat('loop-', copyIndex())).outputs.collection.value]"
},
"index": {
"value": "[copyIndex()]"
},
"locationNames": {
"value": "[parameters('locationNames')]"
}
}
}
}
],
"outputs": {
"result": {
"type": "object",
"value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
}
}
}
transform.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"state": {
"type": "object",
"defaultValue": {}
},
"index": {
"type": "int"
},
"locationNames": {
"type": "array"
}
},
"variables": {
"instance": {
"[string(parameters('index'))]": {
"position": {
"x": "[mul(parameters('index'), 4)]",
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[parameters('index')])]",
"title": "",
"subtitle": ""
}
}
}
}
}
}
},
"resources": [],
"outputs": {
"collection": {
"type": "object",
"value": "[union(parameters('state'), variables('instance'))]"
}
}
}