Продолжаем готовить для вас переводы статей о разработке и эксплуатации инфраструктурных решений. Сегодня разбираемся в том, как при работе с Terraform возникает «дрейф» (drift), на основе материала в блоге Lead DevOps Engineer Saijal Shrivastava.
Если вам когда-либо приходилось расследовать загадочные проблемы с инфраструктурой, вы наверняка сталкивались с дрейфом. Так почему он доставляет столько неприятностей и как порождает для инженеров ситуации в духе «кто ел из моей миски»?

Что вообще такое «дрейф» в Terraform?
У каждого супергероя неизбежно найдется слабость, и криптонитом Terraform является дрейф. По сути, это разновидность неконсистентности. Дрейф случается, когда описанная в коде инфраструктура перестает совпадать с реальным положением дел в облаке.
Идея Infrastructure as Code (IaC), которую реализует Terraform, заключается в том, чтобы сделать инфраструктуру предсказуемой и воспроизводимой. Если появляется дрейф, эта предсказуемость нарушается.
Terraform полагается на файл состояния (state file), создающийся на основе примененных конфигурационных файлов (.tf file), чтобы хранить в памяти данные о развернутых ресурсах. Если изменения происходят в обход Terraform, например при ручном обновлении или использовании автоматизации, полагаться на файл состояния и, соответственно, конфигурационный файл, больше нельзя.
Ситуация напоминает путешествие с картой, которая вдруг перестала соответствовать реальной местности. Незамеченная вовремя небольшая ошибка ведет к путанице, рискам безопасности и операционным проблемам.
“...мы меняем ландшафты, причем вручную”

Например, Terraform разворачивает инстанс EC2, а позже кто-то изменяет настройки группы безопасности прямо из консоли AWS, в обход системы IaC. Terraform остается в неведении до тех пор, пока вы не запустите обновление состояния (state refresh). Как итог, «желаемое состояние» по версии Terraform вступает в конфликт с «реальным», что вызывает проблемы при развертывании и неожиданное поведение.

