Конвейер инфраструктурного кода и золотое правило Terraform

Рейтинг: 67.6% · 8 голосов
Подробный курс по Terraform и OpenTofu на примерах Yandex Cloud: ресурсы и провайдеры, состояние и бэкенды, модули, циклы и условия HCL, секреты и Lockbox, тестирование, CI/CD и командная работа. С актуализацией на 2026 (Terraform 1.3-1.10, OpenTofu).
Ответить
Аватара пользователя
Vlad_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Конвейер инфраструктурного кода и золотое правило Terraform

Сообщение Vlad_DevOps »

Оглавление курса (47)
  1. Что такое инфраструктура как код и зачем она нужна
  2. Категории инструментов IaC: чем отличаются Ansible, Packer, Kubernetes и Terraform
  3. Чем Terraform отличается от Ansible, Pulumi и CloudFormation
  4. Как работает Terraform под капотом и кто такой OpenTofu
  5. Установка Terraform и OpenTofu, подготовка Yandex Cloud
  6. Первый ресурс: разворачиваем виртуальную машину в Yandex Cloud
  7. Веб-сервер на ВМ: метаданные, user-data и группы безопасности
  8. Переменные ввода и выходные значения в Terraform
  9. Кластер ВМ: группа экземпляров Yandex Compute Instance Group
  10. Балансировщик нагрузки: Application Load Balancer в Yandex Cloud
  11. Состояние Terraform: что такое tfstate и чем опасен локальный файл
  12. Удалённое хранилище состояния: бэкенд на Yandex Object Storage
  13. Изоляция состояния: рабочие области против раскладки по папкам
  14. Источники данных и terraform_remote_state: связываем компоненты
  15. Модули Terraform: переиспользуем инфраструктуру
  16. Входные, локальные и выходные переменные модуля
  17. Версионирование модулей и подводные камни
  18. Циклы в Terraform: параметр count
  19. Циклы в Terraform: for_each по множествам и картам
  20. Выражения for и строковые директивы
  21. Условная логика: count-трюк, for_each и директива if
  22. Встроенные функции, типы и выражения HCL
  23. Развёртывание без простоя: create_before_destroy
  24. Подводные камни Terraform и рефакторинг с блоком moved
  25. Управление секретами: основы и типы
  26. Инструменты управления секретами: Yandex Lockbox, Vault, SOPS
  27. Аутентификация провайдера и секреты: сервисные аккаунты и OIDC
  28. Секреты в ресурсах и состоянии, ephemeral-значения
  29. Провайдеры Terraform: установка, версии, required_providers
  30. Несколько копий одного провайдера: alias и мультизона
  31. Несколько провайдеров и аккаунтов: configuration_aliases
  32. Terraform, Docker и Kubernetes: Managed Kubernetes в Yandex Cloud
  33. Код Terraform промышленного уровня: почему это долго
  34. Мелкие компонуемые модули вместо монолита
  35. Тестируемые модули и проверки: validation, precondition, postcondition
  36. Версионирование, публикация модулей и Terragrunt
  37. Ручное тестирование Terraform и очистка ресурсов
  38. Автоматические тесты на Terratest: модульные тесты
  39. Интеграционные и сквозные тесты, пирамида тестирования
  40. Нативный terraform test и статический анализ
  41. Внедрение Terraform в команде: процессы и культура
  42. Конвейер развёртывания прикладного кода
  43. Конвейер инфраструктурного кода и золотое правило Terraform (вы здесь)
  44. Стиль, ревью и CI/CD-инструменты: Atlantis, TACOS, policy as code
  45. Что нового в Terraform 1.3-1.10: моды, импорт, провайдер-функции, Stacks
  46. OpenTofu в 2026: чем живёт форк и как мигрировать
  47. Сертификация HashiCorp Terraform Associate и карьера
Зачем тебе вообще конвейер, если apply работает с ноутбука

Представь картину. Понедельник, в команде три человека, у каждого свой terraform на ноуте. Петя катит apply из дома, Маша - из офиса, ты - из кофейни через мобильный интернет. У всех чуть разные версии Terraform, у кого-то старая копия state, у кого-то лишняя переменная в окружении. И вот в среду прод лежит, а в логах непонятно кто, когда и что катил. Знакомо? Это не выдуманный ужастик, это типичная боль команд, которые пришли к подходу "инфраструктура как код" (iac), но остановились на полпути.

Terraform решает половину проблемы: он описывает инфраструктуру декларативно, в коде. Но код, который катится руками с десяти разных машин, ничем не лучше кликанья мышкой в консоли. Воспроизводимости ноль, аудита ноль, а terraform state - общий ресурс, который эти десять рук рвут на части. Сегодня разберём, как из ручного apply сделать нормальный конвейер инфраструктурного кода: VCS как единый источник правды, plan на пулл-реквесте вместо code review на глаз, и apply строго из CI после merge. И главное - золотое правило, ради которого вся эта глава и затевалась.

Изображение

Золотое правило Terraform

Сформулирую сразу, чтобы держал в голове весь урок:
Ветка master (или main) - это единственный и точный источник правды о том, что сейчас развёрнуто в проде. Никаких ручных изменений в облаке, никаких локальных apply в обход git. То, что в master, и есть твой прод. Точка.
Звучит банально, пока не начнёшь нарушать. А нарушают это правило двумя способами.

Первый - кто-то зашёл в веб-консоль Yandex Cloud и руками поправил группу безопасности, "там же на минуточку". Теперь реальность разъехалась с кодом. Следующий terraform plan покажет дрейф (drift), а следующий apply откатит твою ручную правку назад, потому что в коде её нет. В лучшем случае ты удивишься. В худшем - снесёшь что-то важное в три часа ночи.

Второй способ - локальный apply из ветки, которая ещё не в master. Ты покатил, всё заработало, обрадовался и забыл сделать merge. Через неделю коллега катит master, в котором твоих изменений нет, и Terraform аккуратно их сносит. Потому что для него master - истина, а твои локальные подвиги он знать не знает.

Вывод простой: руки убираем от облака и от локального apply на проде. Меняем инфраструктуру только через git. Хочешь поправить - открой пулл-реквест.

Как устроен PR-flow для Terraform

Рабочий цикл выглядит так. Ты создаёшь ветку, правишь .tf-файлы, открываешь пулл-реквест (или merge request, смотря где живёшь). И вот тут начинается магия: CI автоматически запускает terraform plan на твоих изменениях и постит результат прямо в PR комментарием.

Этот plan и есть твоё ревью. Обычный diff кода показывает, что ты написал. А terraform plan показывает, что реально произойдёт с инфраструктурой: сколько ресурсов добавится, сколько изменится, сколько (внимание!) уничтожится. Строчка

Код: Выделить всё

Plan: 1 to add, 0 to change, 3 to destroy
в ревью спасала больше продов, чем любой линтер. Ревьюер смотрит не только на синтаксис, но и на последствия.

Дальше связка terraform plan apply разносится по двум событиям:
  • plan - на каждый push в PR, как проверка и предпросмотр. Безопасно, ничего не меняет.
  • apply - только после merge в master, только из CI, и в идеале только после ручного аппрува.
Минимальный набор шагов в пайплайне:

Код: Выделить всё

# .gitlab-ci.yml, упрощённо
stages:
  - validate
  - plan
  - apply

validate:
  stage: validate
  script:
    - terraform init -input=false
    - terraform fmt -check
    - terraform validate

plan:
  stage: plan
  script:
    - terraform init -input=false
    - terraform plan -input=false -out=tfplan
  artifacts:
    paths:
      - tfplan
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

apply:
  stage: apply
  script:
    - terraform init -input=false
    - terraform apply -input=false tfplan
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual   # вот он, ручной аппрув на прод
Обрати внимание на пару деталей. Plan сохраняется в артефакт через

Код: Выделить всё

-out=tfplan
, и apply применяет именно этот сохранённый план, а не считает новый. Так ты гарантируешь, что катится ровно то, что ревьюер видел и одобрил, без сюрпризов "а между plan и apply кто-то что-то поменял". И

Код: Выделить всё

when: manual
на стадии apply - это тот самый аппрув: пайплайн дойдёт до прода и встанет, ожидая, пока человек нажмёт кнопку.

State и блокировки: почему CI обязан быть единственным

Теперь про terraform state - сердце всей системы. Это файл, где Terraform хранит соответствие между твоим кодом и реальными ресурсами в облаке. Локальный terraform.tfstate на ноутбуке в команде - это билет в ад: он у каждого свой, конфликтует, теряется, и в нём, между прочим, лежат секреты в открытом виде.

Решение - удалённый бэкенд. Для Yandex Cloud это Object Storage (S3-совместимый), а блокировки берёт на себя таблица в YDB. Выглядит так:

Код: Выделить всё

terraform {
  backend "s3" {
    endpoints = {
      s3       = "https://storage.yandexcloud.net"
      dynamodb = "https://docapi.serverless.yandexcloud.net/ru-central1/b1g.../etn..."
    }
    bucket         = "my-tfstate-bucket"
    region         = "ru-central1"
    key            = "prod/terraform.tfstate"
    dynamodb_table = "terraform-lock"

    skip_region_validation      = true
    skip_credentials_validation = true
    skip_requesting_account_id   = true
    skip_s3_checksum            = true
  }
}
Ключевая идея - dynamodb_table (через YDB Document API). Перед apply Terraform ставит блокировку (lock) на state. Пока один процесс держит lock, второй apply не стартует, а честно ждёт или падает с ошибкой "state is locked". Это и есть защита от проблемы одновременных apply: даже если два пайплайна каким-то чудом стартанули вместе, второй упрётся в замок и не испортит state.

Зачем нам один-единственный исполнитель в лице CI, теперь понятно: state лежит в защищённом бакете, доступ к нему - только у сервисного аккаунта пайплайна, а блокировка не даёт двум apply наступить друг другу на ноги. Никто с ноутбука к этому state даже не подключится без ключей, которые лежат в секретах CI, а не у людей в .bashrc.

Кстати, всё ровно то же справедливо и для opentofu - открытого форка Terraform. Конвейер, бэкенд, блокировки, золотое правило - один в один, меняется только имя бинарника. Если решишь мигрировать на OpenTofu, твой CI-процесс переживёт это почти без изменений.

Типичные грабли
  • apply на master без plan-артефакта. Если apply пересчитывает план заново, а не берёт сохранённый, ты катишь не то, что ревьюили. Всегда apply из -out файла.
  • Секреты в state и в логах. State содержит пароли и ключи. Бакет - приватный, версионирование включено, логи plan чистим от чувствительных значений (помечай переменные как sensitive).
  • Нет блокировки. Удалённый state без dynamodb_table / YDB-локов - это гонка. Два apply, поехавший state, ручное восстановление. Не экономь на блокировках.
  • Дрейф из-за ручных правок. Кто-то тронул облако руками - plan покажет неожиданные изменения. Лечится дисциплиной (золотое правило) и регулярным plan по расписанию как детектором дрейфа.
  • Один state на всё. Прод и dev в одном ключе state - и тестовый apply трогает прод. Разделяй окружения по разным key/бакетам.
Мини-лаба

Руками, на тестовом проекте, без спешки:
  • Заведи репозиторий, положи в него .tf с одной ВМ или бакетом в Yandex Cloud.
  • Настрой backend "s3" на Object Storage и блокировку через YDB. Сделай terraform init, убедись что state уехал в облако.
  • Создай ветку, поменяй один атрибут, открой PR. Напиши простейший пайплайн, чтобы plan постился в PR.
  • Слей PR и сделай apply из CI с ручным аппрувом (when: manual). Почувствуй кнопку.
  • Для эксперимента запусти два apply почти одновременно и посмотри, как второй упирается в блокировку.
Контрольные вопросы
  • Сформулируй золотое правило Terraform своими словами. Что считается единственным источником правды о проде?
  • Почему apply должен брать сохранённый plan-артефакт, а не пересчитывать план заново перед применением?
  • Какой механизм защищает state от двух одновременных apply и где он живёт в случае Yandex Cloud?
  • Чем грозит ручная правка ресурса в веб-консоли облака и как пайплайн это обнаружит?
Итог: что запомнить

Конвейер для terraform yandex cloud - это не бюрократия, а способ спать спокойно. master = прод, изменения только через git, plan на PR как настоящее ревью, apply из CI после аппрува, state в защищённом бэкенде с блокировкой. Убери руки от облака и от локального apply - и инфраструктура как код наконец станет предсказуемой. Модули terraform, переменные, окружения - всё это надстройки, но без дисциплины конвейера они тебя не спасут. Золотое правило простое до неприличия, и именно поэтому его так легко нарушить. Не нарушай.
👍2 ❤️3 🔥1 😄 🤔5
Аватара пользователя
dougt
Сообщения: 1
Зарегистрирован: 12 май 2026, 18:26

Re: Конвейер инфраструктурного кода и золотое правило Terraform

Сообщение dougt »

Наконец дошло зачем нужен -out=tfplan, всегда думал что это лишний шаг. Теперь буду катить только сохранённый план, спасибо.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
rustnerd
Сообщения: 1
Зарегистрирован: 11 май 2026, 08:06

Re: Конвейер инфраструктурного кода и золотое правило Terraform

Сообщение rustnerd »

А если apply упал на середине из-за блокировки от прошлого зависшего пайплайна, как правильно снимать lock? force-unlock не страшно делать на проде?
👍 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Конвейер развёртывания прикладного кода
Следующая глава →
Стиль, ревью и CI/CD-инструменты: Atlantis, TACOS, policy as code

Все главы курса «Terraform: инфраструктура как код на Yandex Cloud»

Поделиться темой: ✈ Telegram VK
Похожие запросы: terraform yandex cloud с чего начать новичкукак установить terraform и opentofu на linuxчто такое terraform state и tfstate простыми словамиудаленный backend terraform на object storage yandex cloudчто такое инфраструктура как код iac простыми словамиterraform plan и apply что делают и чем отличаются

Вернуться в «Terraform: инфраструктура как код на Yandex Cloud»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость