Azure ARM template : set point-to-site configuration in a Virtual network Gateway - azure

I'd like to set the 'Address pool' property in the 'point-to-site' section of a Virtual network Gateway created by a template.
Here the setting in Azure portal
Here the template
{
"apiVersion": "2015-06-15",
"name": "[variables('gateway').name]",
"type": "Microsoft.Network/virtualNetworkGateways",
"location": "[parameters('aseLocation')]",
"dependsOn": [
"[variables('virtualNetworkSubnet').name]",
"[variables('publicIpVnGateway').name]"
],
"properties": {
"gatewayType": "Vpn",
"ipConfigurations": [
{
"name": "default",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', variables('virtualNetwork').name, variables('virtualNetworkSubnet').name)]"
},
"publicIpAddress": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/publicIPAddresses/', variables('publicIpVnGateway').name)]"
}
}
}
],
"enableBgp": false,
"vpnType": "RouteBased",
"sku": {
"name": "Standard",
"tier": "Standard"
}
}
}

Yes and you can do so using these properties:
"properties": {
"ipConfigurations": [
{
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": ""
},
"publicIPAddress": {
"id": ""
}
},
"name": "vnetGatewayConfig"
}
],
"gatewayType": "VPN",
"vpnType": "RouteBased",
"enableBgp": false,
"activeActive": false,
"vpnClientConfiguration": {
"vpnClientAddressPool": {
"addressPrefixes": [
"<ip_address>"
]
},
"vpnClientProtocols": [
"SSTP",
"IkeV2"
]
},
"sku": {
"name": "<sku>",
"tier": "<sku>",
"capacity": "2"
}
}
By inserting the "vpnClientConfiguration" section you can define the point to site config. Additionally you can add the certificate references here also.

Related

Creating a internal standard load balancer with HA ports in Azure

