Ты уже умеешь писать HCL, гонять terraform plan apply и собирать модули terraform. Технически ты готов. Но вот неприятная правда: 90 процентов провалов внедрения IaC происходят не из-за плохого кода, а из-за людей. Один админ ночью руками поправил security group в консоли Yandux Cloud, забыл сказать команде, и через неделю чей-то apply снёс это изменение. Прод лежит, виноватых нет, а terraform получает репутацию "той штуки, которая всё ломает".
Инфраструктура как код - это не про синтаксис. Это про договорённости. Terraform работает ровно настолько, насколько вся команда согласна играть по одним правилам. Можно иметь идеальный код и при этом полный хаос, если половина команды правит ресурсы мышкой. В этом уроке разберём, как протащить IaC в команду так, чтобы это прижилось, а не было выброшено через два месяца со словами "не взлетело".

Как продать IaC начальству и команде
Начальство не интересует слово "декларативность". Его интересуют деньги, риски и скорость. На этом языке и говори.
Аргумент про риск. Ручные правки в консоли - это не задокументированные изменения, которые знает только тот, кто их сделал. Уволился человек - знание ушло с ним. Случилась авария в 3 ночи - никто не может воспроизвести инфраструктуру, потому что она существует только в голове и в текущем состоянии облака. Terraform превращает это в код в git, который читается, ревьюится и восстанавливается.
Аргумент про скорость. Поднять копию окружения для тестов руками - это день кликанья. С terraform - это terraform apply и пятнадцать минут. Новый менеджер просит staging-стенд? Не проблема, у тебя есть модуль.
Аргумент про аудит. Кто, когда и что менял в инфраструктуре - это git log. Для безопасников и для разбора инцидентов это золото.
Постепенный переход вместо big bangЛайфхак: не проси разрешения переписать всё. Попроси разрешения на маленький пилот - один некритичный сервис. Покажи результат цифрами (было N часов, стало M минут), и дальше тебя начнут просить сами.
Главная ошибка энтузиаста - попытаться затерраформить всю компанию за один спринт. Это всегда заканчивается выгоранием и откатом. Big bang не работает по простой причине: ты не можешь одновременно учиться, переписывать прод и не ломать бизнес.
Правильный путь - инкрементальный:
- Начни с нового, а не со старого. Все новые ресурсы создаём только через terraform. Старое пока живёт как живёт.
- Импортируй существующее постепенно. terraform import затаскивает уже созданные руками ресурсы под управление кода, по одному, когда до них дошли руки.
- Сначала некритичное. Dev и staging - отличный полигон. Если apply там что-то сломает, никто не пострадает.
- Прод - в последнюю очередь и осознанно, когда команда уже набила руку.
Правило только-через-код и дрейф
Это самое важное организационное правило всего IaC. Звучит просто: никаких ручных изменений в консоли облака. Вообще. Если что-то надо поменять - меняешь код и делаешь apply.
Почему так строго? Из-за дрейфа конфигурации (configuration drift). Terraform хранит в terraform state своё представление о мире. Когда кто-то правит ресурс мышкой, реальность расходится с состоянием и с кодом. Дальше два сценария, оба плохие:
- Следующий apply увидит расхождение и откатит ручную правку обратно к коду. Поздравляю, ты только что снёс чужой "временный" фикс на проде.
- Или ты добавишь это изменение в код задним числом, но уже потеряв понимание, зачем оно было нужно.
Чтобы правило работало не на честном слове, его подкрепляют технически: у людей забирают права на запись в консоли облака, оставляя read-only для просмотра. Менять инфру может только сервисный аккаунт из CI-пайплайна. Звучит жёстко, но именно это убивает дрейф в зародыше.
Вот так выглядит безобидный кусок инфраструктуры в Yandex Cloud, который теперь живёт только в репозитории и меняется только через pull request:
Код: Выделить всё
terraform {
required_providers {
yandex = {
source = "yandex-cloud/yandex"
}
}
}
resource "yandex_compute_instance" "app" {
name = "app-prod"
platform_id = "standard-v3"
zone = "ru-central1-a"
resources {
cores = 2
memory = 4
}
boot_disk {
initialize_params {
image_id = "fd8ccebmjslue5nphmt6" # ubuntu образ
size = 20
}
}
network_interface {
subnet_id = yandex_vpc_subnet.app.id
nat = true
}
}
resource "yandex_vpc_network" "app" {
name = "app-network"
}
resource "yandex_vpc_subnet" "app" {
name = "app-subnet"
zone = "ru-central1-a"
network_id = yandex_vpc_network.app.id
v4_cidr_blocks = ["10.10.0.0/24"]
}
Кто владеет кодом, ревью и ответственность
IaC без владельцев - это код, который гниёт. Нужно явно решить, кто отвечает за инфра-репозиторий.
Две крайности, между которыми выбирают команды. Первая - выделенная платформенная команда владеет всем terraform, а разработчики просят изменения через тикеты. Надёжно, но платформа становится узким горлышком. Вторая - каждая продуктовая команда владеет своим куском инфры (модель "you build it, you run it"). Быстро, но требует зрелости и общих стандартов, иначе расцветает зоопарк.
На практике побеждает гибрид: платформенная команда даёт переиспользуемые модули terraform и общие правила, а продуктовые команды собирают из этих модулей свои окружения. Так и контроль есть, и узкого горла нет.
Ревью обязателен для любого изменения инфраструктуры. terraform plan в пайплайне прикладывается прямо к pull request, и ревьюер видит, что именно изменится, до применения. Особое внимание - на строки с destroy и replace в выводе плана. Одно дело "добавится диск", совсем другое - "пересоздастся база с данными". План в PR ловит такие сюрпризы до того, как они станут инцидентом.
Используй CODEOWNERS в git, чтобы изменения в чувствительных директориях (сеть, IAM, прод) автоматически требовали аппрува нужного человека.
Монорепо или полирепо
Извечный спор, как организовать репозитории инфраструктуры.
Монорепо - вся инфра в одном репозитории. Плюсы: общие модули под рукой, атомарные изменения через несколько компонентов, единая история. Минусы: один большой terraform state становится медленным и опасным (любой apply трогает весь мир), плюс права доступа выдаются на весь репозиторий сразу.
Полирепо - у каждой команды или сервиса свой репозиторий и свой state. Плюсы: маленький радиус поражения, гранулярные права, быстрые независимые apply. Минусы: переиспользуемые модули приходится выносить в отдельный репозиторий и версионировать, история размазана.
Здравый компромисс для большинства: общие модули в отдельном версионируемом репозитории, а окружения - в репозиториях по командам или по доменам. И обязательно дроби terraform state по окружениям и компонентам - один гигантский state на всю компанию это бомба замедленного действия.
Типичные грабли
- Один общий state на всё и всех. Рано или поздно два человека сделают apply одновременно и подерутся за блокировку, а время плана уползёт в минуты.
- Нет remote backend с блокировкой. Если state лежит у людей локально - вы обречены на конфликты и потерю состояния. Храни его в Yandex Object Storage с блокировкой.
- Секреты в коде и в state. Пароли и ключи нельзя класть в HCL открытым текстом, а сам state надо считать секретным файлом (там лежат пароли в открытом виде).
- Правило только-через-код есть на бумаге, но права в консоли не отобрали. Тогда оно не работает - кто-нибудь обязательно "по-быстрому поправит руками".
- Внедрили инструмент, но не сменили культуру. Terraform без договорённостей о ревью и владении - это просто ещё один способ сломать прод, только теперь декларативно.
Руками тренировать тут особо нечего, это организационный урок. Но проделай мысленный (а лучше письменный) разбор для своей текущей работы:
- Выпиши три аргумента, которыми ты убедишь своего тимлида попробовать IaC на одном пилотном сервисе. Цифрами, а не лозунгами.
- Сформулируй для своей команды правило только-через-код в одно предложение и придумай, как технически запретить ручные правки.
- Нарисуй, как ты разложишь инфраструктуру по репозиториям и по state-файлам: что в монорепо, что отдельно, где граница.
- Реши, кто будет CODEOWNER для прод-сети и IAM, и почему именно он.
- Что такое дрейф конфигурации и почему правило "только через код" - это не занудство, а защита от инцидентов?
- Почему стратегия big bang при внедрении terraform обычно проваливается, и как выглядит постепенный переход?
- Чем монорепо отличается от полирепо для инфраструктуры, и почему один общий terraform state на всё - плохая идея?
- Зачем прикладывать terraform plan к pull request и на какие строки вывода смотреть особенно внимательно?
Terraform - это на 30 процентов инструмент и на 70 процентов договорённости в команде. Продавай IaC начальству на языке рисков, скорости и аудита, а не терминов. Внедряй постепенно: новое - через код, старое - импортом, прод - последним. Святое правило - только через код, подкреплённое отбором прав в консоли, иначе дрейф съест тебя. Назначь владельцев, сделай ревью с обязательным planом в PR, разнеси state по окружениям. Сделаешь это - и terraform станет скучным и надёжным. А скучная инфраструктура - это лучший комплимент, который можно ей сделать.