Spec-Zone.ru › OpenTofu 1.12

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.12/language/expressions/for/

Spec-Zone.ru

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