I am trying to create a internal standard load balancer in Azure with HA ports using ARM template . I am getting below validation error.
{
"code": "InvalidTemplateDeployment",
"details": [
{
"code": "PortValueIsOutOfRange",
"message": "Resource DC10TESTCPW01 has invalid value of Port (0). The value must be between 1 and 65535.",
"details": []
}
],
"message": "The template deployment 'Microsoft.Template-20210524012843' is not valid according to the validation procedure. The tracking id is '585f5d57-4423-47a8-a45d-4a0e371b47c2'. See inner errors for details."
}
Sample:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminUsername": {
"type": "string",
"metadata": {
"description": "Admin username"
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Admin password"
}
},
"vmNamePrefix": {
"type": "string",
"defaultValue": "BackendVM",
"metadata": {
"description": "Prefix to use for VM names"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_DS1_V2",
"metadata": {
"description": "Size of the virtual machines"
}
}
},
"variables": {
"availabilitySetName": "AvSet",
"storageAccountType": "Standard_LRS",
"storageAccountName": "[uniqueString(resourceGroup().id)]",
"virtualNetworkName": "vNet",
"subnetName": "backendSubnet",
"loadBalancerName": "ilb",
"networkInterfaceName": "nic",
"subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]",
"numberOfInstances": 2
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[variables('storageAccountType')]"
},
"kind": "StorageV2"
},
{
"type": "Microsoft.Compute/availabilitySets",
"apiVersion": "2020-06-01",
"name": "[variables('availabilitySetName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Aligned"
},
"properties": {
"PlatformUpdateDomainCount": 2,
"PlatformFaultDomainCount": 2
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-06-01",
"name": "[variables('virtualNetworkName')]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "10.0.2.0/24"
}
}
]
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2020-06-01",
"name": "[concat(variables('networkInterfaceName'), copyindex())]",
"location": "[parameters('location')]",
"copy": {
"name": "nicLoop",
"count": "[variables('numberOfInstances')]"
},
"dependsOn": [
"[variables('virtualNetworkName')]",
"[variables('loadBalancerName')]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), 'BackendPool1')]"
}
]
}
}
]
}
},
{
"type": "Microsoft.Network/loadBalancers",
"apiVersion": "2020-06-01",
"name": "[variables('loadBalancerName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"dependsOn": [
"[variables('virtualNetworkName')]"
],
"properties": {
"frontendIPConfigurations": [
{
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"privateIPAddress": "10.0.2.6",
"privateIPAllocationMethod": "Static"
},
"name": "LoadBalancerFrontend"
}
],
"backendAddressPools": [
{
"name": "BackendPool1"
}
],
"loadBalancingRules": [
{
"properties": {
"frontendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('loadBalancerName'), 'LoadBalancerFrontend')]"
},
"backendAddressPool": {
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), 'BackendPool1')]"
},
"probe": {
"id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), 'lbprobe')]"
},
"protocol": "Tcp",
"frontendPort": 80,
"backendPort": 80,
"idleTimeoutInMinutes": 15
},
"Name": "lbrule"
}
],
"probes": [
{
"properties": {
"protocol": "Tcp",
"port": 80,
"intervalInSeconds": 15,
"numberOfProbes": 2
},
"name": "lbprobe"
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2020-06-01",
"name": "[concat(parameters('vmNamePrefix'), copyindex())]",
"location": "[parameters('location')]",
"copy": {
"name": "virtualMachineLoop",
"count": "[variables('numberOfInstances')]"
},
"dependsOn": [
"[variables('storageAccountName')]",
"nicLoop",
"[variables('availabilitySetName')]"
],
"properties": {
"availabilitySet": {
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('availabilitySetName'))]"
},
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"osProfile": {
"computerName": "[concat(parameters('vmNamePrefix'), copyIndex())]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
},
"osDisk": {
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('networkInterfaceName'), copyindex()))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true,
"storageUri": "[reference(variables('storageAccountName')).primaryEndpoints.blob]"
}
}
}
}
]
}
Update with HA:
Configure more than one front-end private IP address for a single
internal Standard Load Balancer resource.
Configure multipleload-balancing rules, where each rule has a single unique front-end IP address selected.
Select the HA ports option, and then set Floating IP to Enabled for all the load-balancing rules.
JSON View:
{
"name": "ilb1",
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1",
"etag": "W/\"<ETAG>\"",
"type": "Microsoft.Network/loadBalancers",
"location": "westeurope",
"tags": {},
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "<ResourceGuid>",
"frontendIPConfigurations": [
{
"name": "LoadBalancerFrontEnd",
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/frontendIPConfigurations/LoadBalancerFrontEnd",
"etag": "W/\"<ETAG>\"",
"type": "Microsoft.Network/loadBalancers/frontendIPConfigurations",
"properties": {
"provisioningState": "Succeeded",
"privateIPAddress": "10.0.0.6",
"privateIPAllocationMethod": "Static",
"subnet": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/virtualNetworks/<RG>-vnet/subnets/default"
},
"loadBalancingRules": [
{
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule1"
}
]
}
},
{
"name": "ilbIP2",
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/frontendIPConfigurations/ilbIP2",
"etag": "W/\"<ETAG>\"",
"type": "Microsoft.Network/loadBalancers/frontendIPConfigurations",
"properties": {
"provisioningState": "Succeeded",
"privateIPAddress": "10.0.0.7",
"privateIPAllocationMethod": "Static",
"subnet": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/virtualNetworks/<RG>-vnet/subnets/default"
},
"loadBalancingRules": [
{
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule2"
}
]
}
}
],
"backendAddressPools": [
{
"name": "poolbackend1",
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/backendAddressPools/poolbackend1",
"etag": "W/\"<ETAG>\"",
"properties": {
"provisioningState": "Succeeded",
"loadBalancingRules": [
{
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule1"
},
{
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule2"
}
]
},
"type": "Microsoft.Network/loadBalancers/backendAddressPools"
}
],
"loadBalancingRules": [
{
"name": "rule1",
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule1",
"etag": "W/\"<ETAG>\"",
"type": "Microsoft.Network/loadBalancers/loadBalancingRules",
"properties": {
"provisioningState": "Succeeded",
"frontendIPConfiguration": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/frontendIPConfigurations/LoadBalancerFrontEnd"
},
"frontendPort": 0,
"backendPort": 0,
"enableFloatingIP": true,
"idleTimeoutInMinutes": 4,
"protocol": "All",
"loadDistribution": "SourceIP",
"disableOutboundSnat": true,
"backendAddressPool": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/backendAddressPools/poolbackend1"
},
"probe": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/probes/Hprobe1"
}
}
},
{
"name": "rule2",
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule2",
"etag": "W/\"<ETAG>\"",
"type": "Microsoft.Network/loadBalancers/loadBalancingRules",
"properties": {
"provisioningState": "Succeeded",
"frontendIPConfiguration": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/frontendIPConfigurations/ilbIP2"
},
"frontendPort": 0,
"backendPort": 0,
"enableFloatingIP": true,
"idleTimeoutInMinutes": 4,
"protocol": "All",
"loadDistribution": "SourceIP",
"disableOutboundSnat": true,
"backendAddressPool": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/backendAddressPools/poolbackend1"
},
"probe": {
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/probes/Hprobe1"
}
}
}
],
"probes": [
{
"name": "Hprobe1",
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/probes/Hprobe1",
"etag": "W/\"<ETAG>\"",
"properties": {
"provisioningState": "Succeeded",
"protocol": "Tcp",
"port": 80,
"intervalInSeconds": 5,
"numberOfProbes": 2,
"loadBalancingRules": [
{
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule1"
},
{
"id": "/subscriptions/<SubscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/loadBalancers/ilb1/loadBalancingRules/rule2"
}
]
},
"type": "Microsoft.Network/loadBalancers/probes"
}
],
"inboundNatRules": [],
"inboundNatPools": []
},
"sku": {
"name": "Standard"
}
}
ILB HA Template:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"loadBalancers_ilb1_name": {
"defaultValue": "ilb1",
"type": "String"
},
"virtualNetworks_<RG>_vnet_externalid": {
"defaultValue": "/subscriptions/<subscriptionId>/resourceGroups/<RG>/providers/Microsoft.Network/virtualNetworks/<RG>-vnet",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/loadBalancers",
"apiVersion": "2020-11-01",
"name": "[parameters('loadBalancers_ilb1_name')]",
"location": "westeurope",
"dependsOn": [
"[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('loadBalancers_ilb1_name'), 'poolbackend1')]"
],
"sku": {
"name": "Standard",
"tier": "Regional"
},
"properties": {
"frontendIPConfigurations": [
{
"name": "LoadBalancerFrontEnd",
"properties": {
"privateIPAddress": "10.0.0.6",
"privateIPAllocationMethod": "Static",
"subnet": {
"id": "[concat(parameters('virtualNetworks_<RG>_vnet_externalid'), '/subnets/default')]"
},
"privateIPAddressVersion": "IPv4"
},
"zones": [
"1",
"2",
"3"
]
},
{
"name": "ilbIP2",
"properties": {
"privateIPAddress": "10.0.0.7",
"privateIPAllocationMethod": "Static",
"subnet": {
"id": "[concat(parameters('virtualNetworks_<RG>_vnet_externalid'), '/subnets/default')]"
},
"privateIPAddressVersion": "IPv4"
},
"zones": [
"1",
"2",
"3"
]
}
],
"backendAddressPools": [
{
"name": "poolbackend1",
"properties": {
"loadBalancerBackendAddresses": [
{
"name": "1a959793-169e-4e7f-8711-128f237dbf67",
"properties": {
"ipAddress": "10.0.0.9",
"virtualNetwork": {
"id": "[parameters('virtualNetworks_<RG>_vnet_externalid')]"
}
}
}
]
}
}
],
"loadBalancingRules": [
{
"name": "rule1",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancers_ilb1_name')), '/frontendIPConfigurations/LoadBalancerFrontEnd')]"
},
"frontendPort": 0,
"backendPort": 0,
"enableFloatingIP": true,
"idleTimeoutInMinutes": 4,
"protocol": "All",
"enableTcpReset": false,
"loadDistribution": "SourceIP",
"disableOutboundSnat": true,
"backendAddressPool": {
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('loadBalancers_ilb1_name'), 'poolbackend1')]"
},
"probe": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancers_ilb1_name')), '/probes/Hprobe1')]"
}
}
},
{
"name": "rule2",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancers_ilb1_name')), '/frontendIPConfigurations/ilbIP2')]"
},
"frontendPort": 0,
"backendPort": 0,
"enableFloatingIP": true,
"idleTimeoutInMinutes": 4,
"protocol": "All",
"enableTcpReset": false,
"loadDistribution": "SourceIP",
"disableOutboundSnat": true,
"backendAddressPool": {
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('loadBalancers_ilb1_name'), 'poolbackend1')]"
},
"probe": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancers_ilb1_name')), '/probes/Hprobe1')]"
}
}
}
],
"probes": [
{
"name": "Hprobe1",
"properties": {
"protocol": "Tcp",
"port": 80,
"intervalInSeconds": 5,
"numberOfProbes": 2
}
}
],
"inboundNatRules": [],
"outboundRules": [],
"inboundNatPools": []
}
},
{
"type": "Microsoft.Network/loadBalancers/backendAddressPools",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('loadBalancers_ilb1_name'), '/poolbackend1')]",
"dependsOn": [
"[resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancers_ilb1_name'))]"
],
"properties": {
"loadBalancerBackendAddresses": [
{
"name": "1a959793-169e-4e7f-8711-128f237dbf67",
"properties": {
"ipAddress": "10.0.0.9",
"virtualNetwork": {
"id": "[parameters('virtualNetworks_<RG>_vnet_externalid')]"
}
}
}
]
}
}
]
}

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.

