Spec-Zone.ru › OpenTofu 1.11

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 возвращает значение типа множество, то 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 — текущий элемент внутреннего блока.

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

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

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

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

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

Spec-Zone.ru

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