Spec-Zone.ru › OpenTofu 1.12

dynamic Блоки

В конструкциях блоков верхнего уровня, таких как ресурсы, выражения обычно можно использовать только при присваивании значения аргументу с помощью формы name = expression. Это охватывает многие случаи использования, но некоторые типы ресурсов включают в аргументы повторяющиеся вложенные блоки, которые обычно представляют отдельные объекты, связанные с содержащим их объектом (или встроенные в него):

Блок кода
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
  name = "tf-test-name" # can use expressions here

  setting {
    # but the "setting" block is always a literal block
  }
}

Вы можете динамически создавать повторяющиеся вложенные блоки, например setting, с помощью специального типа блока dynamic, который поддерживается внутри блоков resource, data, provider и provisioner:

Блок кода
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
  name                = "tf-test-name"
  application         = "${aws_elastic_beanstalk_application.tftest.name}"
  solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6"

  dynamic "setting" {
    for_each = var.settings
    content {
      namespace = setting.value["namespace"]
      name = setting.value["name"]
      value = setting.value["value"]
    }
  }
}

Блок dynamic работает во многом как выражение for, но создает вложенные блоки, а не сложное типизированное значение. Он перебирает заданное сложное значение и создает вложенный блок для каждого элемента этого значения.

  • Метка динамического блока ("setting" в примере выше) указывает, какой тип вложенного блока нужно создать.
  • Аргумент for_each задает сложное значение для перебора.
  • Аргумент iterator (необязательный) задает имя временной переменной, представляющей текущий элемент сложного значения. Если этот аргумент не указан, имя переменной по умолчанию совпадает с меткой блока dynamic ("setting" в примере выше).
  • Аргумент labels (необязательный) — это список строк, задающий метки блоков в том порядке, в котором их следует использовать для каждого создаваемого блока. В этом значении можно использовать временную переменную итератора.
  • Вложенный блок content определяет тело каждого создаваемого блока. Внутри этого блока можно использовать временную переменную итератора.

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

Объект итератора (setting в примере выше) имеет два атрибута:

  • key — это ключ карты или индекс элемента списка для текущего элемента. Если выражение for_each создает значение типа set, то key идентичен value и его не следует использовать.
  • value — это значение текущего элемента.

Блок dynamic может создавать только аргументы, относящиеся к настраиваемому типу ресурса, источнику данных, провайдеру или провижионеру. Создавать блоки метааргументов, такие как блоки lifecycle и provisioner, невозможно, поскольку OpenTofu должен обработать их до того, как станет безопасно вычислять выражения.

Значение for_each должно быть коллекцией, содержащей по одному элементу для каждого требуемого вложенного блока. Если вам нужно объявить экземпляры ресурсов на основе вложенной структуры данных или сочетаний элементов из нескольких структур данных, вы можете использовать выражения и функции OpenTofu, чтобы получить подходящее значение. Примеры некоторых распространенных ситуаций см. в описании функций flatten и setproduct.

Многоуровневые структуры вложенных блоков​

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

Например, модуль может принимать сложную структуру данных, подобную следующей:

Блок кода
variable "load_balancer_origin_groups" {
  type = map(object({
    origins = set(object({
      hostname = string
    }))
  }))
}

Если вы определяете ресурс, тип которого ожидает блок для каждой группы источников, а затем вложенные блоки для каждого источника в группе, вы можете попросить OpenTofu динамически создать такую структуру с помощью следующих вложенных блоков dynamic:

Блок кода
  dynamic "origin_group" {
    for_each = var.load_balancer_origin_groups
    content {
      name = origin_group.key

      dynamic "origin" {
        for_each = origin_group.value.origins
        content {
          hostname = origin.value.hostname
        }
      }
    }
  }

При использовании вложенных блоков dynamic особенно важно обращать внимание на символ итератора каждого блока. В примере выше origin_group.value обозначает текущий элемент внешнего блока, а origin.value — текущий элемент внутреннего блока.

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

Рекомендации по использованию блоков dynamic​

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

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

Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.12/language/expressions/dynamic-blocks/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API