linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/kb/Основы Terraform/tf-functions-collection

kb/core ── Основы Terraform ── beginner

Функции коллекций HCL: length, lookup, merge, concat, flatten

Для list/set/map в HCL есть функции: length (размер), lookup (по ключу с default), merge (объединить map), concat (склеить list), flatten (раскрыть), keys/values. Базовый инструментарий трансформаций.

view as markdown

length, размер коллекции

Работает на list, set, map и string:

hcl
length(["a", "b", "c"])              # 3
length(toset(["a", "b", "b"]))       # 2 (дубликат убирается)
length({a = 1, b = 2})               # 2
length("hello")                       # 5

Полезно для условий и валидации:

hcl
validation {
  condition     = length(var.azs) >= 2
  error_message = "Минимум 2 availability zone."
}

lookup, значение по ключу с default

hcl
lookup({a = 1, b = 2}, "a")           # 1
lookup({a = 1, b = 2}, "missing")     # ошибка
lookup({a = 1, b = 2}, "missing", 0)  # 0 (третий арг = default)

Третий аргумент, fallback, если ключ не найден. Без него lookup упадёт. На практике почти всегда дают default.

Современный шорткат, map["key"]:

hcl
var.tags["Environment"]          # как lookup, но без default, упадёт если нет
try(var.tags["Environment"], "")  # с default через try

merge, объединение map

Несколько map'ов в один, последующие перекрывают предыдущие:

hcl
merge(
  { Project = "demo", Owner = "team" },
  { Owner = "platform", Env = "prod" }
)
# {
#   Project = "demo"
#   Owner   = "platform"   # перебито
#   Env     = "prod"
# }

Главный кейс, common_tags + специфичные:

hcl
locals {
  common_tags = { Project = var.project, ManagedBy = "terraform" }
}
resource "aws_s3_bucket" "logs" {
  bucket = "logs-bucket"
  tags = merge(local.common_tags, {
    Purpose = "logs"
  })
}

concat, склейка list

hcl
concat(["a", "b"], ["c", "d"])           # ["a", "b", "c", "d"]
concat(var.base_cidrs, var.extra_cidrs)  # склейка двух списков CIDR

Порядок сохраняется. Дубликаты не убираются (если нужно, заверните в distinct).

flatten, раскрыть вложенные list

Часто результат for-expression или нескольких concat, массив массивов. flatten делает плоский список:

hcl
flatten([["a", "b"], ["c"], [], ["d", "e"]])
# ["a", "b", "c", "d", "e"]

Типичный кейс: собрать все IP всех инстансов всех групп:

hcl
locals {
  all_private_ips = flatten([
    for asg in aws_autoscaling_group.tiers : asg.target_group_arns
  ])
}

Раскрывает только один уровень. Если внутри есть ещё вложения, flatten(flatten(...)).

keys, values, части map

hcl
keys({a = 1, b = 2, c = 3})       # ["a", "b", "c"]  (отсортированы по ключу)
values({a = 1, b = 2, c = 3})     # [1, 2, 3]         (в том же порядке)

keys всегда возвращает отсортированный список, это удобно для стабильных результатов в plan.

contains, проверка наличия

hcl
contains(["dev", "staging", "prod"], var.env)
# true / false

Самая частая роль, в validation:

hcl
validation {
  condition     = contains(["dev", "staging", "prod"], var.env)
  error_message = "env должен быть dev/staging/prod."
}

Для map нет contains. Используйте contains(keys(map), "k") или try(map["k"], null) != null.

distinct, убрать дубликаты

hcl
distinct(["a", "b", "a", "c", "b"])   # ["a", "b", "c"]

Порядок сохраняется (первое вхождение). Альтернатива, toset(...), но toset теряет порядок.

element и slice

hcl
element(["a", "b", "c"], 1)       # "b"
element(["a", "b", "c"], 5)       # "c", wraps around: 5 % 3 = 2
slice(["a", "b", "c", "d"], 1, 3) # ["b", "c"], [start, end)

