Arm template if condition - azure

I am trying to implement if condition for the arm template. Idea is from the parameter to read if it suppose to deploy in prod or nonprod sub and have the subnets predefined. Then deploy storage and add some subnets to the storage account virtual network list.
The following line causing troubles:
"virtualNetworkRules": "[if(equals(parameters('Sub'), 'nonprod'),'variables('nonprodvirtualNetworkSubnets').virtualNetworkRulesCopy', 'variables('prodvirtualNetworkSubnets').virtualNetworkRulesCopy', )]",
All help is much appreciated.
"Parameters": {
"Sub": {
"type": "string",
"defaultValue": "nonprod",
"metadata": {
"description": "Prod or nonprod sub"
}
}
},
"variables": {
"subscriptionId": "[subscription().subscriptionId]",
"resourcegroupName": "[toUpper(concat(parameters('splitSubscriptionName')[0], '-', parameters('splitSubscriptionName')[1], '-', parameters('splitSubscriptionName')[2], '-02-NET-RSG'))]",
"virtualNetworkname": "[toLower(concat(parameters('splitSubscriptionName')[0], '-', parameters('splitSubscriptionName')[1], '-', parameters('splitSubscriptionName')[2], '-02-NET-', parameters('splitSubscriptionName')[3], '-00-net'))]",
"storageAccountType": "Standard_LRS", // "allowedValues": ["Standard_LRS", "Standard_GRS", "Standard_ZRS", "Premium_LRS"]
"blobServicesName": "default",
"VirtualNetworkExternalId": "[concat('/subscriptions/', variables('subscriptionId'), '/resourceGroups/', variables('resourcegroupName'), '/providers/Microsoft.Network/virtualNetworks/', variables('virtualNetworkname'), '/subnets/')]",
"nonprodAllowedSubnets": [
"mngm00-devtest-sub",
"mngm01-devtest-sub",
"mngm02-devtest-sub"
],
"prodAllowedSubnets": [
"mngm00-prod-sub",
"mngm01-prod-sub"
],
"nonprodvirtualNetworkSubnets": {
"copy": [
{
"name": "virtualNetworkRulesCopy",
"count": "[length(variables('nonprodAllowedSubnets'))]",
"input": {
"id": "[concat(variables('VirtualNetworkExternalId'), variables('nonprodAllowedSubnets')[copyIndex('virtualNetworkRulesCopy')])]",
"action": "Allow",
"state": "Succeeded"
}
}
]
},
"prodvirtualNetworkSubnets": {
"copy": [
{
"name": "virtualNetworkRulesCopy",
"count": "[length(variables('prodAllowedSubnets'))]",
"input": {
"id": "[concat(variables('VirtualNetworkExternalId'), variables('prodAllowedSubnets')[copyIndex('virtualNetworkRulesCopy')])]",
"action": "Allow",
"state": "Succeeded"
}
}
]
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[parameters('storageAccountName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "[variables('storageAccountType')]"
},
"kind": "[parameters('storageAccountKind')]",
"properties": {
"accessTier": "[parameters('accessTier')]",
"supportsHttpsTrafficOnly": true,
"allowBlobPublicAccess": false,
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": "[if(equals(parameters('Sub'), 'nonprod'),'variables('nonprodvirtualNetworkSubnets').virtualNetworkRulesCopy', 'variables('prodvirtualNetworkSubnets').virtualNetworkRulesCopy', )]",
"defaultAction": "Deny"
},
"encryption": {
"services": {
"file": {
"enabled": true
},
"blob": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
}
}
}
]
}

