Создание нескольких экземпляров ресурсов с помощью 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 переключается в режим последовательного развертывания между этими двумя ресурсами. Это может повлиять на скорость развертывания, но вы указали, что вас интересует определенный порядок развертывания, который теперь имеет более высокий приоритет.