Шаблон Azure ARM, как использовать копию для нескольких частей - PullRequest
0 голосов
/ 10 января 2019

У меня есть проблема, для которой я не могу найти решение, это когда я пытаюсь использовать копирование для динамического создания нескольких деталей в шаблоне ARM на панели инструментов.

Я получаю сообщение об ошибке, когда пытаюсь использовать «[copyIndex ()]» в одном из ключей, как я понимаю из сообщения об ошибке, это не будет работать. Но я не уверен, как я могу обойти эту проблему, поэтому любые идеи будут оценены.

"copy": [
  {
    "name": "servers",
    "count": "[length(parameters('locationKeys'))]",
    "input": {
      "[copyIndex('servers')]": {
        "position": {
          "x": "[mul(copyIndex('servers'), 4)]",
          "y": 1,
          "colSpan": 2,
          "rowSpan": 1
        }
      }
    }
  }
]

Как вы можете видеть в приведенном выше примере, это то, что не удается

"[copyIndex('servers')]": {

И я получаю эту ошибку

Error: Code=InvalidTemplate; Message=Deployment template validation failed: 
'Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.'.

Структура для создания панели мониторинга выглядит следующим образом

"properties": {
  "lenses": {
    "0": {
      "order": 0,
      "parts": {
        "0": {},
        "1": {},
        ...

И у меня есть функция копирования под клавишей "parts".

Обойти это можно было бы путем удаления функции копирования и дублирования кода, но тогда мне трудно заставить его работать с любым заданным количеством «мест», поскольку мне нужно жестко их кодировать.

В основном это то, что я хочу получить в конце.

enter image description here

Есть ли другие хорошие решения, чтобы обойти эту проблему?

UPDATE

Это два шаблона, на которые я ссылаюсь из своей задачи DevOps Azure в конвейере. Обратите внимание, что теперь мне нужно сделать параметры ('locationKeys') [0] и продублировать все блоки вместо копирования с параметрами ('locationKeys') [copyIndex ()]. ​​

parameters.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "locationNames": {
      "value": "#{locationNames}"
    }
  }
}

deploy.json

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "appName": {
      "type": "string",
      "defaultValue" : "myApp"
    },
    "locationNames": {
      "type": "array"
    }
  },
  "variables": {
    "dashboardName": "[concat(parameters('appName'), '-dashboard')]"
  },
  "resources": [
    {
      "name": "[variables('dashboardName')]",
      "type": "Microsoft.Portal/dashboards",
      "apiVersion": "2015-08-01-preview",
      "location": "westeurope",
      "tags": {
        "hidden-title": "24/7 Operations"
      },
      "properties": {
        "lenses": {
          "0": {
            "order": 0,
            "parts": {
              "0": {
                "position": {
                  "x": 0,
                  "y": 0,
                  "colSpan": 4,
                  "rowSpan": 1
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/PartType/MarkdownPart",
                  "settings": {
                    "content": {
                      "settings": {
                        "content": "[concat('# ', parameters('locationNames')[0])]",
                        "title": "",
                        "subtitle": ""
                      }
                    }
                  }
                }
              },
              "1": {
                "position": {
                  "x": 4,
                  "y": 0,
                  "colSpan": 4,
                  "rowSpan": 1
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/PartType/MarkdownPart",
                  "settings": {
                    "content": {
                      "settings": {
                        "content": "[concat('# ', parameters('locationNames')[1])]",
                        "title": "",
                        "subtitle": ""
                      }
                    }
                  }
                }
              },
              "2": {
                "position": {
                  "x": 8,
                  "y": 0,
                  "colSpan": 4,
                  "rowSpan": 1
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/PartType/MarkdownPart",
                  "settings": {
                    "content": {
                      "settings": {
                        "content": "[concat('# ', parameters('locationNames')[2])]",
                        "title": "",
                        "subtitle": ""
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "dependsOn": []
    }
  ],
  "outputs": {
    "resourceGroupId": {
      "type": "string",
      "value": "[resourceGroup().id]"
    }
  }
}

ОБНОВЛЕНИЕ 2

Это рабочий пример с объектами вместо массива. Я проверил это локально с помощью PowerShell, загрузив collector.json и transform.json в http://myjson.com и включив их в качестве свойств при запуске развертывания.

parameters.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "azureEnvironment": {
      "value": "#{azureEnvironment}"
    },
    "locationKeys": {
      "value": "#{locationKeys}"
    },
    "locationNames": {
      "value": "#{locationNames}"
    },
    "transformTemplateLink": {
      "value": "#{transform}"
    },
    "collectorTemplateLink": {
      "value": "#{collector}"
    }
  }
}

deploy.json

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "appName": {
      "type": "string",
      "defaultValue": "myApp"
    },
    "azureEnvironment": {
      "type": "string"
    },
    "locationKeys": {
      "type": "array"
    },
    "locationNames": {
      "type": "array"
    },
    "transformTemplateLink": {
      "type": "string",
      "defaultValue": "[uri(deployment().properties.templateLink.uri, 'transform.json')]"
    },
    "collectorTemplateLink": {
      "type": "string",
      "defaultValue": "[uri(deployment().properties.templateLink.uri, 'collector.json')]"
    }
  },
  "resources": [
    {
      "apiVersion": "2015-01-01",
      "name": "collector",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[parameters('collectorTemplateLink')]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "transformTemplateUri": {
            "value": "[parameters('transformTemplateLink')]"
          },
          "locationNames": {
            "value": "[parameters('locationNames')]"
          }
        }
      }
    },
    {
      "name": "[concat(parameters('appName'), '-dash-', parameters('azureEnvironment'))]",
      "type": "Microsoft.Portal/dashboards",
      "apiVersion": "2015-08-01-preview",
      "location": "westeurope",
      "tags": {
        "hidden-title": "[concat('24/7 Operations - (', parameters('azureEnvironment'), ')')]"
      },
      "properties": {
        "lenses": {
          "0": {
            "order": 0,
            "parts": "[reference('collector').outputs.result.value]"
          }
        }
      },
      "dependsOn": [
        "collector"
      ]
    }
  ],
  "outputs": {
    "resourceGroupId": {
      "type": "string",
      "value": "[resourceGroup().id]"
    }
  }
}

collector.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "transformTemplateUri": {
      "type": "string"
    },
    "locationNames": {
      "type": "array"
    }
  },
  "variables": {
    "count": "[length(parameters('locationNames'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2015-01-01",
      "name": "loop-0",
      "properties": {
        "mode": "Incremental",
        "parameters": {},
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "variables": {},
          "resources": [],
          "outputs": {
            "collection": {
              "type": "object",
              "value": {}
            }
          }
        }
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2015-01-01",
      "name": "[concat('loop-', copyIndex(1))]",
      "copy": {
        "name": "iterator",
        "count": "[variables('count')]",
        "mode": "serial"
      },
      "dependsOn": [
        "[concat('loop-', copyIndex())]"
      ],
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[parameters('transformTemplateUri')]"
        },
        "parameters": {
          "state": {
            "value": "[reference(concat('loop-', copyIndex())).outputs.collection.value]"
          },
          "index": {
            "value": "[copyIndex()]"
          },
          "locationNames": {
            "value": "[parameters('locationNames')]"
          }
        }
      }
    }
  ],
  "outputs": {
    "result": {
      "type": "object",
      "value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
    }
  }
}

transform.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "state": {
      "type": "object",
      "defaultValue": {}
    },
    "index": {
      "type": "int"
    },
    "locationNames": {
      "type": "array"
    }
  },
  "variables": {
    "instance": {
      "[string(parameters('index'))]": {
        "position": {
          "x": "[mul(parameters('index'), 4)]",
          "y": 0,
          "colSpan": 4,
          "rowSpan": 1
        },
        "metadata": {
          "inputs": [],
          "type": "Extension/HubsExtension/PartType/MarkdownPart",
          "settings": {
            "content": {
              "settings": {
                "content": "[concat('# ', parameters('locationNames')[parameters('index')])]",
                "title": "",
                "subtitle": ""
              }
            }
          }
        }
      }
    }
  },
  "resources": [],
  "outputs": {
    "collection": {
      "type": "object",
      "value": "[union(parameters('state'), variables('instance'))]"
    }
  }
}

1 Ответ

0 голосов
/ 10 января 2019

если вы просто попробуете тот же (но упрощенный) подход в разделе переменных, вы получите эту ошибку:

Имя переменной не может быть выражением.

Я думаю, что то же самое везде, вы не можете использовать выражение для вычисления имени свойства, только значение. Сказав это, если вы хотите создать цикл, вам нужно использовать вложенное развертывание в качестве итератора. Вы передадите необходимые части в \ соберите их там на основе ввода и создадите получившийся массив:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {
        "locations": [
            "eastus",
            "westeurope"
        ],
        "eastus": {
            "red": 1
        },
        "westeurope": {
            "blue": 2
        },
        "empty": []
    },
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "[concat('iterator-', copyIndex(1))]",
            "type": "Microsoft.Resources/deployments",
            "copy": {
                "name": "someName",
                "count": "[length(variables('locations'))]"
            },
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "https://paste.ee/r/t5ca9/0"
                },
                "parameters": {
                    "source": {
                        "value": "[variables(variables('locations')[copyIndex()])]"
                    },
                    "state": {
                        "value": "[if(equals(copyIndex(), 0), variables('empty'), reference(concat('iterator-', copyIndex())).outputs.collection.value)]"
                    }
                }
            }
        }
    ],
    "outputs": {
        "results": {
            "type": "array",
            "value": "[reference(concat('iterator-', string(length(variables('locations'))))).outputs.collection.value]"
        }
    } }

и ваш итератор выглядит так:

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "source": {
            "type": "object"
        },
        "state": {
            "type": "array",
            "defaultValue": []
        }
    },
    "resources": [],
    "outputs": {
        "collection": {
            "type": "array",
            "value": "[concat(array(parameters('source')), parameters('state'))]"
        }
    }
}

пс. эта ссылка временная (1 месяц), но вы можете загрузить шаблон итератора где угодно и просто жестко, он не содержит никаких секретов \ никаких данных. имп. более простой способ - создать это вне шаблона (powershell \ python \ what) и передать в качестве параметра внутри шаблона

...