Создание нескольких экземпляров ресурсов с помощью copy element

Завершено

Вы уже объявили ресурсы в списке ресурсов в шаблоне. При развертывании вы получаете один экземпляр каждого элемента, указанного в списке ресурсов. Может потребоваться создать несколько экземпляров определенного ресурса. Например, может потребоваться несколько подсетей в виртуальной сети.

Учтите следующие вопросы и моменты при создании множества экземпляров и при повторении конструкций:

  • Требуется ли несколько копий: для более простых сценариев вы не можете. В более сложных сценариях, таких как подсети или виртуальные машины, может потребоваться определить, требуется ли несколько копий чего-либо.
  • Зависит ли я от ресурса: обычно Azure Resource Manager хорошо определяет, что необходимо создать в каком порядке, чтобы ссылки на шаблон Azure Resource Manager работали. Однако существуют ситуации, в которых может потребоваться указать порядок.
  • Определите схему именования: вы хотите указать значимые имена ресурсов. По этой причине можно использовать параметры, передаваемые во время развертывания. При наличии нескольких копий может потребоваться более детализированный контроль и определение имени итерации для текущей последовательности копирования.
  • Настройка и управление созданием ресурсов: может потребоваться ограничить количество ресурсов, создаваемых в рабочей среде. Это можно сделать, настроив последовательное или параллельное создание ресурсов.
  • Скопируйте другие типы: ресурсы не являются единственной вещью, которую можно создать несколько копий и выполнить итерацию. Фактически, те же действия можно выполнять с помощью свойств, переменных и выходных данных.
  • Родительский-дочерний элемент: может потребоваться настроить отношения "родитель-дочерний" в ресурсах.

Развертывание нескольких экземпляров

Чтобы экономить нажатие клавиш, можно использовать конструкции зацикливания. Если вам нужно снова и снова повторять одну операцию, например для имени и типа, лишь с небольшими отличиями, то можно воспользоваться преимуществом при использовании copy element.

copy element является фрагментом JSON, который можно использовать для различных типов конструкций, таких как ресурсы, свойства, переменные и выходные данные. Синтаксис copy element состоит из ключа copy и массива в качестве значения. Например: "copy": [].

Массив принимает несколько элементов, и каждый элемент является объектом {}, состоящим из набора свойств. Эти свойства зависят от того, в какой конструкции они используются. Как правило, все конструкции элемента copy имеют одно общее свойство count. Это свойство определяет, сколько экземпляров требуется для определенного типа конструкции. Большинство конструкций также позволяют использовать свойство name, позволяющее ссылаться на него из других частей кода. Другие используемые свойства зависят от конструкции.

Выбор

Вы можете спросить: "Если можно использовать copy элемент во многих типах конструкций, которые следует выбрать и когда, и можно ли использовать несколько типов в шаблоне?"

Все зависит от вашего варианта использования. Итерация ресурсов позволяет создавать несколько копий ресурса, и ее имеет смысл использовать, если требуется много учетных записей хранения. Итерация свойств, с другой стороны, позволяет создавать несколько свойств внутри одного ресурса. Это позволяет сэкономить нажатия клавиш и время, и вам самим лучше известно о повторяющихся элементах в шаблоне.

Элемент copy можно использовать во многих местах шаблона. Элемент copy можно использовать для создания множества ресурсов, а также для создания нескольких похожих переменных в одном шаблоне.

Как это работает

Элемент copy работает при вычислении и замене инструкции copy. Замена является результатом того, что вы определяете в copy операторе, повторяющемся столько раз, сколько вы показано в copy поле.

В примере ниже показано, как выглядит определение, использующее copy.

"copy": [
  {
    "name": "dataDisks",
    "count": 2,
    "input": {
      "diskSizeGB": 1023,
      "lun": "[copyIndex('dataDisks')]",
      "createOption": "Empty"
    }
  }
]

Обратите внимание на запись count: 2. Значение 2 означает, что приведенное выше выражение необходимо развернуть до двух записей. Результатом является следующее значение:

"dataDisks": [
{
  "lun": 0,
  "createOption": "Empty",
  "diskSizeGB": 1023
},
{
  "lun": 1,
  "createOption": "Empty",
  "diskSizeGB": 1023
}

Видно, что значение свойства name стало именем свойства, а содержимое свойства input стало частью повторяющегося кода JSON.

Примечание.

Выражение copy и его выходные данные отличаются тем, какой тип выражения используется. Приведенный выше пример дает хорошее представление о том, что происходит при преобразовании выражения в ряд повторяющихся инструкций.

Количество копий может быть ограничено. В настоящее время ограничение составляет 800 записей.

Важно!

Дополнительные сведения об ограничениях см. в статье Итерация ресурсов в шаблонах ARM.

Управление итерацией

Существуют вспомогательные функции, которые помогают ссылаться на определенные индексы в массиве. Функция copyIndex() возвращает текущий индекс. Например, для третьей повторяющейся записи copyIndex() функция возвращает значение 2. Синтаксис copyIndex() выглядит следующим образом.

copyIndex(loopName, offset)

Функция copyIndex() имеет два разных входных параметра loopName и offset. Параметр offset всегда является необязательным и используется для получения смещения текущего индекса. То, что вы добавляете в качестве значения offset, добавляется к текущему индексу. Если текущий индекс возвращает 2, и вы указываете 1 в качестве смещения, функция copyIndex() вернет 3.

Параметр loopName является либо необязательным, либо обязательным в зависимости от того, где он используется. Он обязателен, если используется в конструкции properties, и необязателен, если используется в массиве resources. Ниже приведен пример, в котором он обязателен:

"properties": {
    "storageProfile": {
      "copy": [
        {
          "name": "dataDisks",
          "count": "[parameters('numberOfDataDisks')]",
          "input": {
            "diskSizeGB": 1023,
            "lun": "[copyIndex('dataDisks')]",
            "createOption": "Empty"
          }
        }
      ]
    }
}

Обратите внимание, что элемент copy используется внутри конструкции properties, а для параметра copyIndex() свойство loopName указано как copyIndex('dataDisks').

Ниже приведен пример, в котором loopName обязателен:

{
  "type": "Microsoft.Network/virtualNetworks",
  "apiVersion": "2018-04-01",
  "name": "[concat(parameters('vnetname'), copyIndex())]",
}

Приведенный выше код показывает объявляемый ресурс, а copyIndex() вызывается без параметров, так как он используется в контексте ресурса.

Настройка развертывания

При использовании элемента copy для ресурсов вы в итоге создаете многочисленные схожие поисковые ресурсы.

Иногда может потребоваться управлять созданием и порядком создания ресурсов. Возможные причины для управления порядком перечислены ниже.

  • Ограничения среды. В зависимости от среды, в которой выполняется развертывание, может потребоваться ограничить объем, на который распространяется развертывание. В рабочей среде имеет смысл ограничить количество ресурсов, затрагиваемых в любой момент времени. Чтобы управлять количеством параллельно развертываемых ресурсов, можно настроить режим развертывания.
  • Зависимости. Перед созданием необходимого ресурса может оказаться, что вы зависите от какого-либо из них. Чтобы выразить такую зависимость, существует конструкция с именем dependsOn.

Режимы развертывания и copy

Может потребоваться, чтобы набор ресурсов, созданный конструкцией copy, создавался ранее чего-то другого. В этом случае необходимо выразить эту ситуацию. Помните, что здесь важен режим развертывания, который использует Resource Manager. Поддерживаются два режима:

  • Последовательно. Перевод ресурса в этот режим развертывания означает, что он будет создан в определенном порядке. В этом режиме вы также должны задать свойство batchSize, чтобы определить, сколько ресурсов развертывается в этом режиме. Новый пакет запустить не удастся до завершения предыдущего. Это необходимо, чтобы ограничить то, что можно использовать в рабочей среде, например, когда может быть важно ограничить количество затронутых ресурсов в любой точке.
  • Параллельно. Этот режим является режимом развертывания по умолчанию. Его преимущества — высокая пропускная способность, поэтому шаблон обрабатывается быстрее. Недостатком же является то, что вы не можете гарантировать порядок и он может быть совсем не тем, что вам нужно для рабочей среды.

Зависимости

В контексте элемента copy необходимо указать ресурс и зависимость ожидаемого раздела. Эту зависимость можно выполнить, обратившись к ней по имени с помощью следующего кода JSON:

"resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-04-01",
      "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "copy": {
        "name": "storagecopy",
        "count": 3
      },
      "properties": {}
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2015-06-15",
      "name": "[concat('VM', uniqueString(resourceGroup().id))]",
      "dependsOn": ["storagecopy"],
    }
  ]

Обратите внимание, что элемент copy имеет свойство name со значением storagecopy. Зависимый ресурс (учетная запись) хранения ожидает завершения операции элемента copy. Это выражается с помощью "dependsOn": ["storagecopy"].

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