Гид по технологиям

Циклы в Terraform: count, for и for_each — практическое руководство

• 6 min read • Инфраструктура • Обновлено 25 Nov 2025
Циклы в Terraform: count, for и for_each
Циклы в Terraform: count, for и for_each

Сетевые компоненты и инфраструктура в облаке

Введение

Сетевые и облачные инфраструктуры — ключевые элементы современной ИТ-среды. Перенос рабочей нагрузки в облако упростил масштабирование, но также потребовал автоматизации управления ресурсами. Terraform — один из наиболее популярных инструментов для описания и управления облачной инфраструктурой через код (IaC). Эта статья подробно рассматривает доступные в Terraform способы повторения (loops) ресурсов и блоков конфигурации, объясняет отличия между ними и даёт практические рекомендации.

Важно: под «повторениями» мы понимаем приём создания нескольких сходных ресурсов или блоков конфигурации на основе коллекций данных.

Что такое Terraform (кратко)

Terraform — это Open Source-инструмент от HashiCorp для декларативного описания инфраструктуры. Конфигурации пишут на HCL (HashiCorp Configuration Language). Terraform сравнивает текущее состояние (state) и желаемое состояние конфигурации и вносит только необходимые изменения.

Ключевые термины: state — файл состояния (JSON), провайдер — плагин для взаимодействия с API облачного или корпоративного сервиса.

Почему важно понимать циклы в Terraform

Использование циклов помогает:

  • уменьшить дублирование кода;
  • управлять наборами ресурсов как единой сущностью;
  • переложить логику генерации имён и параметров на конфигурацию, а не на ручные сценарии.

Но неправильное применение циклов приводит к неожиданной замене ресурсов, конфликтам ключей и проблемам с источником правды (state).

Обзор доступных механизмов

Terraform предоставляет три основных способа повторений:

  • count — создаёт N копий ресурса или модуля;
  • выражение for — трансформирует коллекции (list/map/object) в другие коллекции;
  • for_each — создаёт один экземпляр ресурса на каждый элемент множества или мапы.

Ниже — подробные объяснения и примеры.


1. Параметр count

Описание: count — целочисленный аргумент ресурса/модуля. Если count = N, Terraform создаст N экземпляров. Для изменения конфигурации на уровне экземпляра используют объект count и его атрибут index (начинается с 0).

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

Пример — создание 5 одинаковых EC2-инстансов (упрощённый HCL):

resource "aws_instance" "web-ec2" {
  count         = 5
  ami           = "ami-xxxx"
  instance_type = "t2.micro"
}

Выходной фрагмент плана:

Plan: 5 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
Enter a value:

Если нужно пронумеровать ресурсы и задать уникальные теги/имена, используйте count.index:

resource "aws_instance" "web-ec2" {
  count         = 5
  ami           = "ami-xxxx"
  instance_type = "t2.micro"

  tags = {
    Name = "my-server-${count.index}"
  }
}

Результат: экземпляры с именами my-server-0 .. my-server-4.

Пример использования count для EC2-инстансов с нумерацией

Важно: изменение значения count может привести к удалению или пересозданию элементов с целым смещением индексов. Планируйте миграцию и используйте lifecycle или create_before_destroy при необходимости.


2. Выражение for

Описание: выражение for (не путать с for_each) применяется в выражениях и шаблонах для трансформации коллекций в новые коллекции (list/map). Синтаксис:

[for  in  : ]

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

Пример — вернуть элементы в верхнем регистре:

variable "demo" {
  description = "A list of items"
  type        = list(string)
  default     = ["one", "two", "three"]
}

output "upper_case" {
  value = [for name in var.demo : upper(name)]
}

Выражения for можно комбинировать с условными фильтрами внутри (например, for … if …).


3. for_each

Описание: for_each позволяет итеративно создавать ресурсы на основе множества (set) или мапы (map). Для каждой пары ключ/значение создаётся отдельный экземпляр, доступный через специальный объект each (each.key, each.value).

Когда использовать: когда требуется однозначная привязка элементов коллекции к создаваемым ресурсам и когда важно, чтобы добавление/удаление элемента не смещало другие ресурсы (в отличие от count/index).

Пример — создание IAM-пользователей из списка:

resource "aws_iam_user" "iam_accounts" {
  for_each = toset(["tecofers", "HowToForge", "Demo"])
  name     = each.key
}

Пояснение: toset() конвертирует список в набор; each.key — ключ набора/мапы для конкретного экземпляра, each.value — соответствующее значение.

Примечание: одновременно использовать count и for_each внутри одного и того же ресурса нельзя.


Сравнение: когда count, а когда for_each

  • count удобен, когда экземпляры полностью идентичны и их порядок/индексы не критичны.
  • for_each нужен, когда наборы имеют уникальные ключи или вы хотите избежать смещения при удалении/добавлении элементов.
  • for (expression) — для трансформации коллекций, но не для создания ресурсов напрямую.

Таблица-Шпаргалка (коротко):

  • count = N => инстансы с count.index
  • for_each = { key = value } / set => each.key / each.value
  • [for x in list : expr] => трансформирует коллекцию

Подводные камни и случаи, когда подходы не работают

  1. Смещение индексов при count: если вы удаляете элемент из середины списка, индексы всех последующих изменятся — Terraform может удалить и пересоздать ресурсы.
  2. for_each требует уникальных ключей: если ваша коллекция содержит дубликаты без явных ключей, преобразуйте её в map с уникальными ключами.
  3. Динамически вычисляемые коллекции, зависящие от ресурсов, могут приводить к циклическим зависимостям.
  4. Ресурсы, созданные вручную вне Terraform, могут конфликтовать со state — избегайте смешивания источников управления.

Альтернативные подходы и когда их применять

  • Используйте модули для повторно используемых шаблонов с параметрами, вместо копирования большого числа ресурсов.
  • dynamic blocks внутри ресурса подходят для создания повторяющихся вложенных блоков (например, security_group_rule).
  • Для конфигураций уровня провайдера можно использовать нативные шаблоны (CloudFormation, ARM) там, где Terraform не даёт нужной гибкости.
  • Ansible/Cloud-Init/packer — для пост-конфигурации виртуальных машин, а не для создания инфраструктуры.

Практическая методология внедрения повторений (мини-процесс)

  1. Подготовка: имена, уникальные ключи, чёткая модель владения ресурсом.
  2. Локальное тестирование: terraform plan, review.
  3. Бэкап state и использование remote state (S3/GCS + блокировка).
  4. Пошаговый apply: использовать targets для поэтапного развёртывания.
  5. Мониторинг и проверка: убедиться, что ресурсы не пересоздаются без необходимости.

Контрольные списки по ролям

DevOps / Инженер по инфраструктуре:

  • Определить, какой метод повторения подходит (count vs for_each).
  • Проверить уникальность ключей для for_each.
  • Подготовить план миграции при смене метода.

SRE / Операции:

  • Создать snapshot/бэкап state перед массовыми изменениями.
  • Проверить impact на идентификаторы ресурсов и зависимости.

Разработчик приложения:

  • Согласовать имена/теги ресурсов, ожидаемые приложением.
  • Проверить, что конфигурация не ломает SD (service discovery).

Команда безопасности:

  • Убедиться в применении корректных IAM/ACL при генерации множества аккаунтов/прав.

Чек-лист «Шпаргалка» (quick cheat sheet)

  • Нужно N одинаковых ресурсов и порядок не важен? Рассмотрите count.
  • Нужно стабильно связывать элемент коллекции с ресурсом? Используйте for_each (map или set).
  • Нужно получить новую коллекцию — используйте выражение for.
  • Изменение count может вызвать пересоздание — проверьте plan.
  • Для вложенных повторений используйте dynamic blocks.

Модель мышления (heuristics)

  • «Желаемое состояние» как цель: создавайте конфигурацию так, чтобы она выражала конечный результат, а не шаги.
  • «Идентичность важнее порядка»: если важна идентичность ресурса во времени, используйте ключи (for_each), а не индексы.
  • «Минимизируй деструктивность»: перед крупными изменениями делайте бэкап и прогоняйте plan с коллегой.

Decision flow (простое дерево решений)

flowchart TD
  A{Нужно создать несколько похожих ресурсов?} -->|Нет| B[Используйте одиночный ресурс]
  A -->|Да| C{Есть ли у элементов уникальные идентификаторы?}
  C -->|Да| D[Используйте for_each с map/set]
  C -->|Нет| E{Порядок и индекс важен?}
  E -->|Да| F[Используйте count с индексом]
  E -->|Нет| D

Критерии приёмки

  • terraform plan показывает ожидаемое количество создаваемых/изменяемых ресурсов.
  • Изменение коллекции не приводит к неожиданной пересоздаче критичных ресурсов.
  • Каждому создаваемому ресурсу назначен понятный уникальный идентификатор (ключ/тег).
  • State хранится надёжно и доступ к нему ограничен.

Короткий словарь (1 строка термина)

  • count — целочисленный счётчик для создания N экземпляров.
  • count.index — индекс текущего экземпляра (0..N-1).
  • for_each — повторение на основе множества или мапы, даёт each.key/each.value.
  • for (expression) — трансформация коллекций в другие коллекции.
  • state — файл состояния Terraform, источник правды о созданных ресурсах.

Заключение

Повторения в Terraform — мощный инструмент для уменьшения дублирования и управления множеством ресурсов. Выбор между count и for_each зависит от требований к идентичности и устойчивости ресурсов при изменениях. Выражения for полезны для преобразования данных. Всегда прогоняйте terraform plan, делайте резервные копии state и документируйте принятые решения.

Краткое резюме:

  • count — прост и полезен для одинаковых экземпляров;
  • for_each — безопаснее для коллекций с уникальными ключами;
  • выражения for — для преобразования коллекций.

Источники и дополнительные материалы:

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро