代码之家  ›  专栏  ›  技术社区  ›  David Gard

ARM资源迭代因空数组而失败

  •  0
  • David Gard  · 技术社区  · 7 年前

    false 对于资源,将计算该资源中的表达式。

    错误的 或者如果它是一个计算结果为 .

    这种行为在资源迭代中是有问题的,因为资源中的表达式可能引用 copyIndex()

    语言表达式属性数组索引“0”超出范围。。请看 https://aka.ms/arm-template-expressions 有关用法的详细信息。

    请注意,我已经“黑客”了 count copy 对象如果是 0 (作为表达 length(variables('productsJArray')) 可能导致评估失败,模板验证失败,出现以下错误-

    副本计数必须为正整数值,且不能超过“800”。

    我觉得如果 计数 ,则不添加任何资源-但这是一个完全不同的主题!

    {
        "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "apiManagementServiceName": {
                "type": "string",
                "metadata": {
                    "description": "The name of the API Management instance."
                }
            },
            "productsJson": {
                "type": "string",
                "metadata": {
                    "description": "A JSON representation of the Products to add."
                }
            }
        },
        "variables": {
            "productsJArray": "[json(parameters('productsJson'))]"
        },
        "resources": [
            {
                "condition": "[greater(length(variables('productsJArray')), 0)]",
                "type": "Microsoft.ApiManagement/service/products",
                "name": "[concat(parameters('apiManagementServiceName'), '/', variables('productsJArray')[copyIndex()].name)]",
                "apiVersion": "2018-06-01-preview",
                "properties": {
                    "displayName": "[variables('productsJArray')[copyIndex()].displayName]",
                    "description": "[variables('productsJArray')[copyIndex()].description]",
                    "state": "[variables('productsJArray')[copyIndex()].state]",
                    "subscriptionRequired": "[variables('productsJArray')[copyIndex()].subscriptionRequired]",
                    "approvalRequired": "[variables('productsJArray')[copyIndex()].approvalRequired]"
                },
                "copy": {
                    "name": "productscopy",
                    "count": "[if(greater(length(variables('productsJArray')), 0), length(variables('productsJArray')), 1)]"
                }
            }
        ]
    }
    

    将工作的示例参数文件

    请注意,虽然这看起来很好,但在某些情况下 productsJson [] ,这就是我的问题所在。

    {
            "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
            "contentVersion": "1.0.0.0",
            "parameters": {
                    "apiManagementServiceName": {
                            "value": "my-api-management"
                    },
                    "productsJson": {
                            "value": "[{\"name\":\"my-product\",\"displayName\":\"My Product\",\"description\":\"My product is awesome.\",\"state\":\"published\",\"subscriptionRequired\":true,\"approvalRequired\":false}]"
                    }
            }
    }
    

    将失败的示例参数文件

    {
            "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
            "contentVersion": "1.0.0.0",
            "parameters": {
                    "apiManagementServiceName": {
                            "value": "lmk-bvt-conveyorbot"
                    },
                    "productsJson": {
                            "value": "[]"
                    }
            }
    }
    

    源自用户“4c74356b41”的建议之一。

    此模板正在生成以下错误-

    无法处理第“1”行和第“839”列的资源“/subscriptions/**************/resourceGroups/********/providers/Microsoft.Resources/deployments/api管理产品”的模板语言表达式此位置不需要模板函数“copyIndex”。该函数只能在指定了副本的资源中使用。

    {
            "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
            "contentVersion": "1.0.0.0",
            "parameters": {
                    "apiManagementServiceName": {
                            "type": "string",
                            "metadata": {
                                    "description": "The name of the API Management instance."
                            }
                    },
                    "productsJson": {
                            "type": "string",
                            "metadata": {
                                    "description": "A JSON representation of the Products to add."
                            }
                    }
            },
            "variables": {
                    "productsJArray": "[json(parameters('productsJson'))]"
            },
            "resources": [
                    {
                            "condition": "[greater(length(variables('productsJArray')), 0)]",
                            "type": "Microsoft.Resources/deployments",
                            "name": "api-management-products",
                            "apiVersion": "2017-05-10",
                            "properties": {
                                    "mode": "Incremental",
                                    "template": {
                                            "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                                            "contentVersion": "1.0.0.0",
                                            "resources": [
                                                    {
                                                            "type": "Microsoft.ApiManagement/service/products",
                                                            "name": "[concat(parameters('apiManagementServiceName'), '/', variables('productsJArray')[copyIndex('productscopy')].name)]",
                                                            "apiVersion": "2018-06-01-preview",
                                                            "properties": {
                                                                    "displayName": "[variables('productsJArray')[copyIndex('productscopy')].displayName]",
                                                                    "description": "[variables('productsJArray')[copyIndex('productscopy')].description]",
                                                                    "state": "[variables('productsJArray')[copyIndex('productscopy')].state]",
                                                                    "subscriptionRequired": "[variables('productsJArray')[copyIndex('productscopy')].subscriptionRequired]",
                                                                    "approvalRequired": "[variables('productsJArray')[copyIndex('productscopy')].approvalRequired]"
                                                            },
                                                            "copy": {
                                                                    "name": "productscopy",
                                                                    "count": "[if(greater(length(variables('productsJArray')), 0), length(variables('productsJArray')), 1)]"
                                                            }
                                                    }
                                            ]
                                    }
                            }
                    }
            ]
    }
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   4c74356b41    7 年前

    解决此问题的两种方法:

    1. if() 哈克,如果 length == 0 , length = 1 . 使用这种方法,您需要有一个要引用的代理对象,因为引用一个不存在的对象是行不通的。
    2. 使用嵌套部署,您可以对部署设置条件,使其在以下情况下不会启动: 长度==0 (并在嵌套部署中运行循环)。这样你就不在乎零的长度了。
        2
  •  2
  •   David Gard    7 年前

    这是我将使用的最终模板。这允许我将对象数组或空数组传递给 productsJson

    {
        "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "apiManagementServiceName": {
                "type": "string",
                "metadata": {
                    "description": "The name of the API Management instance."
                }
            },
            "productsJson": {
                "type": "string",
                "metadata": {
                    "description": "A JSON representation of the Products to add."
                }
            }
        },
        "variables": {
            "productsJArray": "[json(parameters('productsJson'))]"
        },
        "resources": [
            {
                "condition": "[greater(length(variables('productsJArray')), 0)]",
                "type": "Microsoft.Resources/deployments",
                "name": "[concat('api-management-products-', copyIndex())]",
                "apiVersion": "2017-05-10",
                "copy": {
                    "name": "productscopy",
                    "count": "[if(greater(length(variables('productsJArray')), 0), length(variables('productsJArray')), 1)]",
                    "mode": "Serial"
                },
                "properties": {
                    "mode": "Incremental",
                    "template": {
                        "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                        "contentVersion": "1.0.0.0",
                        "resources": [
                            {
                                "type": "Microsoft.ApiManagement/service/products",
                                "name": "[concat(parameters('apiManagementServiceName'), '/', variables('productsJArray')[copyIndex()].name)]",
                                "apiVersion": "2018-06-01-preview",
                                "properties": {
                                    "displayName": "[variables('productsJArray')[copyIndex()].displayName]",
                                    "description": "[variables('productsJArray')[copyIndex()].description]",
                                    "state": "[variables('productsJArray')[copyIndex()].state]",
                                    "subscriptionRequired": "[variables('productsJArray')[copyIndex()].subscriptionRequired]",
                                    "approvalRequired": "[variables('productsJArray')[copyIndex()].approvalRequired]"
                                }
                            }
                        ]
                    }
                }
            }
        ]
    }
    
        3
  •  1
  •   user2309432    5 年前

    也可以在空数组中包含占位符元素,并使用条件忽略占位符元素。这样地

    {
    "parameters": {
        "yourArray": {
            "defaultValue": [
                {
                    "name": "placeholder"
                }
            ],
            "type": "array"
        }
    },
    "resources": [
        {
            "condition": "[not(equals(parameters('yourArray')[copyIndex()].name,'placeholder'))]",
            "copy": {
                "name": "yourArray",
                "count": "[length(parameters('yourArray'))]"
            }
        }
    ]
    }