it should be like this:
[if(equals(parameters('Sub'), 'nonprod'), variables('nonprodvirtualNetworkSubnets').virtualNetworkRulesCopy, variables('prodvirtualNetworkSubnets').virtualNetworkRulesCopy]
so drop ' from your if

Related

Azure DevOps ARM Template adminPassword Windows VM

I am setting up my first ARM template to create a simple windows Virtiual Machine via Azure DevOps.
I have the template file and parameters file and have set a pipeline variable to avoid the complexities of an Azure KeyVault as the first step.
I have setup a pipeline variable Password and locked it.
The Virtual Machine gets setup in my Azure Account no problem but I cannot log in to it. It will not accept the credentials I am passing in. If I reset the password using portal.azure.com all is well. Something is not right about what I am doing in passing my ARM template the adminPassword.
template:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"networkInterfaceName": {
"type": "string"
},
"networkSecurityGroupName": {
"type": "string"
},
"networkSecurityGroupRules": {
"type": "array"
},
"subnetName": {
"type": "string"
},
"virtualNetworkName": {
"type": "string"
},
"addressPrefixes": {
"type": "array"
},
"subnets": {
"type": "array"
},
"publicIpAddressName": {
"type": "string"
},
"publicIpAddressType": {
"type": "string"
},
"publicIpAddressSku": {
"type": "string"
},
"virtualMachineName": {
"type": "string"
},
"virtualMachineComputerName": {
"type": "string"
},
"virtualMachineRG": {
"type": "string"
},
"osDiskType": {
"type": "string"
},
"dataDisks": {
"type": "array"
},
"dataDiskResources": {
"type": "array"
},
"virtualMachineSize": {
"type": "string"
},
"adminUsername": {
"type": "string"
},
"adminPassword": {
"type": "secureString"
},
"patchMode": {
"type": "string"
}
},
"variables": {
"nsgId": "[resourceId(resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]",
"vnetId": "[resourceId(resourceGroup().name,'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetId'), '/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"name": "[parameters('networkInterfaceName')]",
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2018-10-01",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkSecurityGroups/', parameters('networkSecurityGroupName'))]",
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"[concat('Microsoft.Network/publicIpAddresses/', parameters('publicIpAddressName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"privateIPAllocationMethod": "Dynamic",
"publicIpAddress": {
"id": "[resourceId(resourceGroup().name, 'Microsoft.Network/publicIpAddresses', parameters('publicIpAddressName'))]"
}
}
}
],
"networkSecurityGroup": {
"id": "[variables('nsgId')]"
}
}
},
{
"name": "[parameters('networkSecurityGroupName')]",
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2019-02-01",
"location": "[parameters('location')]",
"properties": {
"securityRules": "[parameters('networkSecurityGroupRules')]"
}
},
{
"name": "[parameters('virtualNetworkName')]",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-09-01",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": "[parameters('addressPrefixes')]"
},
"subnets": "[parameters('subnets')]"
}
},
{
"name": "[parameters('publicIpAddressName')]",
"type": "Microsoft.Network/publicIpAddresses",
"apiVersion": "2019-02-01",
"location": "[parameters('location')]",
"properties": {
"publicIpAllocationMethod": "[parameters('publicIpAddressType')]"
},
"sku": {
"name": "[parameters('publicIpAddressSku')]"
}
},
{
"name": "[parameters('dataDiskResources')[copyIndex()].name]",
"type": "Microsoft.Compute/disks",
"apiVersion": "2020-09-30",
"location": "[parameters('location')]",
"properties": "[parameters('dataDiskResources')[copyIndex()].properties]",
"sku": {
"name": "[parameters('dataDiskResources')[copyIndex()].sku]"
},
"copy": {
"name": "managedDiskResources",
"count": "[length(parameters('dataDiskResources'))]"
}
},
{
"name": "[parameters('virtualMachineName')]",
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2020-12-01",
"location": "[parameters('location')]",
"dependsOn": [
"managedDiskResources",
"[concat('Microsoft.Network/networkInterfaces/', parameters('networkInterfaceName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('virtualMachineSize')]"
},
"storageProfile": {
"osDisk": {
"createOption": "fromImage",
"managedDisk": {
"storageAccountType": "[parameters('osDiskType')]"
}
},
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2016-Datacenter",
"version": "latest"
},
"copy": [
{
"name": "dataDisks",
"count": "[length(parameters('dataDisks'))]",
"input": {
"lun": "[parameters('dataDisks')[copyIndex('dataDisks')].lun]",
"createOption": "[parameters('dataDisks')[copyIndex('dataDisks')].createOption]",
"caching": "[parameters('dataDisks')[copyIndex('dataDisks')].caching]",
"diskSizeGB": "[parameters('dataDisks')[copyIndex('dataDisks')].diskSizeGB]",
"managedDisk": {
"id": "[coalesce(parameters('dataDisks')[copyIndex('dataDisks')].id, if(equals(parameters('dataDisks')[copyIndex('dataDisks')].name, json('null')), json('null'), resourceId('Microsoft.Compute/disks', parameters('dataDisks')[copyIndex('dataDisks')].name)))]",
"storageAccountType": "[parameters('dataDisks')[copyIndex('dataDisks')].storageAccountType]"
},
"writeAcceleratorEnabled": "[parameters('dataDisks')[copyIndex('dataDisks')].writeAcceleratorEnabled]"
}
}
]
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]"
}
]
},
"osProfile": {
"computerName": "[parameters('virtualMachineComputerName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]",
"windowsConfiguration": {
"enableAutomaticUpdates": true,
"provisionVmAgent": true,
"patchSettings": {
"patchMode": "[parameters('patchMode')]"
}
}
},
"priority": "Spot",
"evictionPolicy": "Deallocate",
"billingProfile": {
"maxPrice": 0.08
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true
}
}
}
}
],
"outputs": {
"adminUsername": {
"type": "string",
"value": "[parameters('adminUsername')]"
}
}
}
parameters.json:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "uksouth"
},
"networkInterfaceName": {
"value": "machine1587"
},
"networkSecurityGroupName": {
"value": "Machine1-nsg"
},
"networkSecurityGroupRules": {
"value": [
{
"name": "RDP",
"properties": {
"priority": 300,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "3389"
}
}
]
},
"subnetName": {
"value": "default"
},
"virtualNetworkName": {
"value": "AzureTest-vnet"
},
"addressPrefixes": {
"value": [
"10.0.0.0/24"
]
},
"subnets": {
"value": [
{
"name": "default",
"properties": {
"addressPrefix": "10.0.0.0/24"
}
}
]
},
"publicIpAddressName": {
"value": "Machine1-ip"
},
"publicIpAddressType": {
"value": "Dynamic"
},
"publicIpAddressSku": {
"value": "Basic"
},
"virtualMachineName": {
"value": "Machine1"
},
"virtualMachineComputerName": {
"value": "Machine1"
},
"virtualMachineRG": {
"value": "AzureTest"
},
"osDiskType": {
"value": "Standard_LRS"
},
"dataDisks": {
"value": [
{
"lun": 0,
"createOption": "attach",
"caching": "ReadOnly",
"writeAcceleratorEnabled": false,
"id": null,
"name": "Machine1_DataDisk_0",
"storageAccountType": null,
"diskSizeGB": null,
"diskEncryptionSet": null
}
]
},
"dataDiskResources": {
"value": [
{
"name": "Machine1_DataDisk_0",
"sku": "Standard_LRS",
"properties": {
"diskSizeGB": 64,
"creationData": {
"createOption": "empty"
}
}
}
]
},
"virtualMachineSize": {
"value": "Standard_DS1_v2"
},
"adminUsername": {
"value": "LocalAdminUserName"
},
"adminPassword": {
"value": null
},
"patchMode": {
"value": "AutomaticByOS"
}
}
}
steps:
- task: AzureResourceManagerTemplateDeployment#3
displayName: 'ARM Template deployment: Resource Group scope'
inputs:
azureResourceManagerConnection: 'Pay-As-You-Go (xxxxxxxxxxxxxxx)'
subscriptionId: 'xxxxxxxxxxxxxxx'
resourceGroupName: AzureTest
location: 'UK South'
csmFile: '$(System.DefaultWorkingDirectory)/_Azure/First Virtual Machine/template.json'
csmParametersFile: '$(System.DefaultWorkingDirectory)/_Azure/First Virtual Machine/parameters.json'
overrideParameters: '-adminPassword "$(Password)"'
That all looks fine on the surface, but your template schema is no longer on the supported schemas list for virtualMachines at Resource Types. I'm wondering if you might get traction with a later template version?

