Когда автоматическое восстановление инфраструктуры делает только хуже

Два часа ночи. Ваше production-приложение начинает выбрасывать ошибки пула соединений. Дежурный инженер прыгает в облачную консоль, меняет параметр базы данных — система стабилизируется. Все выдыхают.

Через двадцать минут снова приходят оповещения. Те же ошибки. Инженер проверяет консоль и обнаруживает, что параметр сброшен на исходное значение. Ваш пайплайн infrastructure-as-code обнаружил ручное изменение как "дрейф" и автоматически его откатил. Теперь вы снова в инциденте, и цикл будет повторяться, пока кто-нибудь не отключит механизм автоматической реконсиляции.

Этот сценарий не гипотетический. Именно так происходит, когда автоматическая реконсиляция считает любое отклонение от кода проблемой, которую нужно исправить.

Проблема предположения, что любой дрейф — это плохо

Автоматическая реконсиляция звучит идеально на бумаге. Ваш пайплайн обнаруживает, когда реальная инфраструктура отклонилась от того, что определено в коде, и автоматически применяет корректное состояние. Никакого вмешательства человека. Никакого окна для сохранения дрейфа.

Но основное предположение ошибочно: не всякий дрейф — это ошибка. Иногда изменения вне пайплайна происходят по легитимным причинам, и именно эти изменения поддерживают систему в рабочем состоянии.

Во время инцидента инженеры вносят экстренные изменения. Во время миграции базы данных команды временно модифицируют ресурсы в рамках тщательно спланированной процедуры. Во время нагрузочного тестирования параметры масштабирования корректируются на лету. Это всё валидные причины иметь инфраструктуру, не соответствующую вашему репозиторию кода.

У автоматической системы реконсиляции нет способа отличить разрушительное изменение от спасительного. Она знает только, что фактическое состояние отличается от желаемого, и её задача — восстановить желаемое состояние. У неё нет контекста о том, почему было сделано изменение, происходит ли сейчас инцидент или прошло ли изменение валидацию командой.

Когда время делает всё хуже

Время автоматической реконсиляции создаёт ещё одну категорию риска. Представьте команду в середине сложной миграции базы данных. Они намеренно вручную модифицируют несколько облачных ресурсов в рамках многошаговой процедуры, которая ещё не полностью отражена в IaC. Если пайплайн реконсиляции запустится в середине миграции, он может удалить ресурсы, находящиеся в переходном состоянии, что приведёт к потере данных или полному сбою миграции.

Это не теоретический граничный случай. Миграции, обновления инфраструктуры и реагирование на инциденты безопасности — всё это включает временные состояния, когда живая среда намеренно отличается от кодовой базы. Автоматическая реконсиляция, запущенная в эти окна, вызывает не просто неудобства. Она может повредить данные, сломать работающие сервисы или отменить критические меры безопасности, которые были применены вручную, потому что ситуация требовала скорости, а не процесса.

Контроль риска без отказа от автоматизации

Ответ не в том, чтобы полностью отключить автоматическую реконсиляцию. Ответ в том, чтобы построить средства контроля, соответствующие тому, как реально работают операции.

Следующая диаграмма иллюстрирует проблемный цикл автореконсиляции и точки, где предлагаемые средства контроля вмешиваются.

flowchart TD A[Обнаружен дрейф] --> B{Шлюз утверждения?} B -- Нет --> C[Автооткат] C --> D[Инцидент повторяется] D --> A B -- Да --> E[Ручная проверка] E --> F{Легитимный дрейф?} F -- Да --> G[Принять в код] F -- Нет --> H[Безопасная реконсиляция] I[Окно реконсиляции] --> B J[Заморозка изменений] --> B K[Правила исключения] --> A

Шлюзы утверждения для реконсиляции

Вместо того чтобы пайплайн автоматически применял изменения при обнаружении дрейфа, заставьте его остановиться на этапе проверки. Отправьте уведомление соответствующей команде с деталями того, что изменилось. Требуйте утверждения перед запуском реконсиляции. Это даёт команде время проверить, следует ли откатить дрейф или принять его в кодовую базу.

Это не означает медленных операций. Хорошо спроектированный процесс утверждения может быть быстрым. Ключевое в том, что решение принимает человек, а не автоматизированная система, лишённая контекста.

Окна реконсиляции

Определите конкретные временные окна, когда автоматическая реконсиляция разрешена. Например, только с 9 до 17 в будние дни. Вне этих часов дрейф обнаруживается и сообщается, но не исправляется автоматически.

Это простое правило предотвращает сценарий инцидента в 2 часа ночи. Если экстренное изменение происходит ночью, пайплайн залогирует его и оповестит команду, но не отменит исправление до утра, когда кто-то сможет его должным образом проверить.

Заморозка изменений

Когда команда находится в периоде заморозки, отключите всю автоматическую реконсиляцию. Заморозки происходят перед крупными релизами, во время аудитов или критических миграций. Во время заморозки дрейф отслеживается и логируется, но никакие автоматические изменения не разрешены. Команда может повторно включить реконсиляцию после окончания заморозки и после подтверждения, что все легитимные изменения зафиксированы в коде.

Правила исключения для динамических ресурсов

Некоторые ресурсы по своей природе часто изменяются вне пайплайна. Группы авто-масштабирования регулируют размер в зависимости от нагрузки. Инструменты мониторинга автоматически настраивают конфигурации. Эти ресурсы следует исключить из автоматической реконсиляции или задать для них специальные правила, допускающие определённые типы дрейфа.

Например, в Terraform можно использовать блок lifecycle с ignore_changes, чтобы предотвратить откат пайплайном легитимных динамических корректировок:

resource "aws_autoscaling_group" "app" {
  name               = "production-app-asg"
  min_size           = 2
  max_size           = 10
  desired_capacity   = 4
  launch_configuration = aws_launch_configuration.app.id
  vpc_zone_identifier = ["subnet-abc123", "subnet-def456"]

  lifecycle {
    ignore_changes = [
      desired_capacity,
      min_size,
      max_size,
    ]
  }
}

Это указывает Terraform игнорировать изменения параметров масштабирования, так что ручное масштабирование во время пиков нагрузки не будет отменено.

Речь не о том, чтобы делать исключения из правил. Речь о признании того, что некоторая инфраструктура по своей сути динамична, и трактовка её нормальных операционных изменений как дрейфа создаёт больше проблем, чем решает.

Практический чек-лист

Перед включением автоматической реконсиляции для любой группы ресурсов проверьте следующие пункты:

  • Может ли команда переопределить или приостановить реконсиляцию во время инцидентов?
  • Определено ли окно реконсиляции, исключающее нерабочие часы?
  • Исключены ли динамические ресурсы, такие как группы авто-масштабирования, или для них заданы специальные правила?
  • Требует ли пайплайн утверждения человеком перед применением изменений реконсиляции?
  • Существует ли документированный процесс принятия легитимного дрейфа обратно в код?

Главный вывод

Автоматическая реконсиляция — это инструмент, а не политика. Она хорошо работает, когда ваша инфраструктура стабильна, все изменения проходят через пайплайн, а инциденты редки. Она работает против вас, когда операции хаотичны, случаются чрезвычайные ситуации и людям нужно принимать решения.

Команды, которые хорошо справляются с этим, не автоматизируют всё. Они автоматизируют обнаружение и уведомление о дрейфе, но оставляют решение о реконсиляции в руках человека. Они строят окна и заморозки, соответствующие их операционной реальности. Они исключают ресурсы, которые должны быть динамическими.

Ваша инфраструктура будет отклоняться от вашего кода. Часть этого дрейфа будет проблемой. Часть будет причиной, по которой ваш сервис остался в строю. Цель не в том, чтобы устранить дрейф. Цель в том, чтобы иметь достаточный контроль, чтобы знать, с каким типом дрейфа вы имеете дело, прежде чем действовать.