GitOps Terraform: почему состояние расходится с кодом
Состояние описывает то, что уже создано в облаке, а код — то, что должно быть. Пока между ними стоит только дисциплина, расхождение появляется быстро: доступ понадобился срочно, инженер правит правило балансировщика или размер диска прямо в консоли, а в описании инфраструктуры это не отражается. Через неделю следующее применение возвращает всё к прежнему виду — и ломает то, что чинили руками.
Второй источник дрейфа — сам файл состояния. Это единственный изменяемый артефакт, и без корректной блокировки два одновременных применения перетирают записи друг друга: часть ресурсов остаётся в состоянии, часть теряется. Хранилище на локальной машине усиливает проблему — состояние существует в одном экземпляре у одного человека, и восстановление после сбоя превращается в археологию.
Цена проявляется не в момент правки, а при разборе инцидента. График изменений пуст, потому что правка не проходила через систему контроля версий; план показывает десятки «новых» ресурсов, которые на самом деле давно работают; откат на предыдущий релиз тянет за собой чужие изменения. Отдельно расходятся среды: то, что вручную поправлено на стенде, никогда не доедет до промышленного контура, и наоборот.
Разбираем, как это закрывается: состояние переезжает в общее защищённое хранилище с блокировкой, изменения проходят только через проверяемое описание, а применение запускается из единой точки, где видно автора и причину. Именно на этом строится GitOps — репозиторий становится единственным источником правды об инфраструктуре.
Что меняется после внедрения: измеримые эффекты
Переход на управление состоянием через репозиторий меняет не сам факт применения изменений, а их стоимость по времени и риску. Пять следствий видны уже в первый месяц работы и дальше только укрепляются.
Скорость доставки. План и его применение идут одним маршрутом: коммит, ревью, автоматическая проверка, применение. Ручные вызовы с машины инженера исчезают, поэтому типовое изменение инфраструктуры проезжает от правки до рабочего контура за минуты вместо часов ожидания окна и свободного ответственного.
Время восстановления после сбоя. Конфигурация и состояние лежат рядом и версионируются, значит откат — это реверс коммита, а не сборка окружения по памяти. Восстановление сокращается с часов до минут и воспроизводится любым инженером команды, а не только тем, кто вносил правку.
Устранённые классы отказов. Блокировка состояния, расхождение копий между площадками, правки напрямую в консоли и изменения «мимо процесса» перестают быть возможными — каждый класс закрыт правилом, а не договорённостью. Остаются ошибки в самой конфигурации, и они ловятся на ревью до применения.
Прозрачность изменений. Каждое действие оставляет коммит с автором, причиной и историей: видно, что менялось, когда и зачем. Разбор инцидента перестаёт зависеть от чьей-то памяти или переписки в чате.
Доля ручных операций падает до ревью и решений об архитектуре — рутинные применения уходят автоматике. Инфраструктура становится предсказуемой не только в описании, но и в обслуживании.
Режимы GitOps Terraform: сравнение подходов
Режим ведения состояния определяет, кто применяет изменения и что считается источником правды по инфраструктуре. Ниже четыре варианта, которые встречаются на практике — от локального состояния до применения по слиянию запроса. Они совместимы по шагам: переход можно делать частями, не переписывая описания сред на Terraform.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Локальное состояние | Проба, один инженер, одноразовый стенд | Блокировки нет, копии расходятся, восстановление только из ручных копий |
| Удалённое хранилище, применение вручную | Команда до восьми человек, редкие релизы | Изменения применяются вне репозитория, проверка изменений не предусмотрена, доступ выдаётся целиком на среду |
| Удалённое хранилище, применение из конвейера по слиянию запроса | Несколько сред, нужен след изменений и проверка до применения | Нужна дисциплина ветвления; аварийные правки идут вне обычного порядка |
| Управляемое хранилище с разделением прав по средам | Несколько команд, прод и тестовые контуры в одном описании | Роли настраиваются заранее, часть возможностей ограничена провайдером |
Что проверяем при переходе
Блокировка состояния не даёт двум запускам одновременно менять одну среду: без неё параллельные применения оставляют расхождения между описанием и реальностью. Разделение прав доступа строим так, чтобы запись в удалённое хранилище состояния была только у конвейера, а инженеры работали через запрос на слияние — тогда изменение проверяют до применения, а откат сводится к возврату предыдущей версии.
Этапы внедрения: от аудита до передачи в работу
Начинаем с аудита инфраструктуры, а не с установки инструментов: без инвентаризации ресурсов любая схема разделения состояния окажется неверной, и её придётся переделывать вместе с уже перенесёнными конфигурациями. Дальше выстраиваем порядок, в котором каждое изменение Terraform-конфигурации проходит через Git, проверяется до применения и остаётся в истории с автором и причиной правки.
- Аудит инфраструктуры. Собираем перечень ресурсов, сред и провайдеров, отмечаем созданное вручную и расхождения между описанием и фактическим состоянием.
- Схема разделения состояния. Определяем гранулярность: отдельные наборы по средам, доменам и критичности, чтобы сбой одного не блокировал остальные. Настраиваем удалённое хранилище и блокировки от параллельных правок.
- Репозитории и доступ. Раскладываем модули и конфигурации, задаём ветвление, обязательное ревью и права на защищённые ветви.
- Проверка изменений до применения. Подключаем автоматический расчёт плана в запросе на слияние, статический анализ и политики: что запрещено — не проходит дальше. Применение в рабочий контур — только после явного подтверждения.
- Тестовый прогон. Прогоняем создание, изменение и импорт существующих ресурсов на неполном контуре, отдельно проверяем восстановление состояния из резервной копии.
- Передача в эксплуатацию. Документируем порядок работы, разбираем типовые сценарии с командой, настраиваем оповещения о расхождениях и дежурство.
- Регламент откатов. Фиксируем, как откатить неудачное применение и что делать при конфликте состояний, пока правки идут параллельно.
На выходе команда работает с инфраструктурой тем же способом, что и с кодом приложения, а доступ к ручным правкам в консоли закрывается или сужается до аварийного.
Артефакты внедрения: конфигурации, схемы, регламенты
Внедрение заканчивается не зелёным планом в последнем коммите, а моментом, когда команда заказчика может менять инфраструктуру без автора схемы. Поэтому передаём не доступ к репозиторию, а набор артефактов, по которым дежурный инженер восстанавливает состояние с нуля: что описано кодом, где лежит состояние, кто имеет право его менять и как откатиться, если применение прошло неудачно.
- Каталог модулей Terraform — назначение каждого модуля, входные и выходные переменные, зависимости между ними, а также места, которые ломаются при смене мажорной версии провайдера.
- Схема разделения сред — какие окружения существуют, какое хранилище состояния закреплено за каждым, как настроена блокировка состояния и кто может применять изменения.
- Политики доступа — матрица ролей: права на репозитории, на хранилище состояния, на облачные аккаунты, обязательные одобрения и защита ветки, из которой запускается применение.
- Конфигурации агента применения — список репозиториев под управлением, шаблоны планов по каталогам, правила параллелизма и привязка проектов к окружениям.
- Регламент изменений — сколько одобрений нужно для продуктивной среды, кто владелец каталога, в каком порядке проходит срочное изменение вне обычного процесса.
- Инструкции по восстановлению — откат к предыдущей ревизии состояния, восстановление из версионированного хранилища, действия при расхождении реальной инфраструктуры с описанной, ручной импорт ресурсов, созданных в обход кода.
- Карта проверок — какие автоматические проверки фиксируют расхождение, куда приходят уведомления, кто и в какой срок разбирает сигнал.
- Регламенты типовых инцидентов — пошаговые сценарии на потерю состояния, частично применённый план и недоступность облачного провайдера.
Все документы лежат рядом с кодом в том же репозитории, поэтому описание и реальная конфигурация не расходятся.
Кейс: убрали ручные правки и расхождение состояния
До внедрения инженеры применяли изменения из локальных копий, а стейт правили командами импорта и удаления объектов напрямую. По журналу блокировок мимо общего конвейера проходила треть изменений: расхождение между описанием инфраструктуры и реальностью всплывало уже на инциденте, а откат собирался руками и занимал около 45 минут.
Мы развернули Atlantis в кластере и привязали его к репозиториям: план публикуется комментарием к запросу на слияние, применение запускается после одобрения, а запись в хранилище со стейтом разрешена только сервисному аккаунту сервиса. У инженеров осталось чтение, аварийное применение — лишь по регламенту с фиксацией причины.
| Метрика | До | После |
|---|---|---|
| Доля ручных изменений | 34% | 2% |
| Время отката | ~45 минут | ~6 минут |
| Конфликты блокировки стейта | 5 в месяц | 0 |
| Расхождения конфигурации с реальностью | 4 за квартал | 0 за два квартала |
Метрики снимали из трёх независимых источников: журнала блокировок стейта, истории версий объекта в хранилище и длительности инцидентов из системы учёта. Сравнивали сопоставимые по нагрузке периоды — расхождение конфигурации перестало быть причиной аварий, а откат свёлся к одному действию.
Что делать, если инфраструктура уже развёрнута вручную?
Если инфраструктура развёрнута вручную, это не помеха — просто нет описания: ресурсы живут у провайдера, но не в конфигурации. Начинаем с инвентаризации: собрать фактические параметры сетей, машин, балансировщиков и прав доступа и сопоставить их с описанием в репозитории. Пока сопоставление неполное, план применять нельзя — он попытается пересоздать то, что уже работает.
Дальше идёт импорт ресурсов в состояние Terraform. Критерий готовности — не «импорт прошёл», а пустой план: если проверка показывает ноль расхождений, описание отражает реальность. Каждое расхождение разбираем отдельно: часть закрывается правкой конфигурации, часть — уточнением параметров, часть требует точечной пересборки ресурса в согласованное окно.
Состояние разделяем по границам отказов: сети, данные, приложения — отдельные наборы. Тогда правка в одном контуре не тянет пересборку остальных, а сбой ограничен одним участком. Блокировка состояния и запрет ручных правок в консоли снимают конфликт: изменения проходят только через репозиторий и проверку.
План перехода строим так, чтобы сервисы не останавливались. Сначала контур работает в режиме проверки — план строится, но не применяется. Затем на применение переводим один модуль и наблюдаем несколько релизов. Ручные права отзываем только после того, как новый контур отработал без откатов.
Страховка на всём пути — версионирование состояния и снимок перед каждым применением. Восстановление из снимка возвращает контур в известное состояние, поэтому миграция идёт порциями, без окна простоя и без остановки сервисов.
Технические сомнения и частые вопросы по внедрению
Инженерные сомнения при переходе на GitOps касаются не самого принципа «состояние меняется только через согласованный запрос», а границ: изоляция сред, доступ к секретам, что останется после передачи проекта. Отвечаем на них так, как разбираем на этапе проектирования, а не после первого инцидента.
Базовое правило, из которого выводится всё остальное: один каталог — одно состояние — одна среда. Работаем на Atlantis — сервис формирует план до применения и блокирует состояние на время операции, поэтому параллельные запуски не портят файл состояния.
Как изолируются среды — это не три копии одного?
У каждой среды свой каталог, своё состояние и свои учётные данные провайдера: прод-путь недоступен из проверок промежуточного контура. Совпадение имён ресурсов перестаёт быть риском — план для промежуточной среды физически не видит промышленное состояние.
Секреты не окажутся в репозитории и в логах?
В репозитории лежат только ссылки, значения подаются в раннер из хранилища секретов по пути среды. Чувствительные поля помечаются и не печатаются в открытом виде, а доступ к промышленным значениям выдаётся отдельной ролью с ограниченным кругом держателей.
Как разграничиваются роли и ведётся аудит изменений?
Права привязаны к группам в системе контроля версий: инженер предлагает изменение, применение к промежуточной среде идёт по одному правилу, к промышленной — только через согласование. Каждое применение оставляет след: кто инициировал, на каком коммите, что изменилось в состоянии.
Что входит в сопровождение после запуска?
Обновление провайдеров и сервиса применения, ревизия правил доступа и ротация учётных данных, разбор отказов на промежуточном контуре до прода, дежурство по инцидентам. Плюс регламент подключения новой среды или команды без правки ядра.
Обсудим задачу: состав работ и порядок старта
Чтобы разговор был предметным, достаточно прислать то, что уже есть. Нам нужна не презентация, а рабочая картина: как устроены репозитории, где хранятся состояния Terraform, кто и как их меняет сегодня и какие ограничения заданы со стороны безопасности.
Для старта хватит такого набора:
- схема репозиториев: один общий или несколько связанных, где лежат модули и описания окружений;
- перечень мест хранения состояний и того, что ещё не переведено в общее хранилище;
- список аккаунтов и проектов облака, к которым обращается инфраструктура, вместе с правилами доступа;
- роли инженеров и то, кому сейчас разрешено применять изменения напрямую;
- принятый порядок согласования: кто ревьюит, какие правки считаются критичными, есть ли обязательные окна;
- известные ограничения: изоляция сред, требования аудита, запрет на автоматическое применение;
- два-три примера последних крупных изменений — по ним видно реальные узкие места.
Дальше порядок простой. Мы изучаем материалы и возвращаемся с уточняющими вопросами по доступам и границам ответственности, затем собираем план внедрения по этапам с точками контроля и только после этого даём оценку сроков и состава работ. Схему GitOps для состояний разворачиваем пошагово, чтобы действующая инфраструктура оставалась рабочей на каждом шаге.
Опишите задачу и пришлите то, что уже есть под рукой, — вернёмся с оценкой и планом работ.