Azure VM Scale Set CustomScriptExtension Failing

I'm trying to create a windows Azure VM Scale Set that auto provisions a formatted attached data disk using the MS guide here: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-attached-disks
No matter what I do I see to get this error:
9:14:16 PM - The deployment 'testvmss' failed with error(s). Showing
1 out of 1 error(s). Status
| Message: VM has reported a failure when processing extension 'customScript'. Error message: "Invalid
| Configuration - CommandToExecute is not specified in the configuration; it must be specified in either
| the protected or public configuration section" More information on troubleshooting is available at
| https://aka.ms/VMExtensionCSEWindowsTroubleshoot (Code:VMExtensionProvisioningError) CorrelationId:
| 3294f49a-23f0-4634-aba0-3bb0e814659e
I've tried:
moving the "commandToExecute" into the protected config area
"typeHandlerVersion" numbers
moving commandToExecute outside of the "settings" section
using case corrected "CommandToExecute"
Simplifying the powershell statement to "powershell echo test"
Searching google for the error message, better/different examples, etc.
Here is the specific section of the ARM:
"extensionProfile": {
"extensions": [
{
"name": "customScript",
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.8",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": ["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/prepare_vm_disks.ps1"],
"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File prepare_vm_disks.ps1"
}
}
}
]
}
And for reference, here is the full ARM:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"virtualMachineScaleSetName": {
"type": "string"
},
"virtualMachineScaleSetRG": {
"type": "string"
},
"singlePlacementGroup": {
"type": "string"
},
"instanceSize": {
"type": "string"
},
"instanceCount": {
"type": "string"
},
"upgradeMode": {
"type": "string"
},
"priority": {
"type": "string"
},
"enableAcceleratedNetworking": {
"type": "string"
},
"subnetId": {
"type": "string"
},
"osDiskType": {
"type": "string"
},
"dataDisks": {
"type": "array"
},
"addressPrefixes": {
"type": "array"
},
"subnets": {
"type": "array"
},
"virtualNetworkId": {
"type": "string"
},
"virtualNetworkName": {
"type": "string"
},
"networkSecurityGroups": {
"type": "array"
},
"networkInterfaceConfigurations": {
"type": "array"
},
"vmName": {
"type": "string"
},
"scaleInPolicy": {
"type": "object"
},
"overprovision": {
"type": "bool"
},
"upgradePolicy": {
"type": "string"
},
"adminUsername": {
"type": "string"
},
"adminPassword": {
"type": "secureString"
},
"platformFaultDomainCount": {
"type": "string"
}
},
"variables": {
"storageApiVersion": "2019-04-01",
"namingInfix": "[toLower(substring(concat(parameters('virtualMachineScaleSetName'), uniqueString(resourceGroup().id)), 0, 9))]"
},
"resources": [
{
"name": "[parameters('virtualNetworkName')]",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-09-01",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": "[parameters('addressPrefixes')]"
},
"subnets": "[parameters('subnets')]"
}
},
{
"name": "[parameters('networkSecurityGroups')[copyIndex()].name]",
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2019-02-01",
"location": "[parameters('location')]",
"properties": {
"securityRules": "[parameters('networkSecurityGroups')[copyIndex()].rules]"
},
"copy": {
"name": "networkSecurityGroups",
"count": "[length(parameters('networkSecurityGroups'))]"
}
},
{
"name": "[parameters('virtualMachineScaleSetName')]",
"type": "Microsoft.Compute/virtualMachineScaleSets",
"apiVersion": "2019-12-01",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"networkSecurityGroups",
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"sku": {
"name": "[parameters('instanceSize')]",
"capacity": "[int(parameters('instanceCount'))]"
},
"properties": {
"overprovision": "[parameters('overprovision')]",
"upgradePolicy": {
"mode": "[parameters('upgradePolicy')]"
},
"singlePlacementGroup": "[parameters('singlePlacementGroup')]",
"virtualMachineProfile": {
"storageProfile": {
"osDisk": {
"createOption": "fromImage",
"caching": "ReadWrite",
"managedDisk": {
"storageAccountType": "[parameters('osDiskType')]"
}
},
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2016-Datacenter",
"version": "latest"
},
"copy": [
{
"name": "dataDisks",
"count": "[length(parameters('dataDisks'))]",
"input": {
"lun": "[parameters('dataDisks')[copyIndex('dataDisks')].lun]",
"createOption": "[parameters('dataDisks')[copyIndex('dataDisks')].createOption]",
"caching": "[parameters('dataDisks')[copyIndex('dataDisks')].caching]",
"writeAcceleratorEnabled": "[parameters('dataDisks')[copyIndex('dataDisks')].writeAcceleratorEnabled]",
"diskSizeGB": "[parameters('dataDisks')[copyIndex('dataDisks')].diskSizeGB]",
"managedDisk": {
"storageAccountType": "[parameters('dataDisks')[copyIndex('dataDisks')].storageAccountType]",
"diskEncryptionSet": "[parameters('dataDisks')[copyIndex('dataDisks')].diskEncryptionSet]"
},
"diskIOPSReadWrite": "[if(equals( parameters('dataDisks')[copyIndex('dataDisks')].diskIOPSReadWrite, -1), json('null'),parameters('dataDisks')[copyIndex('dataDisks')].diskIOPSReadWrite)]",
"diskMBpsReadWrite": "[if(equals( parameters('dataDisks')[copyIndex('dataDisks')].diskMBpsReadWrite, -1), json('null'),parameters('dataDisks')[copyIndex('dataDisks')].diskMBpsReadWrite)]"
}
}
]
},
"priority": "[parameters('priority')]",
"networkProfile": {
"copy": [
{
"name": "networkInterfaceConfigurations",
"count": "[length(parameters('networkInterfaceConfigurations'))]",
"input": {
"name": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name]",
"properties": {
"primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]",
"enableAcceleratedNetworking": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].enableAcceleratedNetworking]",
"ipConfigurations": [
{
"name": "[concat(parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name, '-defaultIpConfiguration')]",
"properties": {
"subnet": {
"id": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].subnetId]"
},
"primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]",
"applicationGatewayBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].applicationGatewayBackendAddressPools]",
"loadBalancerBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerBackendAddressPools]",
"loadBalancerInboundNatPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerInboundNatPools]",
"publicIPAddressConfiguration": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, ''), json('null'), union(json(concat('{\"name\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, '\"}'))\n ,json('{\"properties\": { \"idleTimeoutInMinutes\": 15}}')))]"
}
}
],
"networkSecurityGroup": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, ''), json('null'),json(concat('{\"id\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, '\"}')))]"
}
}
}
]
},
"extensionProfile": {
"extensions": [
{
"name": "customScript",
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.8",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": ["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/prepare_vm_disks.ps1"],
"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File prepare_vm_disks.ps1"
}
}
}
]
},
"osProfile": {
"computerNamePrefix": "[variables('namingInfix')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]",
"windowsConfiguration": {
"provisionVmAgent": true
}
}
},
"scaleInPolicy": "[parameters('scaleInPolicy')]",
"platformFaultDomainCount": "[parameters('platformFaultDomainCount')]"
}
}
],
"outputs": {
"adminUsername": {
"type": "string",
"value": "[parameters('adminUsername')]"
}
}
}
Any help is greatly appreciated, thanks!
I had the same issue with VMSS Managed Disk and Service Fabric, because there is a problem with the last commit (from last September) - Here you can find an open issue about it.
Until this issue would be solved you can still use the script extension with link to previous version as I did:
https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/fdc643759c9aa7e9259da10575e67dc1368e4e9f/prepare_vm_disks.ps1
Add this script extension to the extensionProfile of the virtualMachineProfile of the scale set:
{
"name": "customScript",
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.8",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [
"https://https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/fdc643759c9aa7e9259da10575e67dc1368e4e9f/prepare_vm_disks.ps1"
],
"commandToExecute": "powershell -ExecutionPolicy Unrestricted -File prepare_vm_disks.ps1"
}
}
}
As the MS guide template, you need to include a dataDisks section in the storageProfile of the Microsoft.Compute/virtualMachineScaleSets resource(s) and deploy the template.
Here is a working template for your references:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vmSku": {
"type": "string",
"defaultValue": "Standard_A1_v2",
"metadata": {
"description": "Size of VMs in the VM Scale Set."
}
},
"windowsOSVersion": {
"type": "string",
"defaultValue": "2016-Datacenter"
},
"vmssName": {
"type": "string",
"minLength": 3,
"maxLength": 61
},
"instanceCount": {
"type": "int",
"defaultValue": 3,
"minValue": 1,
"maxValue": 100,
"metadata": {
"description": "Number of VM instances (100 or less)."
}
},
"singlePlacementGroup": {
"type": "bool",
"defaultValue": true
},
"adminUsername": {
"type": "string",
"defaultValue": "vmssadmin"
},
"adminPassword": {
"type": "securestring"
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"platformFaultDomainCount": {
"type": "int",
"defaultValue": 1
}
},
"variables": {
"namingInfix": "[toLower(substring(concat(parameters('vmssName'), uniqueString(resourceGroup().id)), 0, 9))]",
"longNamingInfix": "[toLower(parameters('vmssName'))]",
"addressPrefix": "10.0.0.0/16",
"subnetPrefix": "10.0.0.0/24",
"virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]",
"publicIPAddressName": "[concat(variables('namingInfix'), 'pip')]",
"subnetName": "[concat(variables('namingInfix'), 'subnet')]",
"loadBalancerName": "[concat(variables('namingInfix'), 'lb')]",
"publicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]",
"lbProbeID": "[resourceId('Microsoft.Network/loadBalancers/probes',variables('loadBalancerName'), 'tcpProbe')]",
"natPoolName": "[concat(variables('namingInfix'), 'natpool')]",
"bePoolName": "[concat(variables('namingInfix'), 'bepool')]",
"lbPoolID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools',variables('loadBalancerName'),variables('bePoolName'))]",
"natStartPort": 50000,
"natEndPort": 50119,
"natBackendPort": 3389,
"nicName": "[concat(variables('namingInfix'), 'nic')]",
"ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]",
"frontEndIPConfigID": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations',variables('loadBalancerName'),'loadBalancerFrontEnd')]",
"osType": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "[parameters('windowsOSVersion')]",
"version": "latest"
},
"imageReference": "[variables('osType')]"
},
"resources": [
{
"type": "Microsoft.Network/loadBalancers",
"apiVersion": "2020-06-01",
"name": "[variables('loadBalancerName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
],
"properties": {
"frontendIPConfigurations": [
{
"name": "LoadBalancerFrontEnd",
"properties": {
"publicIPAddress": {
"id": "[variables('publicIPAddressID')]"
}
}
}
],
"backendAddressPools": [
{
"name": "[variables('bePoolName')]"
}
],
"inboundNatPools": [
{
"name": "[variables('natPoolName')]",
"properties": {
"frontendIPConfiguration": {
"id": "[variables('frontEndIPConfigID')]"
},
"protocol": "Tcp",
"frontendPortRangeStart": "[variables('natStartPort')]",
"frontendPortRangeEnd": "[variables('natEndPort')]",
"backendPort": "[variables('natBackendPort')]"
}
}
],
"loadBalancingRules": [
{
"name": "LBRule",
"properties": {
"frontendIPConfiguration": {
"id": "[variables('frontEndIPConfigID')]"
},
"backendAddressPool": {
"id": "[variables('lbPoolID')]"
},
"protocol": "Tcp",
"frontendPort": 80,
"backendPort": 80,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 5,
"probe": {
"id": "[variables('lbProbeID')]"
}
}
}
],
"probes": [
{
"name": "tcpProbe",
"properties": {
"protocol": "Tcp",
"port": 80,
"intervalInSeconds": 5,
"numberOfProbes": 2
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"apiVersion": "2020-06-01",
"name": "[variables('namingInfix')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('vmSku')]",
"tier": "Standard",
"capacity": "[parameters('instanceCount')]"
},
"dependsOn": [
"[resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName'))]",
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
],
"properties": {
"overprovision": true,
"upgradePolicy": {
"mode": "Automatic"
},
"singlePlacementGroup": "[parameters('singlePlacementGroup')]",
"platformFaultDomainCount": "[parameters('platformFaultDomainCount')]",
"virtualMachineProfile": {
"storageProfile": {
"osDisk": {
"caching": "ReadWrite",
"createOption": "FromImage"
},
"dataDisks": [
{
"diskSizeGB": 128,
"lun": 0,
"createOption": "Empty"
}
],
"imageReference": "[variables('imageReference')]"
},
"osProfile": {
"computerNamePrefix": "[variables('namingInfix')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "[variables('nicName')]",
"properties": {
"primary": true,
"ipConfigurations": [
{
"name": "[variables('ipConfigName')]",
"properties": {
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[variables('lbPoolID')]"
}
],
"loadBalancerInboundNatPools": [
{
"id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('loadBalancerName'), variables('natPoolName'))]"
}
]
}
}
]
}
}
]
},
"extensionProfile": {
"extensions": [
{
"name": "customScript",
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.8",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [
"https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/prepare_vm_disks.ps1"
],
"commandToExecute": "powershell -ExecutionPolicy Unrestricted -File prepare_vm_disks.ps1"
}
}
}
]
}
}
}
},
{
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2020-06-01",
"name": "[variables('publicIPAddressName')]",
"location": "[parameters('location')]",
"properties": {
"publicIPAllocationMethod": "Static",
"dnsSettings": {
"domainNameLabel": "[variables('longNamingInfix')]"
}
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-06-01",
"name": "[variables('virtualNetworkName')]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('addressPrefix')]"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "[variables('subnetPrefix')]"
}
}
]
}
}
],
"outputs": {}
}
If you want to create multiple data disks with the copy function, you can add it like this
"storageProfile": {
"osDisk": {
"caching": "ReadWrite",
"createOption": "FromImage"
},
"copy": [
{
"name": "dataDisks",
"count": "[parameters('numberOfDataDisks')]",
"input": {
"diskSizeGB": 1023,
"lun": "[copyIndex('dataDisks')]",
"createOption": "Empty"
}
}
],
After my validation, after the above deployment finishs, you need to initialize the disk in each instance, then you could get the expected result.
Reference: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/tutorial-use-disks-powershell#prepare-the-data-disks

Why does setting CosmosDB throughputSettings result in "Entity with the specified id does not exist in the system"?

While trying to deploy a CosmosDB instance with 2 collections ("MyCollection1", "MyCollection2") I keep getting the error:
NotFound: Entity with the specified id does not exist in the system
So I keep searching for "resourceId" in my custom ARM template (please see below) but cannot find the erorr cause.
I don't understand, why does not the pipeline at least print the line number for me?
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"accountName": {
"defaultValue": "my-cosmosdb",
"type": "String"
}
},
"variables": {
"resourceName": "[concat(resourceGroup().name, '-', parameters('accountName'))]",
"resourceId": "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]",
"apiVersion": "[providers('Microsoft.DocumentDB', 'databaseAccounts').apiVersions[0]]"
},
"outputs": {
"CosmosDbConnectionString": {
"type": "string",
"value": "[concat('AccountEndpoint=https://', variables('resourceName'), '.documents.azure.com:443/;AccountKey=', listKeys(variables('resourceId'), variables('apiVersion')).primaryMasterKey, ';')]"
},
"DatabaseName": {
"type": "string",
"value": "MyDB"
},
"CollectionName1": {
"type": "string",
"value": "MyCollection1"
},
"CollectionName2": {
"type": "string",
"value": "MyCollection2"
}
},
"resources": [
{
"type": "Microsoft.DocumentDB/databaseAccounts",
"apiVersion": "2020-03-01",
"name": "[variables('resourceName')]",
"location": "[resourceGroup().location]",
"tags": {
"defaultExperience": "DocumentDB"
},
"kind": "GlobalDocumentDB",
"properties": {
"publicNetworkAccess": "Enabled",
"enableAutomaticFailover": false,
"enableMultipleWriteLocations": false,
"isVirtualNetworkFilterEnabled": false,
"virtualNetworkRules": [],
"disableKeyBasedMetadataWriteAccess": false,
"databaseAccountOfferType": "Standard",
"consistencyPolicy": {
"defaultConsistencyLevel": "Session",
"maxIntervalInSeconds": 5,
"maxStalenessPrefix": 100
},
"locations": [
{
"locationName": "[resourceGroup().location]",
"provisioningState": "Succeeded",
"failoverPriority": 0,
"isZoneRedundant": false
}
],
"capabilities": []
}
},
{
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases",
"apiVersion": "2020-03-01",
"name": "[concat(variables('resourceName'), '/MyDB')]",
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]"
],
"properties": {
"resource": {
"id": "MyDB"
},
"options": {}
}
},
{
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers",
"apiVersion": "2020-03-01",
"name": "[concat(variables('resourceName'), '/MyDB/MyCollection1')]",
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('resourceName'), 'MyDB')]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]"
],
"properties": {
"resource": {
"id": "MyCollection1",
"indexingPolicy": {
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
}
]
},
"partitionKey": {
"paths": [
"/partitionKey"
],
"kind": "Hash"
},
"uniqueKeyPolicy": {
"uniqueKeys": []
},
"conflictResolutionPolicy": {
"mode": "LastWriterWins",
"conflictResolutionPath": "/_ts"
}
},
"options": {}
}
},
{
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers",
"apiVersion": "2020-03-01",
"name": "[concat(variables('resourceName'), '/MyDB/MyCollection2')]",
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('resourceName'), 'MyDB')]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]"
],
"properties": {
"resource": {
"id": "MyCollection2",
"indexingPolicy": {
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
}
]
},
"partitionKey": {
"paths": [
"/partitionKey"
],
"kind": "Hash"
},
"uniqueKeyPolicy": {
"uniqueKeys": []
},
"conflictResolutionPolicy": {
"mode": "LastWriterWins",
"conflictResolutionPath": "/_ts"
}
},
"options": {}
}
},
{
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/throughputSettings",
"apiVersion": "2020-03-01",
"name": "[concat(variables('resourceName'), '/MyDB/default')]",
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('resourceName'), 'MyDB')]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]"
],
"properties": {
"resource": {
"throughput": 400
}
}
}
]
}
UPDATE:
I have removed the part creating collections and the error is still there.
UPDATE 2:
The following part seemingly causes the error, but why?
{
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/throughputSettings",
"apiVersion": "2020-03-01",
"name": "[concat(variables('resourceName'), '/MyDB/default')]",
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('resourceName'), 'MyDB')]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]"
],
"properties": {
"resource": {
"throughput": 400
}
}
}
What is wrong with the dependsOn entry "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('resourceName'), 'MyDB')]?
UPDATE 3:
Trying to deploy the complete ARM template listed above manually results in:
Try setting your throughput in the options for your database.
UPDATE: You cannot specify throughput on a resource that did not have it when initially provisioned. Databases and containers provisioned without throughput cannot be updated later to have it. Conversely, a resource provisioned with throughput, cannot be updated to remove. You must delete and recreate the resource. This will require migrating your data.
{
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases",
"apiVersion": "2020-03-01",
"name": "[concat(variables('resourceName'), '/MyDB')]",
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]"
],
"properties": {
"resource": {
"id": "MyDB"
},
"options": { "throughput": "[parameters('throughput')]" }
}
},
btw, there are lots of samples you can use to start with here Cosmos DB templates
The following has worked for me, I had to replace "sqlDatabases/throughputSettings" by "sqlDatabases/containers/throughputSettings":
{
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/throughputSettings",
"apiVersion": "2020-03-01",
"name": "[concat(variables('resourceName'), '/', variables('DatabaseName'), '/', variables('CollectionName1'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers', variables('resourceName'), variables('databaseName'), variables('CollectionName1'))]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('resourceName'), variables('databaseName'))]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('resourceName'))]"
],
"properties": {
"resource": {
"throughput": 400
}
}
}
And then similar entry for CollectionName2

ARM templates cyclic/circular dependency resolution

I created few resrources through Azure Portal in the following order.
Created a virtual network with two subnets and on one the subnet1 I enabled the Storage Service End point.
Created a storage account stgaccount1 and then on the firewall settings for the storage account, I added the subnet1.
Created a Service Endpoint Policy which allowed access only to stgaccount1 and associated this policy to subnet1.
This setup worked for me just fine and now I wanted to automate it and hence I generated the template for it, however just by looking at the template it seemed like there were circular dependencies in the template and when I tried deploying it failed as expected.
The dependency flow looked like this.
Service Endpoind policy is dependent on Storage Account.
Storage Account is dependent on subnet1 as the access is allowed only for this subnet.
Now since subnet is also associated with ServiceEndpoint policy, it is dependent on Service End Point Policy.
I am not sure who can I resolved this dependency chain or what is the right way for it.
Below is the template for reference.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymenttemplate.json#",
"contentversion": "1.0.0.0",
"parameters": {
"virtual_network_name": {
"defaultvalue": "vnet",
"type": "string"
},
"serviceEndPointPolicyName": {
"type": "string",
"defaultvalue": "storageEndPointPolicy"
}
},
"variables": {
"storageAccountName": "[tolower(concat(resourceGroup().name, 'storageaccount'))]",
"virtualNetworkName": "[concat(resourceGroup().name, parameters('virtual_network_name'))]"
},
"resources": [
{
"type": "Microsoft.Network/serviceEndpointPolicies",
"apiVersion": "2019-11-01",
"name": "[parameters('serviceEndPointPolicyName')]",
"location": "eastus",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"serviceEndpointPolicyDefinitions": [
{
"name": "[concat(parameters('serviceEndPointPolicyName'), '_Microsoft.Storage')]",
"properties": {
"service": "Microsoft.Storage",
"serviceResources": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
}
}
]
}
},
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[variables('storageAccountName')]",
"location": "eastus",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), 'subent1')]"
],
"sku": {
"name": "Standard_RAGRS",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [
{
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), 'subent1')]",
"action": "Allow",
"state": "Succeeded"
}
],
"ipRules": [
],
"defaultAction": "Deny"
},
"supportsHttpsTrafficOnly": false,
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true
},
"blob": {
"keyType": "Account",
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "Hot"
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-11-01",
"name": "[variables('virtualNetworkName')]",
"location": "eastus",
"dependsOn": [
"[resourceId('Microsoft.Network/serviceEndpointPolicies', parameters('serviceEndPointPolicyName'))]"
],
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "subnet2",
"properties": {
"addressPrefix": "10.0.1.0/24",
"delegations": [
],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
},
{
"name": "subent1",
"properties": {
"addressPrefix": "10.0.0.0/24",
"serviceEndpointPolicies": [
{
"id": "[resourceId('Microsoft.Network/serviceEndpointPolicies', parameters('serviceEndPointPolicyName'))]"
}
],
"serviceEndpoints": [
{
"service": "Microsoft.Storage",
"locations": [
"*"
]
}
],
"delegations": [
],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
}
],
"virtualNetworkPeerings": [
],
"enableDdosProtection": false,
"enableVmProtection": false
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2019-11-01",
"name": "[concat(variables('virtualNetworkName'), '/subent1')]",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
"[resourceId('Microsoft.Network/serviceEndpointPolicies', parameters('serviceEndPointPolicyName'))]"
],
"properties": {
"addressPrefix": "10.0.0.0/24",
"serviceEndpointPolicies": [
{
"id": "[resourceId('Microsoft.Network/serviceEndpointPolicies', parameters('serviceEndPointPolicyName'))]"
}
],
"serviceEndpoints": [
{
"service": "Microsoft.Storage",
"locations": [
"*"
]
}
],
"delegations": [
],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2019-11-01",
"name": "[concat(variables('virtualNetworkName'), '/subnet2')]",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
],
"properties": {
"addressPrefix": "10.0.1.0/24",
"delegations": [
],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
}
]
}
Export problems aside, follow the same steps in your template (sequence) that you followed in the portal. Below is my version of that... Essentially you'll deploy the vnet first without the policies and then add the policy later...
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymenttemplate.json#",
"contentversion": "1.0.0.0",
"parameters": {
"virtual_network_name": {
"defaultvalue": "vnet",
"type": "string"
},
"serviceEndPointPolicyName": {
"type": "string",
"defaultvalue": "storageEndPointPolicy"
}
},
"variables": {
"storageAccountName": "[uniqueString(resourceGroup().id)]",
"virtualNetworkName": "[parameters('virtual_network_name')]"
},
"resources": [
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-11-01",
"name": "[variables('virtualNetworkName')]",
"location": "eastus",
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "subnet2",
"properties": {
"addressPrefix": "10.0.1.0/24",
"delegations": [
],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
},
{
"name": "subent1",
"properties": {
"addressPrefix": "10.0.0.0/24",
"serviceEndpoints": [
{
"service": "Microsoft.Storage",
"locations": [
"*"
]
}
],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
}
],
"enableDdosProtection": false,
"enableVmProtection": false
}
},
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[variables('storageAccountName')]",
"location": "eastus",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
],
"sku": {
"name": "Standard_RAGRS",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [
{
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), 'subent1')]",
"action": "Allow",
"state": "Succeeded"
}
],
"defaultAction": "Deny"
},
"supportsHttpsTrafficOnly": false,
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true
},
"blob": {
"keyType": "Account",
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "Hot"
}
},
{
"type": "Microsoft.Network/serviceEndpointPolicies",
"apiVersion": "2019-11-01",
"name": "[parameters('serviceEndPointPolicyName')]",
"location": "eastus",
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"serviceEndpointPolicyDefinitions": [
{
"name": "[concat(parameters('serviceEndPointPolicyName'), '_Microsoft.Storage')]",
"properties": {
"service": "Microsoft.Storage",
"serviceResources": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
}
}
]
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2019-11-01",
"name": "[concat(variables('virtualNetworkName'), '/subent1')]",
"dependsOn": [
"[resourceId('Microsoft.Network/serviceEndpointPolicies', parameters('serviceEndPointPolicyName'))]"
],
"properties": {
"addressPrefix": "10.0.0.0/24",
"serviceEndpointPolicies": [
{
"id": "[resourceId('Microsoft.Network/serviceEndpointPolicies', parameters('serviceEndPointPolicyName'))]"
}
],
"serviceEndpoints": [
{
"service": "Microsoft.Storage",
"locations": [
"*"
]
}
],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
}
]
}

