I started Infrastructure as Code with ARM Template and previously all my deployment was made with Powershell. Hope you can help me to fix this issue.
I would like to deploy {2 app services + Azure FrontDoor]. In FrontDoor-Backendpool I want to define the 2 appservices. Below my code:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "array",
"metadata": {
"description": "array of region"
},
"defaultValue": [
"centralus",
"eastus"
]
},
"Stage": {
"type": "string",
"metadata": {
"description": "Stage dev, prod"
},
"allowedValues": [
"Dev",
"Prod"
],
"defaultValue": "Dev"
}
},
"functions": [],
"variables": {
"appServicePlanName": "[concat('AppServicePlan-', parameters('Stage'),'-')]",
"appServiceName": "[concat('AppService-', parameters('Stage'), '-')]",
"frontDoorName": "[concat('FrontDoor-', parameters('Stage'), uniqueString(resourceGroup().id))]"
},
"resources": [
{ // App Service Plan
"type": "Microsoft.Web/serverfarms",
"name": "[concat(variables('appServicePlanName'),parameters('location')[copyIndex()])]",
"apiVersion": "2018-02-01",
"copy": {
"count": "[length(parameters('location'))]",
"name": "copy multiple"
},
"location": "[parameters('location')[copyIndex()]]",
"sku": {
"name": "F1",
"capacity": 1
},
"tags": {
"cost": "[parameters('Stage')]"
},
"properties": {
"name": "[concat(variables('appServicePlanName'),parameters('location')[copyIndex()])]"
}
},
{ // App Services
"type": "Microsoft.Web/sites",
"name": "[concat(variables('appServiceName'), parameters('location')[copyIndex()])]",
"apiVersion": "2018-11-01",
"copy": {
"name": "Copy website",
"count": "[length(parameters('location'))]"
},
"location": "[parameters('location')[copyIndex()]]",
"tags": {
"cost": "[parameters('Stage')]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', concat(variables('appServicePlanName'),parameters('location')[copyIndex()]))]"
],
"properties": {
"name": "[concat(variables('appServiceName'), parameters('location')[copyIndex()])]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', concat(variables('appServicePlanName'),parameters('location')[copyIndex()]))]"
}
},
{ // Front Door
"type": "Microsoft.Network/frontDoors",
"apiVersion": "2020-05-01",
"name": "[variables('frontDoorName')]",
"location": "global",
"properties": {
"routingRules": [
{
"name": "routingRule1",
"properties": {
"frontendEndpoints": [
{
"id": "[resourceId('Microsoft.Network/frontDoors/frontendEndpoints', variables('frontDoorName'), 'frontendEndpoint1')]"
}
],
"acceptedProtocols": [
"Http",
"Https"
],
"patternsToMatch": [
"/*"
],
"routeConfiguration": {
"@odata.type": "#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration",
"forwardingProtocol": "MatchRequest",
"backendPool": {
"id": "[resourceId('Microsoft.Network/frontDoors/backendPools', variables('frontDoorName'), 'backendPool1')]"
}
},
"enabledState": "Enabled"
}
}
],
"healthProbeSettings": [
{
"name": "healthProbeSettings1",
"properties": {
"path": "/",
"protocol": "Http",
"intervalInSeconds": 120
}
}
],
"loadBalancingSettings": [
{
"name": "loadBalancingSettings1",
"properties": {
"sampleSize": 4,
"successfulSamplesRequired": 2
}
}
],
"backendPools": [
{
"id": "backendPool1",
"name": "backendPool1",
"properties": {
"copy": [
{
"name": "backends",
"count": "[length(parameters('location'))]",
"input": {
"address": "[concat(variables('appServiceName'), parameters('location')[copyIndex()], '.azurewebsites.net') ]",
"httpPort": 80,
"httpsPort": 443,
"weight": 50,
"priority": 1,
"enabledState": "Enabled"
}
}
],
"loadBalancingSettings": {
"id": "[resourceId('Microsoft.Network/frontDoors/loadBalancingSettings', variables('frontDoorName'), 'loadBalancingSettings1')]"
},
"healthProbeSettings": {
"id": "[resourceId('Microsoft.Network/frontDoors/healthProbeSettings', variables('frontDoorName'), 'healthProbeSettings1')]"
}
}
}
],
"frontendEndpoints": [
{
"name": "frontendEndpoint1",
"properties": {
"hostName": "[concat(variables('frontDoorName'), '.azurefd.net')]",
"sessionAffinityEnabledState": "Enabled"
}
}
],
"enabledState": "Enabled"
}
}
],
"outputs": {}
}
As you can see i iterate on paramater location to create my AppService Plan and AppService and it worked well. So I thought to do same for BackEndpool.
Here part of code which break my head
address": "[concat(variables('appServiceName'), parameters('location')[copyIndex()], '.azurewebsites.net') ]",
Something is wrong inside but I have no idea why. Error retuned is: Error: Code=InvalidTemplate; Message=Deployment template language expression evaluation failed: 'The template language function 'copyIndex' has an invalid argument. The provided copy name '' doesn't exist in the resource. Please see https://aka.ms/arm-copy for usage details.'. Please see https://aka.ms/arm-template-expressions for usage details.
I take my inspiration from official MS documentation link from MS Any idea on how I can fix it ? Thx
You need to include the copy
name property in the call to copyIndex
in the backendPools
part. That is why is says "The provided copy name '' doesn't exist". The property copy is treated a little differently than the resource copy.
"The loopName property enables you to specify whether copyIndex is referring to a resource iteration or property iteration. If no value is provided for loopName, the current resource type iteration is used. Provide a value for loopName when iterating on a property." Source: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-numeric#copyindex
parameters('location')[copyIndex('backends')]