Сбой итерации ресурса ARM с пустым массивом - PullRequest
0 голосов
/ 11 декабря 2018

Кажется, что все выражения в шаблоне ARM оцениваются заранее, поэтому, даже если у вас есть условие false для ресурса, выражения в этом ресурсе оцениваются.

Это выглядит такнезависимо от того, явно ли условие установлено на false или это выражение, которое оценивается как false.

Такое поведение проблематично в итерации ресурса case, поскольку выражения внутри ресурса могут ссылаться на copyIndex() параметра или переменной.Тем не менее, этот параметр переменной является пустым массивом, оценка этих выражений завершится неудачно с сообщением, похожим на следующее -

Индекс массива свойств языкового выражения '0' выходит за пределы. Пожалуйста,подробности использования см. в https://aka.ms/arm-template-expressions.

Можно ли как-то изменить свой шаблон, чтобы он работал независимо от того, есть ли ресурсы для добавления?

Примерtemplate

Обратите внимание, что мне уже пришлось взломать параметр count объекта copy.Если оно равно 0 (как может вычислять выражение length(variables('productsJArray'))), проверка шаблона завершится неудачно со следующей ошибкой -

Число копий должно быть положительным целочисленным значением и не может превышать 800.

Я чувствую, что разумно ожидать, что если count равно 0, то ресурс не добавляется - но это совсем другая тема!

{
    "$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'.

Этот шаблонгенерирует следующую ошибку -

Невозможно обработать выражения языка шаблонов для ресурса '/ подписки / ********** / resourceGroups / **********/providers/Microsoft.Resources/deployments/api-management-products »в строке« 1 »и столбце« 839 ».Функция шаблона 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 ]

0 голосов
/ 11 декабря 2018

Вот последний шаблон, который я буду использовать.Это позволяет мне передавать либо массив объектов, либо пустой массив параметру 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]"
                            }
                        }
                    ]
                }
            }
        }
    ]
}
0 голосов
/ 11 декабря 2018

два способа обойти это:

  1. if() взломать, так что если length == 0, length = 1.Используя этот подход, вам нужен прокси-объект, на который вы будете ссылаться, поскольку ссылка на несуществующий объект не будет работать.
  2. При использовании вложенных развертываний вы можете поместить условие в развертывание, чтобы оно не запускалось, если length == 0(и вы запускаете цикл внутри вложенного развертывания).Таким образом, вы не заботитесь о длине нуля.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...