Почему дрейф в Terraform — это больше чем просто неудобство
Дрейф — это серьезная проблема инфраструктуры, которая может перерасти в критические сбои, риски безопасности и снижение продуктивности. Перечислим основные угрозы, к которым может привести дрейф.
Подрыв целостности подхода Infrastructure as Code
Основная цель Terraform — обеспечить повторяемость и согласованность в управлении инфраструктурой. Описывая инфраструктуру декларативно, он гарантирует, что развертывания предсказуемы и воспроизводимы. Однако дрейф подрывает этот принцип, вызывая расхождения между кодовой базой (подразумевается набор конфигурационных файлов и файлов состояний — прим. “Базис”) и реальным развернутым окружением. Несоответствия возникают из-за таких факторов, как ручные вмешательства и неcмерженные пул-реквесты в конфигурационных файлах, описывающих инфраструктуру.
В итоге Terraform теряет надежность и не может выполнять свои задачи. Это приводит к отклонениям, порой неожиданным. Менеджмент инфраструктуры тонет в ошибках, а поддержка превращается в испытание.
Пример
Ваша конфигурация Terraform определяет пять инстансов, но два из них были удалены вручную, в обход Terraform. Поскольку файлы состояния и конфигурации не изменились, Terraform по-прежнему считает, что все пять существуют. При следующем запуске plan Terraform обнаружит несоответствие и неожиданно пересоздаст недостающие инстансы. Такое непреднамеренное выделение ресурсов может повлиять на их распределение, увеличить затраты, нарушить механизмы автомасштабирования и создать риски безопасности из-за неконсистентных конфигураций инфраструктуры.
Сбои при развертывании и неожиданные ошибки
Дрейф нарушает консистентность инфраструктуры. Закономерный итог — сбои при развертывании. Например, Terraform может попытаться создать ресурс, который уже был создан вручную, или попытаться удалить активный ресурс. Причина в том, что зависимости существуют вне зоны контроля Terraform.
Также он может неверно интерпретировать устаревшие конфигурации, что приведет к некорректным обновлениям. Эти несоответствия нарушают автоматизацию, делают инфраструктуру ненадежной и увеличивают риск непреднамеренных простоев или уязвимостей.
Пример
Если политика резервного копирования базы данных была изменена вручную вне Terraform, следующий запуск приведет к перезаписи ручных обновлений (это обусловлено тем, что в конфигурационных файлах указана старая политика, поэтому при обновлении файла состояний произойдет изменение инфраструктуры в вид, описанный в конфигурации, — прим. “Базис”). Дрейф, развивающийся по такому сценарию, внесет неопределенность в управление инфраструктурой. Даже незначительные обновления влекут за собой операционные риски.
Превращает отладку в страшный сон
Поиск первопричины изменений конфигурации может быстро превратиться в упражнение по сбору головоломки с очень плохой документацией. Было ли отклонение вызвано незадокументированным изменением в AWS? А может, мы ищем невмерженный пул-реквест? Или стоит отследить локальные запуски в обход инструментов автоматизации?
Поиск ответов на эти вопросы способен значительно замедлить выпуск фич и новых версий, включая содержащие критические исправления.
Комментарий от инженеров “Базиса”: исправление ошибок и неточностей, как и поиск причин, требует времени. Зачастую – очень много времени. Большинство систем автоматического развертывания приложений так или иначе опираются на Terraform, поэтому неработоспособность конфигурации приводит и к неработоспособности конвейеров автоматизации.
Пример
Отсутствующее правило файрвола заставило всю команду безопасности панически искать, в какой момент оно выпало из среды продакшена. В Terraform не было никаких признаков удаления правила, на проблему указывал только эмпирически наблюдаемый дрейф.
Несоответствие заставило инженеров потратить массу времени и сил на утомительные поиски. После нескольких часов кропотливого перебора вариантов они наконец отследили первопричину до невмерженного пул-реквеста, который непреднамеренно дал Terraform команду удалить критически важное правило.
Создает риски безопасности и нарушения комплаенса
Помимо простых операционных неудобств дрейф инфраструктуры представляет угрозу для безопасности и соответствий. Неотслеживаемые и незадокументированные изменения создают уязвимости, открывая путь для атак злоумышленников.
Дрейф может пробить брешь в системах защиты сразу несколькими способами:
добавленные вручную правила групп безопасности могут случайно открыть порты;
IAM-роли, измененные вне Terraform, могут предоставлять избыточные привилегии;
просроченные сертификаты могут нарушать соединения и вызывать сбои;
изменения в обход систем логирования и мониторинга могут серьезно затруднить обнаружение инцидентов безопасности.
Пример
С виду безобидное ручное исправление, предназначенное для временной отладки, непреднамеренно открыло порт 22 (SSH) для всего интернета. К сожалению, инженер забыл отменить изменение. Terraform, не зная о ручной правке, не идентифицировал уязвимость. Зато брешь не обошли вниманием злоумышленники, произведя полномасштабный взлом.
Сценарий иллюстрирует, как дрейф сводит на нет практики по укреплению безопасности. Истинный масштаб уязвимости остается неизвестным, пока не станет слишком поздно.
Кто виноват? Типичные виновники дрейфа
Дрейф в Terraform не приходит один. Выводим на опознание его основных спутников и сообщников, которые делают дрейф возможным.
Сценарий 1. Невлитые пул-реквесты, или Призрачные изменения
Terraform полагается на идеальное соответствие между файлом состояния и конфигурационными файлами. Однако если пул-реквест (PR) изменяет инфраструктуру, но не вливается в основную ветку, в файле состояния сохраняются обновления, которых нет в конфигурации. Terraform «убежден», что параметры верны, но у конфигурационных файлов своя версия событий.
Эта несогласованность вызывает дрейф. Последующие запуски Terraform сталкиваются с несоответствиями, ошибочными планами выполнения, а в худшем случае приводят к удалению критически важных ресурсов. Казавшаяся незначительной ошибка начинает расти как снежный ком и может привести к глобальным операционным проблемам.
Как это приводит к дрейфу
Допустим, разработчик отправляет пул-реквест с изменениями. Они применяются, обновляют окружение и файл состояния. Однако сам PR остается невмерженным. Что происходит дальше? Файл состояния отображает изменения, которые отсутствуют в основной ветке.
Позднее другой разработчик запускает terraform plan. Terraform обнаруживает расхождения и рекомендует удалить проблемные ресурсы. Бездумного выполнения terraform apply в этом случае достаточно для уничтожения критической инфраструктуры, приводящего к перебоям в работе.
Пример
С помощью Terraform подготовлен балансировщик нагрузки.
Изменения успешно применены и информация о них сохранена в файле состояния, но…
Пул-реквест по недосмотру не смержили.
Другой инженер запускает terraform plan.
Terraform не находит балансировщик в коде, решает, что тот был вручную удален.
Terraform предлагает удалить ресурс из инфраструктуры.
Как видите, всего одно исполнение terraform apply — и сбой становится неизбежным. А начиналось все с простой невнимательности и оплошности при мерже.

Сценарий 2. Частичные применения (Partial Applies), или Торт без сахара
Допустим, вы отправляете пул-реквест, который обновляет директории network/ и compute/, но применяете изменения только для network/, оставляя compute/ неизменным. Эта несогласованность, намеренная или случайная, приводит к дрейфу инфраструктуры.
Это как если бы вы испекли торт, но забыли добавить сахар. Рецепт (конфигурация Terraform) правильный, но результат (инфраструктура) — нет. Будет казаться, что все в порядке, пока торт кто-то не попробует. Несовпадение порождает непредвиденное поведение системы, превращая отладку в сущий кошмар.
Как именно это приводит к дрейфу?
Так как в файле состояний записана лишь часть внесенных изменений, при запуске terraform plan разработчик получает запутанную смесь старых и новых конфигураций. Обнаружив ошибку, Terraform может попытаться откатить изменения или даже пересоздать ресурсы, вызывая каскад сбоев.
Пример
Разработчику необходимо обновить сетевые правила и вычислительные экземпляры для поддержки новой службы.
Для этого он вносит изменения в две директории:
изменяет network/ — например, настройку групп безопасности и подсетей;
изменяет compute/ — к примеру, обновление типов экземпляров и политик масштабирования.
Изменения применяются лишь к network/, а про compute/ почему-то забыли.
Через неделю другой разработчик запускает terraform plan и сталкивается с предложением Terraform внести конфликтующие изменения в compute/.
Начинается путаница — возникают старые типы инстансов, в плане копятся противоречия.
Если не разобраться в происходящем и применить plan неверно, путаница может привести к поломке окружения.

Сценарий 3. Пропуск и plan, и apply одновременно. Идеальный дрейф
Давайте признаем: некоторые наши коллеги просто любят риск. Искатели адреналина от инженеров автоматизации отправляют пул-реквесты, не запуская ни plan, ни apply. Закономерным исходом становится ситуация, когда конфигурационная база развивается, но изменения не доходят до актуальной инфраструктуры, и она как будто застывает во времени.
Файл состояний же «остается в неведении», открывая возможности для дрейфа и возможных ошибок в конфигурации, что делает наступление хаоса лишь вопросом времени.
Как этот сценарий приводит к дрейфу?
Для возникновения дрейфа создаются идеальные условия: изменения вносятся без верификации через terraform plan или apply. Инженер обновляет конфигурацию и мержит пул-реквесты, не внося никаких изменений в инфраструктуру. Файл состояний при этом не меняется, и в следующий раз при запуске terraform plan противоречия выходят на поверхность.
Рецепт «идеального дрейфа»
Разработчик меняет правила безопасности.
Не выполняет ни plan, ни apply.
Конфигурация обновилась, но файл состояния — нет.
Х дней спустя коллега применяет несвязанные изменения и обнаруживает, что Terraform пытается пересоздать группы безопасности, рискуя разорвать активные соединения.
От сбоя систему теперь отделяет лишь один необдуманный terraform apply.

Сценарий 4. Локальные изменения в Terraform
Зачастую проблемой становится игнорирование возможностей автоматизации вроде Atlantis, Terraform Cloud или CI/CD-пайплайнов. Инженеры могут заниматься партизанщиной и запускать Terraform с локальных машин, что на первый взгляд может показаться безобидной и даже логичной идеей.
На деле такой подход зачастую оборачивается бомбой замедленного действия, заложенной под фундамент цифровой инфраструктуры. Запуск terraform apply локально, в обход инструментов для автоматизации и командной работы, приводит к изменениям только в файле состояний на локальной машине. И вновь при повторном запуске Terraform предложит удалить или пересоздать недостающие ресурсы.
Возвращаясь к кулинарным метафорам, это все равно, что придумать новый рецепт, не обновив запись в поваренной книге. Теперь когда кто-то решит приготовить блюдо, он не только воспользуется старой инструкцией, но и удалит все ваши изменения в рецепте.
Пример
Разработчику нужно изменить группу безопасности AWS.
Он обходит стандартные протоколы и запускает terraform apply локально.
Хотя группа безопасности успешно обновляется, общий файл состояний остается без изменений.
Неделю спустя другой инженер запускает terraform plan.
Terraform, не зная о локальном изменении, помечает группу безопасности на удаление.
Группы безопасности удалена, потоки трафика тонут в пучине хаоса.

Сценарий 5. Ручные изменения в AWS
Думаете, ничего хуже локального запуска Terraform уже не придумать? Тогда попробуйте начать вносить ручные правки в AWS. Будь то горячее исправление, быстрая проверка гипотезы или даже продуманное внесение изменений — ручные правки могут полностью миновать Terraform. Что, разумеется, откроет окно возможностей для хаоса и непредвиденных перезаписей.
Как редактирование AWS провоцирует дрейф?
Инженер вручную вносит изменения напрямую в AWS — правит политику автомасштабирования, корректирует правила безопасности, обновляет AMI. Файл состояний Terraform не обновляется, и следующего пользователя ожидает сюрприз. Ручные изменения идентифицируются как дрейф и откатываются.
Это создает опасную ситуацию, в которой для потери модификаций достаточно одной команды. Если вовремя не понять, что происходит, исполнительный Terraform удалит все внесенные вручную изменения, включая критические корректировки, и нарушит работу продакшена.
Пример
Обновления в Auto Scaling Group вносятся во время критического инцидента, чтобы использовать новую версию AMI и стабилизировать сервис.
Угроза миновала, о ручных обновлениях все забыли.
Проходит время, другой сотрудник запускает terraform apply для внесения не связанных с инцидентом изменений.
Terraform обнаруживает несоответствие в ASG, восстанавливает старый AMI из файла состояния и конфигурации.
Сервис откатывается назад, вызывая простой.
-
Перезапись изменений отменяет и критически важное исправление.
Причем с точки зрения Terraform все логично — он просто восстанавливает консистентность.

Дрейф растет с масштабированием. Выводы
Коварная природа дрейфа инфраструктуры приводит к экспоненциальному росту проблем по мере масштабирования. То, что начинается с незначительного расхождения в небольшой системе, превращается в совершенно неуправляемую ситуацию, когда речь идет о сотнях или тысячах ресурсов.
Без автоматизации дрейф действует как тихая разрушительная сила, постепенно подрывая надежность и целостность инфраструктуры. Как термиты, он способен долго и планомерно «подтачивать» несущую конструкцию, ослабляя ее: о проблеме можно узнать уже когда дом начал рассыпаться на части.
Вместо послесловия
Разобранные сценарии могут показаться пугающими, но главная мысль заключается не в том, что Terraform — ненадежный инструмент. Напротив! Дрейф — это (почти) всегда не симптом проблем с технологией, а показатель несогласованных «человеческих процессов». Будь то недостаток коммуникации или излишняя вера в силу ручных правок.
Борьба с дрейфом начинается не с поиска волшебного инструмента, а с выстраивания надежных CI/CD-пайплайнов, строгих правил код-ревью и, самое главное, выработки осознанности и ответственности за каждый коммит. Это и есть фундамент для построения по-настоящему предсказуемой и стабильной инфраструктуры.
Несколько советов
В качестве постскриптума приведем несколько советов от наших инженеров.
Как избежать дрейфа?
Если несколько простых правил, которые лежат на поверхности, но ими довольно часто пренебрегают.
Самое главное правило: при работе с Terraform важно помнить, что этот инструмент теперь — единственное хранилище истины об инфраструктуре. Если нужно что-то поменять или выполнить — делать это стоит только с помощью Terraform.
В случае возникновения экстренных случаев (все мы не без греха, и первое правило в таких ситуациях иногда нарушается), когда требуется внести правки в инфраструктуре, все изменения должны быть отражены в конфигурациях Terraform и его файлах состояний. Чем быстрее — тем лучше. Это позволит избежать накопления расхождений.
Процесс изменения конфигурации должен быть налажен и доведен до каждого участника команды, ответственной за инфраструктуру. Наладить следует и регулярную проверку PR, тестовые запуски (при возможности), ревью старшими членами команды.
Нельзя использовать terraform apply (особенно с флагом -auto-approve) без предварительной проверки конфигурации с помощью terraform plan — это позволит избежать неожиданного поведения, так как terraform plan выстроит карту изменений и сообщит об этом инженеру. Terraform apply, конечно, тоже построит предварительный план действий и запросит подтверждения, но все-таки лучше использовать предварительный terraform plan.
При внесении правок в конфигурацию и файл состояния с локальной машины необходимо все изменения направить в общие файлы.
Описанные конфигурации следует применять всегда.
Лечение дрейфа
Конечно, предотвратить проще, чем лечить, но если дрейф уже возник, его надо устранять. Вот самые распространенные способы лечения, пункты отсортированы по нарастанию боли от их использования:
Мердж всех изменений и PR.
Внесение правок в конфигурации и применение новых конфигураций для формирования актуального состояния.
Внесение правок в конфигурацию, удаление «сломанных кусков» состояний с помощью terraform state rm и импортирование c помощью terraform import актуальных состояний инфраструктуры.
Внесение правок в конфигурацию, ручное внесение правок в файл состояний. Данный вариант используется в крайнем случае, при развале файла состояний из-за слишком больших, месяцами копившихся расхождений инфраструктуры с теми данными, которыми оперирует Terraform.
Стоит помнить, что чем дольше копятся изменения, которые не нашли свое отражение в файле состояния и в конфигурации, тем больше проблем доставит восстановление работоспособности Terraform. Все правки необходимо делать вовремя, не откладывая «на потом». Это позволит избежать головной (и не только) боли в будущем.
Комментарии (4)
ElDark
22.08.2025 11:32это (почти) всегда не симптом проблем с технологией, а показатель несогласованных «человеческих процессов»
И это верно (почти) для любой технологии. Процессы еще можно настроить, хотя и требует времени, а вот стремление лезть руками куда не нужно и оставлять бардак - неистребимо.
white_crow
22.08.2025 11:32>разрешение "terraform apply" только из мейна
и дополнительно:
- запрет эплаить с локальных машин на прод (тупо права/креды для людей только рид онли). Креды на запись - только у CI (ну, разумеется у ограниченного круга опытных и ответвенных лиц права на запись будут - но они все равно в обычном режиме должны катить через git/CI/IaС - и лишь в экстренных случаях что-то трогать на проде вручную, а потом устранить дрифт)
- чоткое разделение окружений и прав + аудит (в облаках с этим все шикарно)
- сначала в CI должен быть степ plan в файл, и следующий степ apply из этого файла (после апрува)
- настройте конфиг - чтобы стейт хранился в облаке (S3) + сделайте автобэкап этого S3 в другой регион (можно даже в рид онли контейнер)
- периодический автоматический процесс поиска дрифта (запуск плана - и если что-то уехало - нотификация)
- изменение архитектуры, обновление терраформа или провайдеров - сначало через тестовые окружения
- и старайтесь сразу заюзать терраформ - ибо импорт потом делать больно, особенно когда у вас юзаются terraform модули, а скорее это иерархия модулей. (как бы не хотелось пока временно быстро потыкать все мышкой или CLI)
- В реальности невозможно покрыть всю инфру на 100% терраформом - 80% это уже хороший результат. Не стращно, что что-то делается руками, скриптами, джобами - но не терраформом - главное это документировать. Просто иногда проще в 10 раз что-то сделать руками (специфические сервисы или настройки), особенно если это делается редко или даже 1 раз при разворачивании нового окружения, ибо кое какие вещи будут вызвать боль, если их пытаться делать терраформ, а потом вносить изменения
Тот самый принцип парето))
Ну, всмысле - не стоит в падать в крайности и фанатизм некоторых догм типа IaC )))
- Юзайте всякие обертки над терраформом для layering и DRY (Dont Repeat Your Self (типа terragrunt, terraspace)
- Старайтесь не писать свои сложные модули без крайней необходимости - уже давно есть куча готовых и годами проверенных комьюнити - (KISS)
И ваши коллеги , особенно если вы потом сдрисните,поставят вам свечку за здравиескажут вам спасибо ))
white_crow
22.08.2025 11:32И да, статья поднимает интересную тему. Но много воды, повторы одногои того же тезиса разными словами. И примеры примитивные. Вот у меня были в опыте всякие хитрожопые нюансы, связанные с териком, с авс. И часто, по не опытности или тупости, иногда потому ,что меняются апишка авс, добавляются и удоляются фичи и опции. Обновляются модули и провайдеры, а у тебя эплай на прод ломается, и ни туда и ни сюда - приходится аккуратно разруливать руками... Более подробно нет магчымасцi написать)
amarkevich
разрешение "terraform apply" только из мейна (ну и в дев окружении)