Azure FrontDoor:如何设置内部有多个实例的后端池?

Azure FrontDoor: how to set up backendPool with multiple instance inside?

我使用 ARM 模板启动基础架构即代码,之前我的所有部署都是使用 Powershell 进行的。希望你能帮我解决这个问题。

我想部署 {2 个应用服务 + Azure FrontDoor]。在 FrontDoor-Backendpool 中,我想定义 2 个应用程序服务。在我的代码下方:

{
"$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": {}

}

如您所见,我在参数 location 上进行迭代以创建我的 AppService 计划和 AppService,它运行良好。所以我想对 BackEndpool 做同样的事情。

这是让我头疼的部分代码

address": "[concat(variables('appServiceName'), parameters('location')[copyIndex()], '.azurewebsites.net') ]",

里面有问题,但我不知道为什么。 返回的错误是: 错误:代码=无效模板; Message=部署模板语言表达式求值 失败:'模板语言函数 'copyIndex' 的参数无效。资源中不存在提供的副本名称“”。 请参阅 https://aka.ms/arm-copy for usage details.'. Please see https://aka.ms/arm-template-expressions 了解使用详情。

我的灵感来自 MS 官方文档 link from MS 关于如何修复它的任何想法? 谢谢

您需要在 backendPools 部分对 copyIndex 的调用中包含 copy 名称 属性。这就是为什么说“提供的副本名称 '' 不存在”。 属性 副本的处理方式与资源副本略有不同。

"loopName 属性 使您能够指定 copyIndex 是指资源迭代还是 属性 迭代。如果没有为 loopName 提供值,则使用当前资源类型迭代。提供在 属性 上迭代时 loopName 的值。” 资料来源:https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-numeric#copyindex

parameters('location')[copyIndex('backends')]