Spec-Zone.ru › OpenTofu 1.11

for Выражения

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

Например, если var.list — это список строк, следующее выражение создаст кортеж строк, состоящих только из заглавных букв:

Блок кода
[for s in var.list : upper(s)]

Это выражение for перебирает каждый элемент var.list, а затем вычисляет выражение upper(s), устанавливая s равным соответствующему элементу. Затем оно создает новое значение-кортеж, содержащее результаты выполнения этого выражения в том же порядке.

Типы входных данных​

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

В приведенном выше примере показано выражение for только с одним временным символом s, однако выражение for может объявлять пару временных символов, чтобы использовать также ключ или индекс каждого элемента:

Блок кода
[for k, v in var.map : length(k) + length(v)]

Для типа «карта» или «объект», как в примере выше, символ k обозначает ключ или имя атрибута текущего элемента. Двухсимвольную форму можно использовать и со списками и кортежами. В этом случае дополнительный символ обозначает индекс каждого элемента, начиная с нуля; обычно ему присваивают имя i или idx, если только более конкретное имя не будет уместнее:

Блок кода
[for i, v in var.list : "${i} is ${v}"]

Символ индекса или ключа всегда необязателен. Если после ключевого слова for указан только один символ, он всегда будет обозначать значение каждого элемента входной коллекции.

Типы результатов​

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

В приведенном выше примере используются [ и ], в результате чего создается кортеж. Если вместо них использовать { и }, результатом будет объект, для которого нужно указать два выражения результата, разделенные символом =>:

Блок кода
{for s in var.list : s => upper(s)}

Это выражение создает объект, атрибутами которого являются исходные элементы из var.list, а соответствующими значениями — их версии в верхнем регистре. Например, результат может выглядеть так:

Блок кода
{
  foo = "FOO"
  bar = "BAR"
  baz = "BAZ"
}

Само по себе выражение for может создавать только значение-объект или значение-кортеж, однако благодаря правилам автоматического преобразования типов в OpenTofu результаты обычно можно использовать там, где ожидаются списки, карты и множества.

Фильтрация элементов​

Выражение for может также содержать необязательное предложение if для фильтрации элементов исходной коллекции. В результате будет получено значение, содержащее меньше элементов, чем исходное:

Блок кода
[for s in var.list : upper(s) if s != ""]

Одна из распространенных причин фильтрации коллекций в выражениях for — разделение одной исходной коллекции на две отдельные по заданному критерию. Например, если входное значение var.users — это карта объектов, каждый из которых имеет атрибут is_admin, может потребоваться создать отдельные карты для объектов с правами администратора и без них:

Блок кода
variable "users" {
  type = map(object({
    is_admin = bool
  }))
}

locals {
  admin_users = {
    for name, user in var.users : name => user
    if user.is_admin
  }
  regular_users = {
    for name, user in var.users : name => user
    if !user.is_admin
  }
}

Порядок элементов​

Поскольку выражения for могут преобразовывать неупорядоченные типы (карты, объекты, множества) в упорядоченные (списки, кортежи), OpenTofu должен задавать порядок элементов неупорядоченной коллекции.

В картах и объектах OpenTofu сортирует элементы по ключу или имени атрибута в лексикографическом порядке.

В множествах строк OpenTofu сортирует элементы по их значениям в лексикографическом порядке.

Для множеств других типов OpenTofu использует произвольный порядок, который может измениться в будущих версиях. Рекомендуем преобразовывать результат выражения в множество, чтобы в других местах конфигурации было ясно, что результат не упорядочен. Для краткого преобразования результата выражения for в значение типа «множество» можно использовать функцию toset.

Блок кода
toset([for e in var.set : e.example])

Группировка результатов​

Если тип результата — объект (с разделителями { и }), то обычно заданное выражение ключа должно давать уникальное значение для каждого элемента результата, иначе OpenTofu вернет ошибку.

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

Чтобы включить режим группировки, добавьте символ ... после выражения значения. Например:

Блок кода
variable "users" {
  type = map(object({
    role = string
  }))
}

locals {
  users_by_role = {
    for name, user in var.users : user.role => name...
  }
}

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

Выражение local.users_by_role инвертирует входную карту: ключами становятся имена ролей, а значениями — имена пользователей. Однако выражение работает в режиме группировки (благодаря символу ... после name), поэтому в результате будет карта списков строк, например:

Блок кода
{
  "admin": [
    "ps",
  ],
  "maintainer": [
    "am",
    "jb",
    "kl",
    "ma",
  ],
  "viewer": [
    "st",
    "zq",
  ],
}

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

Повторяющиеся блоки конфигурации​

Механизм выражений for предназначен для создания значений-коллекций из других значений-коллекций в выражениях. Затем эти значения можно присвоить отдельным аргументам ресурсов, ожидающим значения сложных типов.

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

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

Spec-Zone.ru

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