How to get ResourceId as output for VM when using copyIndex

I use copyIndex(0) to create several virtualMachine resources (along with publicIP addresses, nic...)
I need the resourceID as output from the deployment for further processing. Usually I do this with the resourceId() function, but since the names are dynamic and copyIndex is not valid in outputs section, I can't figure out the proper syntax for this:
{
"code": "DeploymentOutputEvaluationFailed",
"message": "Unable to evaluate template outputs: 'resourceID'. Please see error details and deployment operations. Please see https://aka.ms/arm-debug for usage details.",
"details": [
{
"code": "DeploymentOutputEvaluationFailed",
"target": "resourceID",
"message": "The template output 'resourceID' 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.."
}
]
}
I guess I need to change resourceID to array, but what is the proper syntax for fetching the resourceId of the dynamically created VMs?
Full ARM template below:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"virtualMachineNamePrefix": {
"type": "string"
},
"virtualMachineSize": {
"type": "string"
},
"virtualMachineCount": {
"type": "int"
},
"adminUsername": {
"type": "string"
},
"adminPassword": {
"type": "secureString"
}
},
"variables": {
"resourceGroupName": "[toLower(ResourceGroup().name)]",
"location": "[resourceGroup().location]",
"networkSecurityGroupName": "[concat(variables('resourceGroupName'), '-nsg')]",
"nsgId": "[resourceId(resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]",
"subnetName": "default",
"virtualNetworkId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', ResourceGroup().name, '/providers/Microsoft.Network/virtualNetworks/', variables('resourceGroupName'), '-vnet')]",
"operatingSystem": "Server2016",
"operatingSystemValues": {
"Server2016": {
"PublisherValue": "MicrosoftWindowsServer",
"OfferValue": "WindowsServer",
"SkuValue": "2016-Datacenter"
}
},
"subnetRef": "[concat(variables('virtualNetworkId'), '/subnets/', variables('subnetName'))]"
},
"resources": [
{
"apiVersion": "2016-03-30",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[concat(parameters('virtualMachineNamePrefix'), copyIndex(0), '-ip')]",
"location": "[variables('location')]",
"copy": {
"name": "PIPCopy",
"count": "[parameters('virtualMachineCount')]"
},
"tags": {
"displayName": "[concat(parameters('virtualMachineNamePrefix'), copyIndex(0), '-ip')]"
},
"properties": {
"publicIPAllocationMethod": "Dynamic"
}
},
{
"name": "[concat(parameters('virtualMachineNamePrefix'), copyIndex(0), '-nic')]",
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2016-03-30",
"location": "[variables('location')]",
"copy": {
"name": "NICCopy",
"count": "[parameters('virtualMachineCount')]"
},
"dependsOn": [
"[concat('Microsoft.Network/publicIpAddresses/', parameters('virtualMachineNamePrefix'), copyIndex(0), '-ip')]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(parameters('virtualMachineNamePrefix'), copyIndex(0), '-ip'))]"
},
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"networkSecurityGroup": {
"id": "[variables('nsgId')]"
}
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"name": "[concat(parameters('virtualMachineNamePrefix'), copyIndex(0))]",
"apiVersion": "2017-03-30",
"location": "[variables('location')]",
"identity": {
"type": "SystemAssigned"
},
"copy": {
"name": "VMcopy",
"count": "[parameters('virtualMachineCount')]"
},
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('virtualMachineSize')]"
},
"storageProfile": {
"imageReference": {
"publisher": "[variables('operatingSystemValues')[variables('operatingSystem')].PublisherValue]",
"offer": "[variables('operatingSystemValues')[variables('operatingSystem')].OfferValue]",
"sku": "[variables('operatingSystemValues')[variables('operatingSystem')].SkuValue]",
"version": "latest"
},
"osDisk": {
"name": "[concat(parameters('virtualMachineNamePrefix'),copyIndex(0), '-disk')]",
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Premium_LRS"
},
"caching": "ReadWrite"
}
},
"osProfile": {
"computerName": "[concat(parameters('virtualMachineNamePrefix'),copyIndex(0))]",
"adminUsername": "[parameters('adminUsername')]",
"windowsConfiguration": {
"provisionVMAgent": true
},
"secrets": [],
"adminPassword": "[parameters('adminPassword')]"
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('virtualMachineNamePrefix'), copyIndex(0), '-nic'))]"
}
]
}
},
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', parameters('virtualMachineNamePrefix'), copyIndex(0), '-nic')]"
]
}
],
"outputs": {
"resourceID": {
"type": "string",
"value": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('virtualMachineNamePrefix'), copyIndex(0)))]"
}
}
}
UPDATE:
Thanks # 4c74356b41 for a working answer:
"copy": [
{
"name": "resources",
"count": "[parameters('virtualMachineCount')]",
"input": {
"id": "[resourceId('Microsoft.Compute/virtualMachines', concat(parameters('virtualMachineNamePrefix'), copyIndex('resources')))]"
}
}
]
probably use a variable and output it?
"variables": {
"copy": [
{
"name": "resources",
"count": "[parameters('virtualMachineCount')]"
"input": {
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('virtualMachineNamePrefix'), copyIndex('resources')))]"
}
}
]
}
and just use that var:
"outputs": {
"resourceID": {
"type": "array",
"value": "[variables('resources')]"
}
}
update: I've just noticed your comment in one of the previous answers, so I'm not sure if this answer is what you are looking for, if not - tell me in the comments what you are after exactly, since I'm a bit confused.

Resources