Failing ARM Template Deployment for Azure Load Balancer - Jenkins Giving No Error

I'm currently attempting to deploy an Azure Load Balancer instance to provide load balanced access to two firewalls. This is to provide a pseudo-HA configuration.
However, when I try to deploy this template using Jenkins, it gives me the following unhelpful response (even with the --debug command):
DEBUG: attempting to read file Test/deployment/azuredeploy.json as utf-8-sig
DEBUG: attempting to read file Test/parameters/deploymentParameters.json as utf-8-sig
DEBUG: No tty
available.
ERROR:
So it's saying there's an error but can't tell me what the error is.
I have two requests:
Can anybody tell me how I can find out what is causing this error? Any commands or tools I am unaware of?
If anybody is skilled with the Azure Load Balancer syntax for ARM then can you eyeball my deployment template and let me know if it has any immediate flaws. Code is below.
code:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"virtualNetworkName": {
"type": "string",
"metadata": {
"description": "vnet name"
}
},
"subnet1Name": {
"type": "string",
"metadata": {
"description": "Subnet 1 name"
}
},
"subnet2Name": {
"type": "string",
"metadata": {
"description": "Subnet 2 name"
}
},
"loadBalancerName": {
"type": "string",
"metadata": {
"description": "name of the load balancer instance"
}
},
"nicName1": {
"type": "string",
"metadata": {
"description": "name of NIC 1"
}
},
"nicName2": {
"type": "string",
"metadata": {
"description": "name of NIC 2"
}
},
"nicName3": {
"type": "string",
"metadata": {
"description": "name of NIC 3"
}
},
"nicName4": {
"type": "string",
"metadata": {
"description": "name of NIC 4"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {
"virtualNetworkName": "[parameters('virtualNetworkName')]",
"subnet1Name": "[parameters('subnet1Name')]",
"subnet2Name": "[parameters('subnet2Name')]",
"loadBalancerName": "[parameters('loadBalancerName')]",
"nicName1": "[parameters('nicName1')]",
"nicName2": "[parameters('nicName2')]",
"nicName3": "[parameters('nicName3')]",
"nicName4": "[parameters('nicName4')]",
"subnetRef1": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnet1Name'))]",
"subnetRef2": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnet2Name'))]"
},
"resources": [
{
"apiVersion": "2018-08-01",
"type": "Microsoft.Network/networkInterfaces",
"name": "[variables('nicName1')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig-firewallBE",
"properties": {
"subnet": {
"id": "[variables('subnetRef1')]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')),'/backendAddressPools/firewallBE-subnet-pool')]"
}
]
}
}
]
}
},
{
"apiVersion": "2018-08-01",
"type": "Microsoft.Network/networkInterfaces",
"name": "[variables('nicName2')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig-firewallBE",
"properties": {
"subnet": {
"id": "[variables('subnetRef1')]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')),'/backendAddressPools/firewallBE-subnet-pool')]"
}
]
}
}
]
}
},
{
"apiVersion": "2018-08-01",
"type": "Microsoft.Network/networkInterfaces",
"name": "[variables('nicName3')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig-firewallFE",
"properties": {
"subnet": {
"id": "[variables('subnetRef2')]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')),'/backendAddressPools/firewallFE-subnet-pool')]"
}
]
}
}
]
}
},
{
"apiVersion": "2018-08-01",
"type": "Microsoft.Network/networkInterfaces",
"name": "[variables('nicName4')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig-firewallFE",
"properties": {
"subnet": {
"id": "[variables('subnetRef2')]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')),'/backendAddressPools/firewallFE-subnet-pool')]"
}
]
}
}
]
}
},
{
"apiVersion": "2017-08-01",
"name": "[variables('loadBalancerName')]",
"type": "Microsoft.Network/loadBalancers",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"properties": {
"frontendIPConfigurations": [
{
"name": "firewallBE-FrontEnd",
"properties": {
"subnet": {
"id": "[variables('subnetRef1')]"
}
}
},
{
"name": "firewallFE-FrontEnd",
"properties": {
"subnet": {
"id": "[variables('subnetRef2')]"
}
}
}
],
"backendAddressPools": [
{
"name": "firewallBE-subnet-pool"
},
{
"name": "firewallFE-subnet-pool"
}
],
"loadBalancingRules": [
{
"properties": {
"frontendIPConfiguration": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')), '/frontendIpConfigurations/firewallBE-FrontEnd')]"
},
"backendAddressPool": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')), '/backendAddressPools/firewallBE-subnet-pool')]"
},
"probe": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')), '/probes/firewall-lb-probe')]"
},
"protocol": "All",
"frontendPort": 0,
"backendPort": 0
},
"name": "firewallBE-subnet-rule"
},
{
"properties": {
"frontendIPConfiguration": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')), '/frontendIpConfigurations/firewallFE-FrontEnd')]"
},
"backendAddressPool": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')), '/backendAddressPools/firewallFE-subnet-pool')]"
},
"probe": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName')), '/probes/firewall-lb-probe')]"
},
"protocol": "All",
"frontendPort": 0,
"backendPort": 0
},
"name": "firewallFE-subnet-rule"
}
],
"probes": [
{
"properties": {
"protocol": "Tcp",
"port": 0,
"intervalInSeconds": 15,
"numberOfProbes": 2
},
"name": "firewall-lb-probe"
}
]
}
}
]
}
in this case the error was due to a missing parameter that needed to be passed to the template

How nested deployments are enforced

I have Azure ARM parent template which has nested deployment of Microsoft.Automation/automationAccounts which in turn has nested resource Configurations. I was able to successfully deploy entire template once, which in fact created configuration in automation Account. I manually deleted configuration inside automation account and tried running template again but this nested deployment is no longer triggered at all. There is no errors, just this nested deployment is not shown up at all in history. I would assume ARM thinks since it succeeded last time it does not need to deploy or something, not sure. What might be the problem?
Here is relevant parts of template. Neither ScaleSet no nested deployment WorkerNodeDSCConfiguration is triggered at all.
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"name": "[variables('namingInfix')]",
"location": "[resourceGroup().location]",
"apiVersion": "[variables('computeApiVersion')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
"[concat('Microsoft.Network/applicationGateways/', variables('appGwName'))]",
"[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]",
"WorkerNodeDscConfiguration"
],
"sku": {
"name": "[parameters('vmSku')]",
"tier": "Standard",
"capacity": "[parameters('instanceCount')]"
},
"properties": {
"overprovision": "false",
"singlePlacementGroup": "true",
"upgradePolicy": {
"mode": "Automatic"
},
"virtualMachineProfile": {
"licenseType": "[parameters('LicenseType')]",
"storageProfile": {
"osDisk": {
"caching": "ReadWrite",
"createOption": "FromImage"
},
"dataDisks": [],
"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": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'), '/subnets/', variables('subnetName'))]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('loadBalancerName'), '/backendAddressPools/', variables('bePoolName'))]"
}
],
"loadBalancerInboundNatPools": [
{
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('loadBalancerName'), '/inboundNatPools/', variables('natPoolName'))]"
}
],
"ApplicationGatewayBackendAddressPools": [
{
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/applicationGateways/', variables('appGwName'), '/backendAddressPools/', variables('appGwBePoolName'))]"
}
]
}
}
]
}
}
]
},
"extensionProfile": {
"extensions": [
{
"name": "Microsoft.Powershell.DSC",
"properties": {
"autoUpgradeMinorVersion": true,
"typeHandlerVersion": "2.72",
"type": "DSC",
"publisher": "Microsoft.Powershell",
//"forceUpdateTag": "[parameters('DSCExtensionTagVersion')]",
"settings": {
"configurationArguments": {
"RegistrationKey": {
"UserName": "PLACEHOLDER_DONOTUSE",
"Password": "[parameters('registrationKey')]"
},
"RegistrationUrl": "[parameters('registrationUrl')]",
"NodeConfigurationName": "swarmHost",
"RebootNodeIfNeeded": true,
"ConfigurationMode": "ApplyAndAutoCorrect"
}
}
}
}
]
}
}
}
},
{
"name": "swarmmanagerdeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2016-09-01",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('_artifactsLocation'), '/', variables('swarmmanagerdeploymentTemplateFolder'), '/', variables('swarmmanagerdeploymentTemplateFileName'), parameters('_artifactsLocationSasToken'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"swarmmanager1Name": { "value": "[parameters('swarmmanager1Name')]" },
"swarmmanager1VmSize": { "value": "[variables('swarmmanager1VmSize')]" },
"adminUsername": { "value": "[parameters('adminUsername')]" },
"adminPassword": { "value": "[parameters('adminPassword')]" },
"dockerswarmstorageaccountName": { "value": "[variables('dockerswarmstorageaccountName')]" },
"dockerswarmstorageaccountType": { "value": "[parameters('dockerswarmstorageaccountType')]" },
"swarmmanager1NicName": { "value": "[variables('swarmmanager1NicName')]" },
"swarmmanagerpublicIPName": { "value": "[variables('swarmmanagerpublicIPName')]" },
"swarmmanager1SubnetRef": { "value": "[variables('swarmmanager1SubnetRef')]" },
"swarmmanager1ImagePublisher": { "value": "[variables('swarmmanager1ImagePublisher')]" },
"swarmmanager1ImageOffer": { "value": "[variables('swarmmanager1ImageOffer')]" },
"windowsOSVersion": { "value": "[parameters('windowsOSVersion')]" },
"swarmmanager1StorageAccountContainerName": { "value": "[variables('swarmmanager1StorageAccountContainerName')]" },
"swarmmanager1OSDiskName": { "value": "[variables('swarmmanager1OSDiskName')]" },
"swarmmanagerpublicIPDnsName": { "value": "[variables('swarmmanagerpublicIPName')]" },
"RegistrationKey": { "value": "[parameters('registrationKey')]" },
"RegistrationUrl": { "value": "[parameters('registrationUrl')]" },
"LicenseType": { "value": "[parameters('LicenseType')]" },
"_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" },
"_artifactsLocation": { "value": "[parameters('_artifactsLocation')]" },
"privateKey": { "value": "[parameters('privateKey')]" },
"serverCert": { "value": "[parameters('serverCert')]" },
"CACert": { "value": "[parameters('CACert')]" }
}
}
},
{
"name": "WorkerNodeDscConfiguration",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"resourceGroup": "[parameters('automationAccountRGName')]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"resources": [
{
"apiversion": "2015-10-31",
"location": "[resourceGroup().location]",
"name": "[parameters('automationAccountName')]",
"type": "Microsoft.Automation/automationAccounts",
"properties": {
"sku": {
"name": "Basic"
}
},
"tags": {
},
"resources": [
{
"name": "swarmhost",
"type": "configurations",
"apiVersion": "2018-01-15",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Automation/automationAccounts/', parameters('AutomationAccountName'))]"
],
"properties": {
"state": "Published",
"overwrite": "true",
"Source": {
"type": "uri",
"value": "[parameters('WorkerNodeDSCConfigURL')]"
}
}
},
{
"name": "[guid(resourceGroup().id, deployment().name)]",
"type": "Compilationjobs",
"apiVersion": "2015-10-31",
"tags": {},
"dependsOn": [
"[concat('Microsoft.Automation/automationAccounts/', parameters('AutomationAccountName'))]",
"[concat('Microsoft.Automation/automationAccounts/', parameters('AutomationAccountName'),'/Configurations/swarmhost')]"
],
"properties": {
"configuration": {
"SwarmManagerURI": "[reference('swarmmanagerdeployment').outputs.returnedIPAddress.value]"
}
}
}
]
}
]
}
}
}
its pretty hard to tell what is going on, but you can verify if something is going on by changing some vmss property, for example, to something else and running the template. it will revert it back to what it is in the template. It might be pretty tricky with the automation account stuff, because I would think it wouldnt trigger the compilation job, because the guid is the same and the resource is there already. you would need to provide a new guid each time (ARM cant help you with this, you need to do some randomization externally). Generally I prefer to use powershell to configure automation accounts compared to ARM.
You can also verify that the nested deployment is being triggered by looking at its timestamp, it should change (and it will). The resource is always deployed, but depending on your situation its properties might stay intact.

Resources