TL;DR. IaC решает проблему первичного развёртывания, но не проблему непрерывной консистентности. Конфигурационный дрейф — структурная характеристика любой живой инфраструктуры, а не следствие «плохой дисциплины». Ни один инструмент детектирования не предотвращает его на архитектурном уровне. В статье РАССУЖДАЮ, почему это так и что с этим реально делать.
Цель данной статьи исследовать дыру с дрейфом и поделиться результатами своих поисков и выводами. Я не претендую на звание IaC гуру, а описываю свой путь от проблемы до конечного решения или выводов.
Рекомендую начать с выводов, чтобы определить, что стоит вашего внимания.
Если у вас уже все случилось и ищете решение, то перед разделом "Выводы" есть небольшой чек-лист.
Откуда взялась эта проблема?
Нас двое: я веду инфраструктуру как основной, коллега подхватывает дежурство когда меня нет. Всё началось в обычный вторник около двух часов ночи. Упал прод: один из сервисов перестал стучаться до Redis. Коллега залез в YC Console, нашёл группу безопасности и добавил недостающее inbound-правило. Сервис поднялся. Написал мне в Telegram «починил, всё ок».
Важная оговорка. Коллега работает по методичке, написанной мною в Obsidian, а если возникают вопросы, но нет возможности задать их мне, то он идет общаться с чатом. Я уже думаю написать ему шаблон для системного промпта, чтобы хотя бы как-то нивелировать эту часть работы.
Следующий terraform apply случился через три дня — в рамках планового деплоя, который делал уже я. Terraform увидел расхождение между state-файлом и реальным состоянием ресурса и удалил вручную добавленное правило. Сервис снова упал — в рабочее время, с клиентами онлайн.
Первая реакция очевидна: «я что-то сломал в Terraform». Вторая - после разбора с коллегой: а разве Terraform должен был это поймать? В репозитории была «правильная» конфигурация. Он просто применил то, что там написано. Коллега всё сделал правильно - остановил инцидент быстрейшим способом имеющимися средствами.
Здесь закономерный вопрос: почему коллега не отредактировал .tf-файл и не применил изменение через Terraform? На первый взгляд это выглядит как очевидное решение.
На практике это намного сложнее, особенно в небольшой команде:
Открыть консоль и добавить правило - минута (и еще 5 минут на чтение методички, логов и запроса в чат). Найти нужный
.tf-файл, понять текущее состояние модуля, написать правильный блок, закоммитить и запуститьapply- это 15-30 минут даже для человека, который хорошо знает кодовую базу. Работая, например, с курсором или claude code все проще, время сокращается до примерно 5 минут. Но коллега выбрать CLI путь, хотя AI инструменты мы применяем чаще, чем сами что-то пишем.terraform planво время инцидента нередко показывает не одно изменение, а двадцать — накопившиеся расхождения из других источников. Применять всё это в 2 ночи, под давлением, без возможности нормально проверить план - хуже, чем ручное точечное исправление.Коллега не всегда знает архитектуру Terraform-модулей так же хорошо, как я. Он знает, как решить проблему в консоли. Заставлять его редактировать незнакомый IaC-код в 2 ночи - это риск новой ошибки. Именно поэтому я все еще считаю, что CLI путь единственно верный в той ситуации.
В нашей команде Terraform-стейт и доступы часто настроены только на основной рабочей машине. У дежурного может просто не быть работающего
terraform initпод рукой.
Так что ручной хотфикс — это рациональное решение, а не безответственность. Проблема не в том, что коллега поступил неправильно. Проблема в том, что система не имела механизма синхронизировать это изменение обратно в IaC. Ну или проблема в том, что нет регламента исправления таких ошибок: ведение документации, постановка задачи с высоким приоритетом и тд, чтобы эти изменени не потерялись в бэклогах.
Я начал копать: насколько распространена эта проблема, есть ли системные решения, или это вечная боль? Оказалось — второе, но с нюансами. Ниже — всё, что я собрал.
Что такое Infrastructure Drift - и почему это не баг и, очевидно, не фича
Конфигурационный дрейф (Configuration Drift) - это состояние, при котором развёрнутые облачные ресурсы расходятся с их описанием в IaC-коде.
Механику самого дрейфа и его последствия для команды хорошо разобрали в переводе на Хабре — я пойду дальше и сосредоточусь на системных причинах и архитектурных ответах.
Формально можно выделить два класса дрейфа:
Managed drift - ресурс есть в Terraform state, но его реальные атрибуты изменились вне Terraform. Именно это произошло в моём кейсе.
Unmanaged drift - ресурс существует в облаке, но вообще не описан в IaC: кто-то создал его через консоль или CLI и забыл (или намеренно не стал) добавлять в репозиторий.
Ключевое слово здесь - расхождение. Terraform хранит «желаемое состояние» в state-файле и применяет его при terraform apply. Что происходит между двумя запусками apply — Terraform не знает и знать не может. Это не недостаток реализации, это фундаментальное ограничение декларативной модели.
HashiCorp прямо пишет в документации: "You should not make manual changes to resources controlled by Terraform, because the state file will be out of sync, or "drift," from the real infrastructure. If your state and configuration do not match your infrastructure, Terraform will attempt to reconcile your infrastructure, which may unintentionally destroy or recreate resources"
Слово «unintentionally» здесь — ключевое.
На русском: "Не следует вручную вносить изменения в ресурсы, управляемые Terraform, поскольку файл состояния будет рассинхронизирован, или «отклонится», от реальной инфраструктуры. Если ваше состояние и конфигурация не соответствуют вашей инфраструктуре, Terraform попытается согласовать вашу инфраструктуру, что может непреднамеренно уничтожить или создать новые ресурсы."
Что по цифрам в мире?
Прежде чем перейти к причинам и решениям, стоит понять, насколько это распространено.
По данным CNCF 2024 Annual Survey, 90% организаций, использующих облако, уже применяют IaC, при этом Terraform занимает 76% рынка. То есть с проблемой дрейфа потенциально сталкивается абсолютное большинство облачных команд.
При этом тот же HashiCorp State of Cloud Strategy Survey 2024 фиксирует: 64% организаций сообщают о нехватке квалифицированных специалистов в области cloud и автоматизации. Это создаёт опасный разрыв: Terraform внедрили, но операционной зрелости для его правильной эксплуатации нет.
Что это означает на практике? Команды с частым конфигурационным дрейфом имеют значительно более высокий change failure rate - ключевую метрику стабильности из DORA State of DevOps. По данным DORA, change failure rate - это процент деплоев, требующих хотфиксов или роллбеков. Конфигурационный дрейф напрямую провоцирует его рост: задеплоили «правильную» конфигурацию из Terraform, а она перезаписала рабочий хотфикс - снова инцидент, снова откат.
Реальный инцидент
В июне 2023 года исследователи из Wiz обнаружили, что команда AI-исследователей Microsoft случайно открыла публичный доступ к 38 ТБ внутренних данных через Azure Storage. Утечка содержала приватные ключи, пароли и более 30 000 внутренних сообщений из Microsoft Teams от 359 сотрудников.
Причина: неправильно настроенный Azure SAS-токен. Исследователь опубликовал в GitHub-репозитории ссылку на Azure Blob Storage для скачивания датасета, но токен был настроен с избыточными правами - он давал доступ не к конкретному бакету, а ко всему storage account. Причём с правами full control, включая запись и удаление.
Утечка существовала с июля 2020 года - три года, прежде чем её обнаружили. SAS-токены в Azure сложно мониторить централизованно: нет единого инструмента в Azure Portal для отслеживания всех выданных токенов.
Это классический unmanaged drift: конфигурация вышла за пределы IaC-воркфлоу - и никто этого не заметил на протяжении трёх лет.
Почему "дисциплина" не решит проблему
Я нашел две причины, по которым это даже не всегда зависит от нас
Облачные провайдеры меняют поведение API и дефолтные значения атрибутов без уведомления. Как указывает Firefly: провайдер может в одностороннем порядке изменить дефолтные настройки сервиса - и ресурс, созданный Terraform месяц назад, окажется в состоянии, отличном от того, что описано в
.tf-файле. Terraform-провайдер может устареть или интерпретировать изменения иначе, чем вы ожидаете.Дрейф возникает не только там, где несколько больших команд работают с одной инфраструктурой. В небольших командах он появляется из-за асимметрии знаний: один человек понимает Terraform-архитектуру глубоко, второй - на уровне «знаю, как починить проблему в консоли». Каждый хотфикс от второго - потенциальный дрейф, который первый обнаружит только при следующем
apply.По наблюдению Spacelift, ситуацию усугубляет наличие нескольких инструментов автоматизации с пересекающимися зонами ответственности:
«Using Terraform for infrastructure management alongside a configuration management tool like Ansible creates a high possibility of infrastructure drift. Ironically, the more automation tools you implement, the more manual effort is required to reconcile the changes they create in Terraform state files».
Это справедливо даже для команды из двух человек - Terraform плюс любой скрипт, который что-то меняет в облаке напрямую, создают пространство для расхождений.
И все еще держим в голове замечтку, что между двумя запусками apply облако продолжает жить своей жизнью: автоскейлинг создаёт инстансы, мониторинг модифицирует теги, другие системы меняют параметры. Terraform об этом не знает.
Есть ли решение?
Если уж я нашел столько источников с описанием дыр, наверняка их находили и другие, не учитывая тех, кто столкнулся с описанными проблемами.
Сейчас действительно есть целый набор разных инструментов для работы с дрейфом. Лично я разделил их на две группы:
tf-нативные средства
1.1terraform plan -refresh-only- обновляет state-файл из реального состояния облака без применения изменений. Показывает расхождения. Но нужно запускать вручную или по расписанию (как будто не составляет проблем), не мониторит continuous.
1.2 HCP Terraform Drift Detection - автоматическое обнаружение дрейфа, но доступно только в платном Standard Edition. Сейчас уже звучит как решение для тех, кто готов платить.Ненативные решения (их искал вместе с чатом)
2.1 Driftctl / Snyk IaC - обнаруживает как managed, так и unmanaged дрейф, генерирует детальные диффы, интегрируется в CI/CD.
2.2 Spacelift - платформа для управления IaC с встроенным drift detection и возможностью автоматической ремедиации.
2.3 CloudQuery - инвентаризация облачных ресурсов и детектирование отклонений от политик.
2.4 Firefly - по собственным данным компании, платформа обнаружила более 512 000 событий дрейфа у клиентов, предотвратив оценочно $3.8M потерь.
Если уже есть решение, то в чем проблема?
Все перечисленные инструменты детектируют дрейф постфактум. Это важно понять: в декларативной модели нет механизма отклонения изменений, внесённых вне IaC-пайплайна. Консоль всегда позволит вам изменить, например, Security Group руками - никакой Terraform не заблокирует это на уровне API.
На мой взгляд это фундаментальное ограничение архитектуры, а не недостаток конкретного инструмента.
Еще немного циферок слабо связанных с темой
Пока искал материал нашел пару источников про секреты/креды в tf-коде
Когда вы ищете дрейф, вы неизбежно работаете с конфигурационными файлами, которые нередко содержат креды. По данным GitGuardian State of Secrets Sprawl 2024, в 2023 году было обнаружено 12.8 миллиона новых секретов в публичных GitHub-репозиториях - рост на 28% год к году. 7 из каждых 1000 коммитов содержали хотя бы один секрет.
Причём 90% секретов остаются валидными через 5 дней после утечки - разработчики удаляют коммиты, но не отзывают токены.
Еще чуть-чуть подушню исследованием
В марте 2025 года исследователи из EPFL (Лозанна) опубликовали на arXiv препринт RIVA: Leveraging LLM Agents for Reliable Configuration Drift Detection.
Работа интересна не столько результатами (хотя они есть), сколько постановкой задачи. Авторы формализуют детектирование дрейфа как задачу reasoning, а не pattern-matching. Это принципиальный сдвиг.
Стандартные инструменты сравнивают атрибуты ресурсов по фиксированным правилам: «значение A должно равняться B». LLM-агенты в RIVA анализируют телеметрию и могут рассуждать о контексте: является ли это расхождение дрейфом или ожидаемым поведением системы?
Система состоит из двух агентов — verifier agent и tool generation agent — которые работают через итеративную кросс-валидацию. На бенчмарке AIOpsLab RIVA достигает 50% точности при наличии ошибочных ответов инструментов, против 27.3% у базового ReAct-агента.
Лично мне понравилось это исследование. Говорить о production-ready решении еще слишком рано, но подход почему-то нашел свой отклик в моей голове. Мы движемся в сторону, когда следующее поколение инструментов будет не просто сравнивать состояния, а понимать, что произошло и почему.
Помимо проблем есть и решения
Опишу несколько принципов, которые могут изменить архитектуру изменений
Policy as Code. Должен решить проблему обнаружения дрейфа не постфактум, а ДО применения
OPA (Open Policy Agent) с Conftest позволяет валидировать Terraform-планы до их применения. Политика может запрещать создание публичных S3-бакетов, Security Group с открытым 0.0.0.0/0, ресурсов без обязательных тегов.
Это не предотвращает ручные изменения через консоль, но блокирует закрепление «плохих» конфигураций через IaC-пайплайн.GitOps как архитектура. Все и так знают про этот подход, поэтому кратенько пробегусь.
GitOps с Flux или ArgoCD непрерывно сверяют желаемое состояние из Git с реальным.
Как описывает архитектуру askantech.com: «A reconciliation agent running inside your cluster continuously compares the desired state declared in Git against the actual state running in the cluster. When they diverge, the agent acts to bring the cluster back into alignment». Ручное изменение черезkubectlбудет замечено и откатано на следующем цикле синхронизации. На этом этапе CLI hotfixes отпадают и инженер уже должен уметь работать с манифестами.
Важно: это не просто «хранение манифестов в Git» - без активного reconciliation loop GitOps даёт только версионирование, но не предотвращение дрейфа. Об этом прямо говорит CNCF GitOps Working Group.Immutable Infrastructure. На мой взгляд самый дорогой подход.
Сам по себе подход схож с GitOps, но нет агента. Мы просто версионируем манифесты и тригерим CI/CD пайплайн.
Это философия, при которой инфраструктура не модифицируется - она пересоздаётся. Нужно изменить конфигурацию сервера? Уничтожить старый инстанс, создать новый.
На практике это означает: никаких SSH на продакшен, никаких kubectl edit в прод-кластере, никаких изменений ресурсов через консоль. Изменения только через код → CI/CD → пересоздание. Это еще не подняли тему stateful-сервисов.Drift Budget. Пока что самый пацифичный подход.
Концепция по аналогии с error budget из SRE: не стремиться к нулевому дрейфу (это недостижимо), а определить допустимый уровень и реагировать при его превышении.
Например:
- Ресурсы уровня Security - алертим везде, куда можем
- Ресурсы менее важного уровня (размер инстансов) - "в целом ок", но до следующего условного apply
- Теги и метаданные - "в целом ок"
Эту концепцию стоит применяеть там, где надо сфокусировать усилия команды там, где дрейф действительно опасен, а не гоняться за каждым расхождением.Просто не давать людям прав на запись и только read-only. Изменениями должна заниматься CI.
Как не надо
Пока готовил статью, наткнулся на несколько распространённых ошибок в подходах к проблеме. Ссылок не сохранил к сожалению, пишу по памяти.
«Просто запустить terraform apply почаще» - не решение. Частые apply без понимания контекста дрейфа могут уничтожить рабочие хотфиксы (как в моём кейсе) или вызвать неожиданные пересоздания ресурсов.
«Запретить всем доступ к консоли» - сомнительно. При реальном инциденте у людей должны быть инструменты для быстрого реагирования.
«Один инструмент всё решит» - нет такого инструмента. Driftctl, Spacelift, CloudQuery — всё это детекция, но не предотвращение. Реальное решение кроется не в одном инструменте, а в комбинации нескольких, например, Policy as Code + GitOps.
Если уже все случилось
Действуй по нарастающей:
terraform plan -refresh-only> посмотреть, что именно уехалоЕсли расхождение небольшое > внести правки в
.tfи применитьЕсли ресурс создан вне Terraform >
terraform importЕсли state сломан сильно >
terraform state rm+terraform importдля конкретных ресурсовРучное редактирование state-файла > крайний случай, когда расхождения копились месяцами
Важно: чем дольше дрейф существует, тем дороже его устранение. Это отдельный аргумент в пользу периодического plan -refresh-only по расписанию.
Выводы
IaC - необходимое, но недостаточное условие консистентности. Terraform решает задачу первичного развёртывания и версионирования инфраструктуры. Он не решает задачу непрерывной синхронизации с реальностью.
Дрейф - не следствие плохой дисциплины. Он структурно неизбежен в любой живой инфраструктуре: hotfixes - это рациональная реакция на инцидент, API провайдеров меняются, асимметрия знаний внутри команды существует даже при двух людях. Бороться надо не с причинами дрейфа, а с отсутствием механизма обратной синхронизации.
Детектирование != предотвращение. Весь существующий инструментарий показывает дрейф после того, как он случился. Предотвращение требует применение иных принципов: Policy as Code, continuous reconciliation, immutable infrastructure.
Безопасность - отдельная зона риска. Дрейф в конфигурациях безопасности (IAM, Security Groups, storage policies) может быть незамечен годами - как в кейсе Microsoft. Для этих ресурсов нужен отдельный, более строгий режим контроля.
LLM-агенты для reasoning о дрейфе. Проект RIVA из EPFL показывает, что следующее поколение инструментов будет не просто сравнивать атрибуты, но понимать контекст изменений. Это потенциально меняет игру - но пока в исследовательской фазе, хотя хотелось бы пощупать на своей лабе.
Я бы помусолил еще эту тему, возможно я что-то упустил или не знаю о каких-то реальных практиках, которые уже закрывают эту проблему. Возможно, для кого-то моя статья станет подспорьем для будущих исследований.
Полезные ссылки
Дублирую сюда источники, используемые в тексте, и даже чуть больше.
RIVA: LLM Agents for Reliable Configuration Drift Detection (arXiv, 2025) — академическая формализация проблемы
Wiz: 38 TB Microsoft Data Exposure (2023) — разбор реального инцидента
GitGuardian State of Secrets Sprawl 2024 — статистика по утечкам секретов
The Terraform Scaling Problem (InfoWorld, 2026) — обзор проблем масштабирования IaC
Spacelift: Terraform Drift Detection Guide — практический разбор инструментов
Terramate: Ultimate Guide for Drift Detection — сравнение подходов
GitOps Best Practices with FluxCD and Terraform — практическая реализация continuous reconciliation
DORA Metrics History — метрики стабильности DevOps
Дрейф Terraform: как незаметно сломать инфраструктуру (Хабр) — русскоязычный разбор механики дрейфа
GitOps: Определение дрейфа Terraform/Terragrunt (Хабр) — практический подход к мониторингу дрейфа через GitLab CI
HashiCorp: Manage Resource Drift (официальная документация) — официальный туториал по работе с дрейфом