element оборачивается по модулю, это специфика. Если нужна жёсткая ошибка при выходе за границы, используйте list[index].

zipmap, собрать map из двух list

hcl
zipmap(["a", "b", "c"], [1, 2, 3])
# {a = 1, b = 2, c = 3}

Длины должны совпадать, иначе ошибка.

for-expression, мощнее всех функций

hcl
# list → list
[for s in ["dev", "prod"] : upper(s)]
# ["DEV", "PROD"]
# list → map
{ for s in ["dev", "prod"] : s => "bucket-${s}" }
# {dev = "bucket-dev", prod = "bucket-prod"}
# с фильтром
[for s in var.envs : s if s != "test"]

for-expression покрывает большинство трансформаций. Многие из встроенных функций (keys, values, иногда merge) могут быть переписаны через for.

Подводные камни

  • merge плоский. Если значения сами map'ы, они перезаписываются, не сливаются. Для глубокого merge, несколько merge или вручную через for-expression.

  • concat не дедуплицирует. Если нужно объединить и убрать дубли, distinct(concat(a, b)).

  • lookup без default, взрыв. Всегда указывайте третий аргумент или используйте try().

  • flatten идёт на один уровень. Двойная вложенность, flatten(flatten(arr)).

  • keys сортирует, это хорошо для стабильности. Если нужен оригинальный порядок ключей map, это in вообще проблема, потому что HCL-map неупорядочен по природе. Используйте список объектов.

  • element оборачивается, а list[index], нет. element(arr, 999) даст результат по модулю. arr[999] упадёт. Для безопасной выборки, try(arr[index], default).

  • contains строго типизирован. contains([1, 2, 3], "1") упадёт, "1" это string, 1 это number. Приведите типы явно.

  • for с map требует уникальных ключей. { for s in arr : key_func(s) => ... }, если key_func даст одинаковый ключ для двух элементов, упадёт. Лечится for ... if cond или сменой ключа.

§ команды

bash
terraform console

Лучший способ изучить функции коллекций. Введи `merge({a=1},{b=2})` и сразу увидишь результат.

bash
echo 'flatten([[1,2],[3,4]])' | terraform console

Быстрая проверка в одну строку из shell.

bash
terraform validate

Проверка типов в выражениях: упадёт без обращения к облаку, если concat смешал несовместимые типы.

§ см. также

  • tf-functions-stringСтроковые функции HCL: format, join, replace, lower и другиеВ HCL функции для строк: format (как printf), join/split (массивы↔строки), replace (regex или текст), lower/upper/title (регистр), trimspace и trim*. Все pure, без побочных эффектов, удобны в locals.
  • tf-interpolation${...}: подстановка значений в строки${expression} внутри строки: подстановка значения выражения. ${var.env}, ${aws_s3_bucket.demo.id}. Если выражение. Это единственное значение аргумента (без обёртки в строку), современный HCL разрешает писать без ${...}.
  • tf-localslocals: вычисляемые внутренние именаlocals: блок с именами, видимыми только внутри HCL (не вход, не выход). Удобны для DRY: один раз сосчитал общий префикс или теги: везде используешь через local.x. Не путать с variable (вход) и output (выход).
  • hcl-typesТипы данных в HCL: string, number, list, map, objectHCL поддерживает примитивы (string, number, bool) и сложные типы: list, set, map, tuple, object. Эта статья, про синтаксис каждого и про разницу между похожими (list vs tuple, map vs object): meta_description: "Типы данных HCL: string, number, bool, list, set, map, tuple, object. Что выбрать для variable, где разница между list и tuple, синтаксис каждого с примерами."
  • tf-count-for-eachcount и for_each: несколько ресурсов из одного блокаcount создаёт N одинаковых ресурсов по индексам 0..N-1. for_each: ресурсы по ключам из set или map. Правило: count для одинаковых, for_each когда у каждого свои настройки. Если сомневаешься, бери for_each.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки