Почему изменения инфраструктуры требуют той же дисциплины, что и изменения кода

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

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

Проблема в том, что многие команды относятся к изменениям инфраструктуры иначе, чем к изменениям кода приложения. Изменения кода проходят через pull request'ы, ревью, автоматические тесты и поэтапные развертывания. Изменения инфраструктуры часто выполняются через прямой доступ к консоли, ad-hoc команды или общие учетные данные. Разрыв в дисциплине создает слепую зону, которая рано или поздно приводит к инциденту.

Инфраструктура как код — это основа, а не решение

Инфраструктура как код (IaC) означает, что вы описываете конфигурацию инфраструктуры в файлах, храните их в репозитории и применяете через автоматизацию. Инструменты вроде Terraform, Pulumi или AWS CDK делают это возможным. Но наличие IaC-файлов в репозитории — это еще не всё. Дисциплина заключается в том, как вы управляете изменениями этих файлов.

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

Шаблон для изменений инфраструктуры

Каждое изменение инфраструктуры должно следовать повторяемой последовательности. Эта последовательность работает независимо от того, какой IaC-инструмент вы используете. Она защищает вашу команду от наиболее распространенных сценариев отказов.

Следующая блок-схема иллюстрирует рекомендуемую последовательность и точки принятия решений:

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

Начинайте с изменения кода

Каждое изменение инфраструктуры должно начинаться как pull request в ваш репозиторий инфраструктуры. Без исключений. Никто не должен изменять рабочую инфраструктуру напрямую через облачную консоль, CLI-команду на сервере или ручной скрипт.

Pull request показывает, что именно изменилось: новый ресурс, измененная сетевая конфигурация, удаленное хранилище. Члены команды могут просмотреть diff, задать вопросы и заметить проблемы до того, как что-то выполнится. Требуйте как минимум одного ревьюера, который понимает влияние изменения. Для критической инфраструктуры, такой как сети или группы безопасности, рассмотрите требование двух ревьюеров.

Запускайте план перед применением

IaC-инструменты могут показать, что изменится, без фактического применения изменений. Terraform называет это планом. Pulumi — предпросмотром. Суть та же: инструмент сравнивает вашу конфигурацию с текущим состоянием и перечисляет все ресурсы, которые будут созданы, изменены или уничтожены.

Запускайте этот план как часть процесса pull request. Сохраняйте вывод и прикрепляйте его к PR. Ревьюеры должны проверять на неожиданные изменения: удаляется ли ресурс, который не должен удаляться? Применяется ли изменение к неправильному окружению? Если план показывает что-то неожиданное, остановитесь и разберитесь, прежде чем продолжать.

Например, план Terraform для изменения группы безопасности может выглядеть так:

Terraform will perform the following actions:

  # aws_security_group_rule.app_ingress will be updated in-place
  ~ resource "aws_security_group_rule" "app_ingress" {
        id                     = "sgrule-1234567890"
      ~ from_port              = 8080 -> 8443
        protocol               = "tcp"
      ~ to_port                = 8080 -> 8443
        type                   = "ingress"
        # (5 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Этот вывод показывает, какое именно правило изменится и как, позволяя ревьюерам заметить ошибки до применения изменения.

Сначала тестируйте в непродакшене

Примените изменение в staging или development-окружении перед продакшеном. Если у вас нет полного инфраструктурного staging-окружения, создайте уменьшенную копию, которая отражает критические части продакшена. Некоторые команды используют отдельный инфраструктурный аккаунт или проект специально для тестирования изменений.

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

Применяйте через пайплайн, а не с ноутбука

Фактическая команда apply должна выполняться в CI/CD-пайплайне, а не на машине разработчика. Пайплайн записывает, кто инициировал apply, когда это произошло и что изменилось. Эта аудиторская запись необходима для отладки и соответствия требованиям.

Пайплайн должен немедленно останавливаться, если apply частично завершился ошибкой. Не позволяйте ему продолжать применять изменения к другим ресурсам после сбоя. Частичные изменения инфраструктуры трудно диагностировать и еще труднее исправить.

Имейте план отката

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

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

Проверяйте после применения

Не предполагайте, что всё в порядке, только потому что apply завершился без ошибок. Проверьте, что новые ресурсы работают. Протестируйте сетевые соединения. Убедитесь, что приложения, зависящие от инфраструктуры, всё еще здоровы.

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

Практический чеклист для изменений инфраструктуры

  • Изменение начинается как pull request в репозиторий инфраструктуры
  • Как минимум один ревьюер, понимающий влияние, одобрил PR
  • Вывод плана проверен и соответствует ожиданиям
  • Изменение сначала применено в непродакшене
  • Apply выполняется через пайплайн, а не с локальной машины
  • План отката задокументирован и готов
  • Проверки верификации пройдены после apply

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

Вывод

Изменения инфраструктуры — это высокорискованные, низкочастотные операции. Такое сочетание делает их опасными. Когда вы делаете что-то редко, вы более склонны к ошибкам. Когда влияние широкое, эти ошибки причиняют больше вреда.

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