Policy as Code: почему ручные проверки не удерживают инфраструктуру
Ручные проверки инфраструктуры держатся на договорённости: ревью изменений работает, пока в команде есть человек, который помнит, что ресурсы нельзя открывать наружу, а сервисным учёткам не нужны права администратора. Как только поток изменений растёт или часть работы уходит подрядчику, договорённость перестаёт держать — план применяется быстрее, чем кто-то успевает прочитать разницу.
Точки отказа выглядят предсказуемо. На больших изменениях ревью превращается в формальность: четыреста строк в описании сети никто не разбирает построчно, а именно там и появляется открытый доступ. Окружения расходятся — согласованное для тестового контура в промышленном применяют с другими правами и параметрами. Дрейф конфигурации накапливается незаметно: правки через консоль не попадают в репозиторий, и следующее применение возвращает инфраструктуру не туда, где её оставили.
Policy as Code переносит эти правила из переписки в код, который проверяет план до применения. Sentinel и OPA описывают запреты декларативно: обязательные метки, разрешённые регионы, запрет неограниченных сетевых правил, требования к правам доступа. Проверка встроена в конвейер, поэтому отклонённые изменения не доходят до среды — с конкретной причиной и ссылкой на нарушенное правило, а не с сообщением «переделай».
Дальше разбираем, как это устроено на практике и что именно удерживает инфраструктуру в заданных границах.
Что меняется после внедрения автоматических проверок
Политики на Open Policy Agent или Sentinel описываются декларативно и подключаются к конвейеру между описанием инфраструктуры и её применением. Поэтому запрет срабатывает на этапе планирования изменений, а не в момент развёртывания: инженер видит причину отказа в выводе обычной команды и правит конфигурацию до того, как она коснётся рабочей среды.
- Время проверки изменений. Ручной разбор, который занимал у ревьюера от получаса до нескольких часов, заменяется прогоном политик по плану — вердикт приходит вместе с результатом сборки, обычно за минуты.
- Доля отклонённых изменений. Порядка трети запросов не проходит проверку автоматически: открытые наружу порты, публичные хранилища, отсутствующие метки, слишком широкие права. Эти правки просто не доходят до среды.
- Классы отказов, которые уходят. Несоответствие политике безопасности, расхождения между средами, изменения, сделанные руками в обход конфигурации, и постепенное разрастание прав.
- Доля инцидентов. Происшествия, вызванные конфигурацией, перестают быть основной причиной сбоев, а разбор каждого случая занимает меньше времени — видно, какая политика и какое изменение его допустили.
- Ускорение выпуска и простой. Окно восстановления при откате сокращается с часов до минут: конфигурация воспроизводима, а предыдущее состояние разворачивается тем же способом, что и текущее.
Проверки не заменяют ревью, а снимают с него механическую часть: человек смотрит на архитектурные решения, а не на список открытых портов. Набор политик при этом расширяется постепенно — начиная с запретов на критичное и добавляя правила по мере накопления отказов.
Подходы к контролю инфраструктуры: сравнение вариантов
Выбор варианта определяет, на каком шаге нарушение будет поймано. Отклонённый план правится минутами, а откат уже применённого изменения затрагивает живые ресурсы, поэтому варианты сравниваем по точке перехвата и цене сопровождения, а не по «мощности» языка правил.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Встроенный движок политик платформы (Sentinel) | Весь ландшафт в одной платформе, нужны проверки между планом и применением | Правила привязаны к платформе: при переезде их описывают заново, выразительность языка ограничена задачами платформы |
| Внешний движок политик (OPA) | Несколько платформ и контуров, одно правило должно работать везде, включая кластеры и конвейеры сборки | Нужен свой слой доставки и версионирования политик, а состояние плана передаётся в отдельном формате |
| Проверки в репозитории | Нужен отклик до обращения к платформе: соглашения об именовании, обязательные теги, структура модулей | Видят исходники, но не вычисленные значения плана — часть нарушений всплывёт позже |
| Ручное ревью | Редкие изменения и ранняя стадия, когда правила ещё не устоялись | Не масштабируется: с ростом числа команд растёт срок согласования и доля пропущенных нарушений |
Рабочий контур обычно собирается из связки: быстрые проверки в репозитории отсекают очевидное, встроенный движок проверяет план перед применением, внешний держит общие правила для нескольких контуров. Дальше разбираем, как собрать такую связку и не дублировать правила между слоями.
Этапы внедрения Policy as Code: от аудита до передачи
Порядок этапов здесь не формальность: если сразу включить блокировку, конвейер сборки встанет на первом же слиянии, и команда вернётся к правкам вручную. Поэтому сначала описываем текущее состояние, потом формулируем правила в предупреждающем режиме и только после проверки на стенде переводим их в блокирующие.
- Аудит репозиториев и состояний. Собираем перечень корневых модулей, где хранится состояние, кто и как часто вносит изменения, какие ресурсы создаются вне общего шаблона. На выходе — карта зон риска: открытые порты, публичные хранилища, ресурсы без тегов и владельца.
- Схема политик. Классифицируем правила на три группы: обязательные (безопасность и доступы), организационные (нейминг, теги, регионы) и гигиенические (запрет устаревших типов ресурсов). Для каждого правила фиксируем область применения и уровень — блокирующий или предупреждающий.
- Привязка правил к стадиям Terraform. Часть проверок выполняется по плану до применения — они ловят ошибку до создания ресурсов, часть по факту применения, часть в ходе ревью. Так разработчик получает обратную связь за секунды, а не после развёртывания.
- Настройка режимов. Блокирующий режим включаем только для правил с нулевым числом ложных срабатываний, остальные ведут в журнал. Исключения оформляем явно — с обоснованием, ответственным и сроком пересмотра, чтобы не накапливались вечные обходы.
- Проверка на стенде. Прогоняем политики на копии реальных конфигураций: считаем долю срабатываний, разбираем спорные случаи, замеряем, насколько выросло время проверки. После этого правила переносятся в общий контур.
- Передача. Отдаём репозиторий с политиками, схему их устройства, регламент изменения и добавления правил, инструкции для разработчиков. Дальше команда заказчика ведёт правила сама — правки проходят то же ревью, что и код.
Артефакты внедрения: библиотека политик, схемы, регламенты
Внедрение Policy as Code проверяется не в день запуска, а в тот момент, когда правило нужно поправить, а автора уже нет на проекте. Поэтому мы передаём не настроенный инструмент, а рабочую систему — набор артефактов, по которым ваша команда меняет правила сама, без нас.
- Библиотека политик — правила Sentinel и Rego, разложенные по доменам: сеть, шифрование, теги, лимиты ресурсов. У каждого правила описание, пример срабатывания и собственный тест.
- Схема зависимостей — карта модулей и outputs: что читает чужие значения, где общий state, какие правки задевают соседние компоненты и требуют одновременного изменения.
- Матрица доступа — кто инициирует изменение, кто подтверждает, для каких ресурсов нужно ручное согласование, а что проходит автоматически по результату проверок.
- Регламент изменений — порядок выката нового правила: сначала режим предупреждения, затем мягкий запрет, затем жёсткий, с прогоном на исторических конфигурациях до включения.
- Инструкция для разработчика — как прогнать политики локально до отправки кода, как читать вывод об отказе и что делать при ложном срабатывании.
- Каталог исключений — оформленные отступления с владельцем и сроком действия, чтобы правило не отключали правкой кода в спешке.
- Документация — точка входа: где лежат правила, как добавить своё, какой порог покрытия тестами считается нормой и к кому идти с вопросом.
Отдельно отдаём журнал первых прогонов: видно, какие правила срабатывали чаще всего и где команда правила конфигурации под них, — это лучший учебный материал для новых инженеров.
Кейс: от ручных проверок к автоматическому контролю изменений
Контур — несколько сотен репозиториев с описанием инфраструктуры, которые вели больше десяти команд. Каждое изменение проходило ручное ревью: проверяющий сверял конфигурацию с внутренним регламентом по чек-листу, который отставал от регламента на месяцы. Часть нарушений — открытые наружу хранилища, отсутствие шифрования, правки в защищённых контурах — уходила в работу и всплывала уже после применения.
Правила описали как код на Open Policy Agent и вынесли в отдельный репозиторий с версионированием и тестами: к каждому правилу приложены конфигурации, которые оно обязано пропустить и обязано заблокировать. Проверку встроили в конвейер на этапе плана — до применения, поэтому автор изменения сразу видит, какое правило и какая строка его остановили.
Новое правило не пишут «на будущее»: сначала фиксируется инцидент или требование безопасности, затем правило прогоняется по историческим конфигурациям, и только потом включается в блокирующий режим. Первое время часть правил работала в режиме предупреждения — так вычистили ложные срабатывания, не останавливая команды.
Блокировки до применения выросли с единичных случаев до 95% всех найденных нарушений. Доля откатов изменений, вызванных ошибкой в конфигурации, упала с 12% до 3%. Время проверки одного изменения сократилось с 40 минут ручного ревью до 3 минут машинной, при этом объём правил вырос с 15 до 60, а ручных пунктов в чек-листе стало втрое меньше.
Чем встроенный движок политик отличается от внешнего?
Встроенный движок идёт вместе с инструментом: правила пишутся его собственным языком и проверяются прямо на этапе планирования изменений. Внешний движок — отдельный компонент, который получает описание инфраструктуры в машиночитаемом виде и выносит вердикт по общему набору правил. Расходятся они по четырём осям: язык описания правил, переносимость политик, скорость проверки и сопровождение.
| Критерий | Встроенный движок | Внешний движок |
|---|---|---|
| Язык описания правил | Собственный, знает объекты одного инструмента | Декларативный общего назначения, единый для всех проверок |
| Переносимость политик | Работают только внутри своего инструмента | Один набор покрывает инфраструктуру и прикладные манифесты |
| Скорость проверки | Вердикт в том же процессе, без сетевых вызовов | Отдельный сервис: сетевой вызов в обмен на независимое масштабирование |
| Сопровождение правил | В темпе обновлений инструмента | Свой график, но реестр правил и тесты держите сами |
Оба варианта — это Policy as Code: правила лежат в репозитории, проходят ревью и проверяются автотестами. Встроенный движок закрывает быстрые риски одного контура — правила про окружения, теги и допустимые типы ресурсов пишутся за часы и не требуют отдельного сервиса.
Внешний выигрывает, когда проверки нужны сразу на нескольких инструментах. Мы обычно начинаем со встроенного, а общие правила переносим во внешний движок — с реестром, версионированием и тестом на каждое правило. Проверка остаётся быстрой, а политики не приходится переписывать при смене инструмента.
Технические сомнения: ограничения и частые ошибки внедрения
Само внедрение правил редко бывает сложным — сложность в том, как политика ведёт себя, когда команда работает под сроком и в нескольких контурах одновременно. Ниже — вопросы, которые чаще всего всплывают на этапе передачи решения в эксплуатацию.
Как быть, если правило блокирует нормальное изменение?
Мы делим правила на предупреждающие и блокирующие, и вторые включаем только после прогона по истории изменений в репозитории — сразу видно, какая доля срабатываний ложная. Правило формулируется на инвариант (открытый порт, выключенное шифрование), а не на оформление кода: проверка стиля ломается на любом рефакторинге и через месяц отключается самой командой.
Что делать при аварии, если правило мешает срочному исправлению?
Путь обхода проектируется заранее, а не изобретается в момент сбоя: отдельная роль с коротким сроком действия, обязательная причина, след в журнале и автоматическая задача на приведение конфигурации к норме. Политика без штатного обхода отключается целиком — это худший исход, потому что контроля не остаётся вовсе.
Можно ли переиспользовать правила между разработкой и эксплуатацией?
Общая библиотека покрывает то, что одинаково везде: теги ресурсов, шифрование, сегментация сети. Различия выносятся в переопределения на среду — в разработке мягкий режим и ослабленные лимиты, в эксплуатации блокировка. Наследование в Terraform строится через отдельные корневые модули на контур: иначе ослабление, добавленное для отладки, незаметно уезжает в боевой контур.
Обсудим задачу: с чего начать внедрение проверок
Чтобы внедрение проверок политик не осталось демонстрацией на тестовом репозитории, начинаем с разбора текущего процесса. Нам важно увидеть, как сегодня рождается изменение инфраструктуры: кто готовит описания ресурсов в Terraform, кто согласует, на каком шаге ошибка обычно всплывает — на ревью или уже в облаке после применения.
От вас для старта достаточно:
- ссылка на репозиторий с инфраструктурным кодом и примеры типовых изменений за последние циклы;
- перечень требований, которые сейчас проверяются вручную: именование, теги, сетевые доступы, шифрование, регионы;
- роли и правила согласования: кто инициирует изменение, кто подтверждает, у кого право на исключение;
- описание сред и отличий в режимах применения;
- доступы к системе контроля версий и к среде, где будут запускаться проверки;
- контакт инженера, который отвечает за инфраструктуру и подтверждает спорные правила.
В ответ вы получаете оценку и план работ: перечень правил с приоритетами, схему их подключения к процессу изменений, объём пилотного контура и сроки. Пилотный контур берём узким — одно хранилище и 5-8 правил в режиме предупреждения, чтобы команда привыкла к сигналам без блокировки выката. Блокирующий режим включаем после того, как правила перестают давать ложные срабатывания.
Передача документации — часть работы, а не финал: описание каждого правила, причина его появления и порядок разбора срабатывания остаются у вашей команды. Опишите задачу — вернёмся с оценкой и планом.







