Когда инфраструктура меняется вне вашего пайплайна: дрейф, политики и практическое управление

Представьте: вы на дежурстве в 2 часа ночи. Произошел инцидент в продакшене, и кому-то из команды нужно временно открыть порт в security group для отладки проблем с подключением. Они заходят в облачную консоль, вносят изменение, инцидент решен. Все облегченно вздыхают.

Через три недели при плановом аудите безопасности вы обнаруживаете, что этот порт все еще открыт на весь интернет. Никто не вспомнил его закрыть. Никто не задокументировал изменение. А ваш пайплайн infrastructure-as-code по-прежнему считает, что security group заблокирована.

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

Почему запрет ручных изменений не работает

Очевидный ответ — просто запретить все ручные изменения. Все должно проходить через пайплайн. Без исключений.

На практике этот подход проваливается по трем причинам.

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

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

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

Лучший подход — не запрещать ручные изменения, а управлять ими.

Политика как код: правила, которые действительно работают

В большинстве организаций есть политики по изменению инфраструктуры. Обычно они записаны где-то в документе: «Все изменения в продакшене должны проходить через процесс управления изменениями». Но документы ничего не контролируют. Они просто лежат.

Политика как код меняет это. Инструменты вроде Open Policy Agent (OPA) или HashiCorp Sentinel позволяют писать правила в коде и привязывать их к точкам контроля. Когда кто-то пытается изменить ресурс через облачную консоль или поступает прямой API-запрос, движок политик оценивает запрос на соответствие вашим правилам, прежде чем разрешить его.

Вот конкретный пример. Вы пишете политику: «Ни одна security group не может иметь порт 22, открытый на 0.0.0.0/0, если изменение не пришло через утвержденный пайплайн». Когда инженер в панике во время инцидента пытается открыть SSH на весь мир из консоли AWS, политика блокирует изменение. Или, как минимум, логирует попытку и требует дополнительного одобрения.

Например, вот политика HashiCorp Sentinel, которая требует, чтобы каждый ресурс имел тег managed-by, гарантируя отслеживаемость изменений вне пайплайна:

# Требует, чтобы все ресурсы имели тег "managed-by"
import "tfplan/v2" as tfplan

# Получаем все ресурсы, которые будут созданы или обновлены
all_resources = tfplan.resource_changes.all

# Правило: каждый ресурс должен иметь тег "managed-by"
mandatory_tag = "managed-by"

main = rule {
  all all_resources as _, rc {
    rc.applied.tags[mandatory_tag] else null != null
  }
}

Эта политика интегрируется в ваш CI/CD пайплайн как защита. Если ресурс развертывается без тега, пайплайн завершается ошибкой, предотвращая попадание неотслеживаемых изменений в продакшен.

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

Проектирование политик, которые не ломаются под давлением

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

Решение — проектировать политики с учетом операционной реальности.

Один из паттернов — механизм break-glass. В определенных задокументированных чрезвычайных ситуациях инженер может переопределить политику. Переопределение логируется с указанием причины, а после инцидента команда решает, нужно ли принять изменение в IaC или откатить его. Это дает безопасность без паралича.

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

Связь политики с обнаружением дрейфа

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

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

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

flowchart TD A[IaC Pipeline] -->|Deploy| B[Infrastructure] C[Manual Change] -->|Emergency or direct action| B B -->|Drift Scanner| D{Drift Detected?} D -->|Yes| E[Policy Engine] D -->|No| F[No Action] E --> G{Policy Check} G -->|Approved Exception| H[Mark as Known & Allowed] G -->|Violation| I[Flag for Remediation] G -->|No Match| J[Queue for Manual Review] H --> K[Post-Incident Review] I --> K J --> K K -->|Adopt into IaC| A K -->|Roll back| B

Если изменение было сделано через утвержденное исключение из политики, оно помечается как «известное и разрешенное». Если изменение нарушает политику, оно помечается для немедленного исправления. Если изменение не соответствует ни одному правилу политики, оно попадает в очередь на ручную проверку.

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

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

Практический чек-лист для управления на основе политик

Если вы настраиваете политики и управление для изменений инфраструктуры, вот краткий чек-лист для проработки:

  • Определите типы изменений, которые наиболее рискованны в вашей среде (security groups, конфигурации БД, IAM-роли)
  • Напишите политики, которые блокируют эти изменения вне пайплайна, с четкими путями для исключений
  • Внедрите механизм break-glass для чрезвычайных ситуаций с обязательным постинцидентным анализом
  • Подключите ваш движок политик к инструментам обнаружения дрейфа
  • Классифицируйте изменения по уровню риска и применяйте разные правила соответственно
  • Настройте автоматическое аудиторское логирование для каждого решения политики
  • Регулярно пересматривайте исключения из политик и принимайте их в IaC или откатывайте

Вывод

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

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