I am looking to create an ARM template code to be able to deploy several VMs with different names using copy and copyindex. To achieve this, I turned to this Microsoft procedure:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageNames": {
"type": "array",
"defaultValue": [
"contoso",
"fabrikam",
"coho"
]
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[concat(parameters('storageNames')[copyIndex()], uniqueString(resourceGroup().id))]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"properties": {},
"copy": {
"name": "storagecopy",
"count": "[length(parameters('storageNames'))]"
}
}
],
"outputs": {}
}
But I have problem when I use array with concat and variables too. it gives me several errors. Can you help me make this code? I would like to use the minimum parameter.
here are my 2 different templates:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"VMNames": {
"type": "array"
},
"Location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_B2s"
}
},
"functions": [],
"variables": {
"VnetName": "[concat(resourceGroup().name, '-vnet1')]"
},
"resources": [
{
"name": "[concat(parameters('VMNames')[copyIndex()].name, '-pip01')]",
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"tags": {
"displayName": "PublicIPAddress"
},
"properties": {
"publicIPAllocationMethod": "Dynamic",
"dnsSettings": {
"domainNameLabel": "[toLower(parameters('VMNames')[copyIndex()].name)]"
}
}
},
{
"name": "[concat(parameters('VMNames')[copyIndex()].name, '-nsg01')]",
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"properties": {
"securityRules": [
{
"name": "nsgRule1",
"properties": {
"description": "description",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Inbound"
}
}
]
}
},
{
"name": "[variables('VnetName')]",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkSecurityGroups/', parameters('VMNames')[copyIndex()].name, '-nsg01')]"
],
"tags": {
"displayName": "[parameters('VMNames')[copyIndex()].name]"
},
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "[ concat(parameters('VMNames')[copyIndex()].name, '-subnet')]",
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('VMNames')[copyIndex()].name, '-nsg01')]"
}
}
}
]
}
},
{
"name": "[concat(parameters('VMNames')[copyIndex()].name, '-nic01')]",
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/', concat(parameters('VMNames')[copyIndex()].name, '-pip01'))]",
"[concat('Microsoft.Network/virtualNetworks/', variables('VnetName'))]"
],
"tags": {
"displayName": "[parameters('VMNames')[copyIndex()].name]"
},
"properties": {
"ipConfigurations": [
{
"name": "ipConfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(parameters('VMNames')[copyIndex()].name, '-pip01'))]"
},
"subnet": {
"id": "[resourceId( 'Microsoft.Network/virtualNetworks/subnets',variables('VnetName'), concat(parameters('VMNames')[copyIndex()].name, '-subnet'))]"
}
}
}
]
}
},
{
"name": "[parameters('VMNames')[copyIndex()].name]",
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"location": "[parameters('Location')]",
"copy": {
"name": "vmcopy",
"count": "[length(parameters('VMNames'))]",
"mode": "Serial"
},
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', concat(parameters('VMNames')[copyIndex()].name, '-nic01'))]"
],
"tags": {
"displayName": "[parameters('VMNames')[copyIndex()].name]"
},
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('VMNames')[copyIndex()].size]"
},
"osProfile": {
"computerName": "[parameters('VMNames')[copyIndex()].name]",
"adminUsername": "cprin",
"adminPassword": "Vivendi$1234"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2012-R2-Datacenter",
"version": "latest"
},
"osDisk": {
"name": "[ concat(parameters('VMNames')[copyIndex()].name, '-OsDisk01')]",
"caching": "ReadWrite",
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('VMNames')[copyIndex()].name, '-nic01'))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true
}
}
}
}
],
"outputs": {}
}
the 2nd different:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"VMNames": {
"type": "array"
},
"Location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_B2s"
}
},
"functions": [],
"variables": {
"NSGName": "[concat(parameters('VMNames')[copyIndex()], '-nsg01')]",
"NicName": "[concat(parameters('VMNames')[copyIndex()], '-nic01')]",
"VnetName": "[concat(resourceGroup().name[copyIndex()], '-vnet1')]",
"publicNicName": "[concat(parameters('VMNames')[copyIndex()], '-pip01')]",
"OsDiskName": "[concat(parameters('VMNames')[copyIndex()], '-OsDisk01')]",
"subnetName": "[concat(parameters('VMNames')[copyIndex()], '-subnet')]"
},
"resources": [
{
"name": "[variables('publicNicName')]",
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"tags": {
"displayName": "PublicIPAddress"
},
"properties": {
"publicIPAllocationMethod": "Dynamic",
"dnsSettings": {
"domainNameLabel": "[toLower(parameters('VMNames')[copyIndex()])]"
}
}
},
{
"name": "[variables('NSGName')]",
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"properties": {
"securityRules": [
{
"name": "nsgRule1",
"properties": {
"description": "description",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Inbound"
}
}
]
}
},
{
"name": "[variables('VnetName')]",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkSecurityGroups/', variables('NSGName'))]"
],
"tags": {
"displayName": "[parameters('VMNames')[copyIndex()]]"
},
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('NSGName'))]"
}
}
}
]
}
},
{
"name": "[variables('NicName')]",
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/', variables('publicNicName'))]",
"[concat('Microsoft.Network/virtualNetworks/', variables('VnetName'))]"
],
"tags": {
"displayName": "[parameters('VMNames')[copyIndex()]]"
},
"properties": {
"ipConfigurations": [
{
"name": "ipConfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicNicName'))]"
},
"subnet": {
"id": "[resourceId( 'Microsoft.Network/virtualNetworks/subnets',variables('VnetName'), variables('subnetName'))]"
}
}
}
]
}
},
{
"name": "[parameters('VMNames')[copyIndex()]]",
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"location": "[parameters('Location')]",
"copy": {
"name": "vmcopy",
"count": "[length(parameters('VMNames'))]",
"mode": "Serial"
},
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', variables('NicName'))]"
],
"tags": {
"displayName": "[parameters('VMNames')[copyIndex()]]"
},
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"osProfile": {
"computerName": "[parameters('VMNames')[copyIndex()]]",
"adminUsername": "cprin",
"adminPassword": "Vivendi$1234"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2012-R2-Datacenter",
"version": "latest"
},
"osDisk": {
"name": "[variables('OsDiskName')]",
"caching": "ReadWrite",
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('NicName'))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true
}
}
}
}
],
"outputs": {}
}
and here is my parameter file for my 1st code:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"VMNames": {
"value": [
{
"name": "vmfakri",
"size": "Standard_B2s"
},
{
"name": "vmrazane",
"size": "Standard_B2s"
},
{
"name": "vmseif",
"size": "Standard_B2s"
}
]
}
}
}
and here is my parameter file for my 2nd code:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"VMNames": {
"value": [
"vmfakri",
"vmrazane",
"vmseif"
]
}
}
}
Here are the errors encountered:
InvalidTemplate - Deployment template validation failed: 'The template variable 'NSGName' is not valid: The template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy
specified. Please see https://aka.ms/arm-copy for usage details.. Please see https://aka.ms/arm-template-expressions for usage details.'.
InvalidTemplate - Deployment template validation failed: 'The template resource '[concat(parameters('VMNames'), '-pip01')]' at line '24' and column '9' is not valid: The provided parameters for language function 'concat' are
invalid. Either all or none of the parameters must be an array. Please see https://aka.ms/arm-template-expressions/#concat for usage details.. Please see https://aka.ms/arm-template-expressions for usage details.'.
CodePudding user response:
It seem that you might be missing iteration property in resource deployment: add "copy" property.
{
"name": "[concat(parameters('VMNames')[copyIndex()].name, '-nsg01')]",
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-11-01",
"location": "[parameters('Location')]",
"properties": {
"securityRules": [
{
"name": "nsgRule1",
"properties": {
"description": "description",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Inbound"
}
}
]
},
"copy": {
"name": "VMcopy",
"count": "[length(parameters('VMNames'))]"
}
}
In this case you don't need to iterate in variable
CodePudding user response:
Thank you for your answer Greg, I just did what you told me but there is still an error: