diff --git a/05.04-Массовое-создание-ресурсов.-Мета-аргументы.md b/05.04-Массовое-создание-ресурсов.-Мета-аргументы.md new file mode 100644 index 0000000..c341e8f --- /dev/null +++ b/05.04-Массовое-создание-ресурсов.-Мета-аргументы.md @@ -0,0 +1,452 @@ +Иногда требуется создать несколько ресурсов, которые будут отличаться незначительными изменениями (например, имя). +В terraform имеются специальные мета-аргументы, которые позволяют описать данную инфраструктуру максимально быстро, избегая повторений блоков. +Однако, при таком подходе стоит учитывать то, что созданная при помощи такого подхода инфраструктура является неким "монолитом" и любые изменения будут применятся для всех ресурсов, которые были созданы с помощью мета аргументов. + +__ВНИМАНИЕ: СОЗДАННЫЕ ТАКИМ ОБРАЗОМ РЕСУРСЫ, УПРАВЛЯЮТСЯ КАК ОДИН РЕСУРС__ + +## Создание дисков. Обычный вариант +Предположим, что необходимо создать несколько дисков, которые будут иметь одинаковые поля, а отличаться только именем. +Тогда, будут использованы несколько блоков resource с описанием данных ресурсов: +```terraform +resource "decort_disk" "disk1" { + account_id = 777 + disk_name = "disk-1" + size_max = 10 + gid = 212 +} + +resource "decort_disk" "disk2" { + account_id = 777 + disk_name = "disk-2" + size_max = 10 + gid = 212 +} +``` +Все блоки повторяются и отличаются только именем. Если не планируется изменение каждого ресурса по-отдельности, то можно вынести имена дисков в отдельную переменную, и считывать их из нее. +## Рефакторинг +Вынесем значения имен дисков в блок locals: +```terraform +locals { + disk_names = [ + "disk-1", + "disk-2", + ] +} + +resource "decort_disk" "disk1" { + account_id = 777 + disk_name = "disk-1" + size_max = 10 + gid = 212 +} + +resource "decort_disk" "disk2" { + account_id = 777 + disk_name = "disk-2" + size_max = 10 + gid = 212 +} +``` +Оставшиеся блоки resource идентичны друг другу, за исключением наименования ресурса, поэтому, их создание и работу с ними можно объединить. +## Мета аргумент for_each +Мета аргумент for_each служит для итерации по набору (set) строки, либо по мапе (map, object). Результатом работы этого мета аргумента станет так же объект, ключами которого будут либо строки, входящие в набор, либо параметры, указанные при итерировании объекта. +Мета аргумент for_each предоставляет переменную each, в которую, при каждой итерации будут ключи (если итерация идет по набору строк), либо ключи и соответствующие им значения, если итерация идет по объекту. +Обратиться к ним можно через символ ".", например: +```terraform +each.key +each.value +``` +Таким образом, конфигурирование одинаковых ресурсов сократится до одного. +При добавлении в код выше, получится: +```terraform +locals { + disk_names = [ + "disk-1", + "disk-2", + ] +} + +#обратите внимание, что ресурс был переименован +resource "decort_disk" "disks" { + #преобразование массива к набору строк для успешной работы for_each + for_each = toset(local.disk_names) + account_id = 777 + #получение имени диска из переменной each + disk_name = each.key + size_max = 10 + gid = 212 +} + +#блок output демонстрирует вывод работы на экран +output "test" { + value = decort_disk.disks +} +``` +При выполнении данной конфигурации в terraform output будет следующее: +``` +Changes to Outputs: + + test = { + + disk-1 = { + + account_id = 777 + + account_name = (known after apply) + + acl = (known after apply) + + boot_partition = (known after apply) + + compute_id = (known after apply) + + compute_name = (known after apply) + + created_time = (known after apply) + + deleted_time = (known after apply) + + desc = (known after apply) + + destruction_time = (known after apply) + + detach = false + + devicename = (known after apply) + + disk_id = (known after apply) + + disk_name = "disk-1" + + disk_path = (known after apply) + + gid = 212 + + guid = (known after apply) + + id = (known after apply) + + image_id = (known after apply) + + images = (known after apply) + + iotune = (known after apply) + + iqn = (known after apply) + + login = (known after apply) + + milestones = (known after apply) + + order = (known after apply) + + params = (known after apply) + + parent_id = (known after apply) + + passwd = (known after apply) + + pci_slot = (known after apply) + + permanently = false + + pool = (known after apply) + + purge_attempts = (known after apply) + + purge_time = (known after apply) + + reality_device_number = (known after apply) + + reason = null + + reference_id = (known after apply) + + res_id = (known after apply) + + res_name = (known after apply) + + restore = false + + role = (known after apply) + + sep_id = (known after apply) + + sep_type = (known after apply) + + size_max = 10 + + size_used = (known after apply) + + snapshots = (known after apply) + + status = (known after apply) + + tech_status = (known after apply) + + timeouts = null + + type = (known after apply) + + vmid = (known after apply) + } + + disk-2 = { + + account_id = 777 + + account_name = (known after apply) + + acl = (known after apply) + + boot_partition = (known after apply) + + compute_id = (known after apply) + + compute_name = (known after apply) + + created_time = (known after apply) + + deleted_time = (known after apply) + + desc = (known after apply) + + destruction_time = (known after apply) + + detach = false + + devicename = (known after apply) + + disk_id = (known after apply) + + disk_name = "disk-2" + + disk_path = (known after apply) + + gid = 212 + + guid = (known after apply) + + id = (known after apply) + + image_id = (known after apply) + + images = (known after apply) + + iotune = (known after apply) + + iqn = (known after apply) + + login = (known after apply) + + milestones = (known after apply) + + order = (known after apply) + + params = (known after apply) + + parent_id = (known after apply) + + passwd = (known after apply) + + pci_slot = (known after apply) + + permanently = false + + pool = (known after apply) + + purge_attempts = (known after apply) + + purge_time = (known after apply) + + reality_device_number = (known after apply) + + reason = null + + reference_id = (known after apply) + + res_id = (known after apply) + + res_name = (known after apply) + + restore = false + + role = (known after apply) + + sep_id = (known after apply) + + sep_type = (known after apply) + + size_max = 10 + + size_used = (known after apply) + + snapshots = (known after apply) + + status = (known after apply) + + tech_status = (known after apply) + + timeouts = null + + type = (known after apply) + + vmid = (known after apply) + } + } + +``` +После подтверждения команды, будет создан файл состояния инфраструктуры, в который запишутся данные. +### Обращение к конфигурации, созданной с помощью for_each +Получить доступ к ресурсам, созданным с помощью for_each можно по сл. схеме: +``` +.[""] +``` +Пример получения доступа к ресурсу disk-2: +``` +decort_disk.disks["disk-2"] +``` +Чтобы получить доступ к полям, которые содержит ресурс: +``` +.[""]. +``` +Например, для получения account_id для disk-2: +``` +decort_disk.disks["disk-2"].account_id +``` +### Использование for_each для более сложной конфигурации +Иногда, необходимо объединить несколько ресурсов с разной конфигурацией в один ресурс, с помощью for_each. Для того, чтобы это сделать, необходимо воспользоваться функцией for для перебора информации о каждом ресурсе, в котором так же необходимо указать какое из полей будет указывать на определенный ресурс. +Рассмотрим более сложный пример создания нескольких дисков: +```terraform +#создание массива из объектов, описывающих инфраструктуру +locals { + disks = [ + { + account_id = 777 + diskname = "test-disk" + disk2_gb = 100 + gid = 212 + }, + { + account_id = 778 + diskname = "test-disk-1" + disk2_gb = 200 + gid = 213 + } + ] +} + +resource "decort_disk" "disks" { + #цикл for проходит по каждому элементы списка, превращая его в объект, где + #ключом будет - имя диска + #знаяением - сам диск + for_each = { for disk in local.disks : disk.diskname => disk } + #получение account_id каждого диска + account_id = each.value.account_id + #шаблон задания имени диска + #так же, если не надо вносить изменения, можно использовать: + #disk_name = each.value.diskname + disk_name = "${each.value.diskname}-data" + #получение размера диска + size_max = each.value.disk2_gb + #получение gid диска + gid = each.value.gid +} +``` +Таким образом, будут созданы ресурсы с разной конфигурацией. +## Мета аргумент count +Мета аргумент count так же служит для множественного создания ресурсов, объединяя их в один, с тем лишь исключением, что это будет массив, а не объект. +Аргумент count принимает на вход либо число, либо выражение, которое возвращает число. +Число - количество итерацией, которые предстоит произвести. +Например: +```terraform +count = 3 +count = length(some_data) +``` +Рассмотрим пример: +```terraform +#без изменений +locals { + disk_names = [ + "disk-1", + "disk-2", + ] +} + +#без изменений, ресурс так же называется - "disks" +resource "decort_disk" "disks" { + #Используется функция length для подсчета длины списка имен дисков + count = length(local.disk_names) + account_id = 777 + #аргумент count имеет поле index, которое возвращает индекс(счетчик) текущей итерации + disk_name = local.disk_names[count.index] + size_max = 10 + gid = 212 +} + +output "test" { + value = decort_disk.disks +} +``` + +При выполнении данной конфигурации в terraform output будет следующее: +``` +Changes to Outputs: + + test = [ + + { + + account_id = 777 + + account_name = (known after apply) + + acl = (known after apply) + + boot_partition = (known after apply) + + compute_id = (known after apply) + + compute_name = (known after apply) + + created_time = (known after apply) + + deleted_time = (known after apply) + + desc = (known after apply) + + destruction_time = (known after apply) + + detach = false + + devicename = (known after apply) + + disk_id = (known after apply) + + disk_name = "disk-1" + + disk_path = (known after apply) + + gid = 212 + + guid = (known after apply) + + id = (known after apply) + + image_id = (known after apply) + + images = (known after apply) + + iotune = (known after apply) + + iqn = (known after apply) + + login = (known after apply) + + milestones = (known after apply) + + order = (known after apply) + + params = (known after apply) + + parent_id = (known after apply) + + passwd = (known after apply) + + pci_slot = (known after apply) + + permanently = false + + pool = (known after apply) + + purge_attempts = (known after apply) + + purge_time = (known after apply) + + reality_device_number = (known after apply) + + reason = null + + reference_id = (known after apply) + + res_id = (known after apply) + + res_name = (known after apply) + + restore = false + + role = (known after apply) + + sep_id = (known after apply) + + sep_type = (known after apply) + + size_max = 10 + + size_used = (known after apply) + + snapshots = (known after apply) + + status = (known after apply) + + tech_status = (known after apply) + + timeouts = null + + type = (known after apply) + + vmid = (known after apply) + }, + + { + + account_id = 777 + + account_name = (known after apply) + + acl = (known after apply) + + boot_partition = (known after apply) + + compute_id = (known after apply) + + compute_name = (known after apply) + + created_time = (known after apply) + + deleted_time = (known after apply) + + desc = (known after apply) + + destruction_time = (known after apply) + + detach = false + + devicename = (known after apply) + + disk_id = (known after apply) + + disk_name = "disk-2" + + disk_path = (known after apply) + + gid = 212 + + guid = (known after apply) + + id = (known after apply) + + image_id = (known after apply) + + images = (known after apply) + + iotune = (known after apply) + + iqn = (known after apply) + + login = (known after apply) + + milestones = (known after apply) + + order = (known after apply) + + params = (known after apply) + + parent_id = (known after apply) + + passwd = (known after apply) + + pci_slot = (known after apply) + + permanently = false + + pool = (known after apply) + + purge_attempts = (known after apply) + + purge_time = (known after apply) + + reality_device_number = (known after apply) + + reason = null + + reference_id = (known after apply) + + res_id = (known after apply) + + res_name = (known after apply) + + restore = false + + role = (known after apply) + + sep_id = (known after apply) + + sep_type = (known after apply) + + size_max = 10 + + size_used = (known after apply) + + snapshots = (known after apply) + + status = (known after apply) + + tech_status = (known after apply) + + timeouts = null + + type = (known after apply) + + vmid = (known after apply) + }, + ] +``` + +### Обращение к конфигурации, созданной с помощью сount +Получить доступ к ресурсам, созданным с помощью count можно по сл. схеме: +``` +.[] +``` +Пример получения доступа к ресурсу disk-2: +``` +decort_disk.disks[1] +``` +Чтобы получить доступ к полям, которые содержит ресурс: +``` +.[]. +``` +Например, для получения account_id для disk-2: +``` +decort_disk.disks[1].account_id +``` +### Использование count для более сложной конфигурации +Иногда, необходимо объединить несколько ресурсов с разной конфигурацией в один ресурс, с помощью count. Для того, чтобы это сделать, необходимо воспользоваться функцией length для установления длины входящих параметров. После чего, обращаться к ним, получая значения, используя индекс. +Рассмотрим более сложный пример создания нескольких дисков: +```terraform +#создание массива из объектов, описывающих инфраструктуру +locals { + disks = [ + { + account_id = 777 + diskname = "test-disk" + disk2_gb = 100 + gid = 212 + }, + { + account_id = 778 + diskname = "test-disk-1" + disk2_gb = 200 + gid = 213 + } + ] +} + +resource "decort_disk" "disks" { + #получение значения длины входящих параметров + count = length(local.disks) + #получение идентификатора аккаунта + account_id = local.disks[count.index].account_id + #получение имени диска + disk_name = "${local.disks[count.index].diskname}-data" + #получение размера диска + size_max = local.disks[count.index].disk2_gb + #получение gid + gid = local.disks[count.index].gid +} +``` +Таким образом, будут созданы ресурсы, с разной конфигурацией. \ No newline at end of file