You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
terraform-provider-dynamix/wiki/1.0.1/05.04-Массовое-создание-рес...

22 KiB

Иногда требуется создать несколько ресурсов, которые будут отличаться незначительными изменениями (например, имя).
В terraform имеются специальные мета-аргументы, которые позволяют описать данную инфраструктуру максимально быстро, избегая повторений блоков.
Однако, при таком подходе стоит учитывать то, что созданная при помощи такого подхода инфраструктура является неким "монолитом" и любые изменения будут применятся для всех ресурсов, которые были созданы с помощью мета аргументов.

ВНИМАНИЕ: СОЗДАННЫЕ ТАКИМ ОБРАЗОМ РЕСУРСЫ, УПРАВЛЯЮТСЯ КАК ОДИН РЕСУРС

Создание дисков. Обычный вариант

Предположим, что необходимо создать несколько дисков, которые будут иметь одинаковые поля, а отличаться только именем.
Тогда, будут использованы несколько блоков resource с описанием данных ресурсов:

resource "dynamix_disk" "disk1" {
  account_id  = 777
  disk_name   = "disk-1"
  size_max    = 10
  gid         = 212
}

resource "dynamix_disk" "disk2" {
  account_id  = 777
  disk_name   = "disk-2"
  size_max    = 10
  gid         = 212
}

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

Рефакторинг

Вынесем значения имен дисков в блок locals:

locals {
 disk_names = [
   "disk-1",
   "disk-2",
  ]
}

resource "dynamix_disk" "disk1" {
  account_id  = 777
  disk_name   = "disk-1"
  size_max    = 10
  gid         = 212
}

resource "dynamix_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, в которую, при каждой итерации будут ключи (если итерация идет по набору строк), либо ключи и соответствующие им значения, если итерация идет по объекту. Обратиться к ним можно через символ ".", например:

each.key
each.value

Таким образом, конфигурирование одинаковых ресурсов сократится до одного. При добавлении в код выше, получится:

locals {
  disk_names = [
    "disk-1",
    "disk-2",
  ]
}

#обратите внимание, что ресурс был переименован
resource "dynamix_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 = dynamix_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 можно по сл. схеме:

<resource_type>.<resource_name>["<key>"]

Пример получения доступа к ресурсу disk-2:

dynamix_disk.disks["disk-2"]

Чтобы получить доступ к полям, которые содержит ресурс:

<resource_type>.<resource_name>["<key>"].<field_name>

Например, для получения account_id для disk-2:

dynamix_disk.disks["disk-2"].account_id

Использование for_each для более сложной конфигурации

Иногда, необходимо объединить несколько ресурсов с разной конфигурацией в один ресурс, с помощью for_each. Для того, чтобы это сделать, необходимо воспользоваться функцией for для перебора информации о каждом ресурсе, в котором так же необходимо указать какое из полей будет указывать на определенный ресурс. Рассмотрим более сложный пример создания нескольких дисков:

#создание массива из объектов, описывающих инфраструктуру
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 "dynamix_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 принимает на вход либо число, либо выражение, которое возвращает число.
Число - количество итерацией, которые предстоит произвести. Например:

count = 3
count = length(some_data)

Рассмотрим пример:

#без изменений
locals {
  disk_names = [
    "disk-1",
    "disk-2",
  ]
}

#без изменений, ресурс так же называется - "disks"
resource "dynamix_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 = dynamix_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 можно по сл. схеме:

<resource_type>.<resource_name>[<index>]

Пример получения доступа к ресурсу disk-2:

dynamix_disk.disks[1]

Чтобы получить доступ к полям, которые содержит ресурс:

<resource_type>.<resource_name>[<index>].<field_name>

Например, для получения account_id для disk-2:

dynamix_disk.disks[1].account_id

Использование count для более сложной конфигурации

Иногда, необходимо объединить несколько ресурсов с разной конфигурацией в один ресурс, с помощью count. Для того, чтобы это сделать, необходимо воспользоваться функцией length для установления длины входящих параметров. После чего, обращаться к ним, получая значения, используя индекс. Рассмотрим более сложный пример создания нескольких дисков:

#создание массива из объектов, описывающих инфраструктуру
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 "dynamix_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
}

Таким образом, будут созданы ресурсы, с разной конфигурацией.