Кажется, что все выражения в шаблоне 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)]"
}
}
]
}
}
}
]
}