Расширение CI/CD на базы данных и инфраструктуру: практический план
Ваш пайплайн приложений работает отлично. Изменения кода проходят путь от коммита до продакшена с автоматическими тестами, сборками и развёртываниями. Команда чувствует уверенность, выкатывая обновления. Но есть проблема: изменения схемы базы данных всё ещё происходят через то, что кто-то запускает SQL-скрипты напрямую на продакшене, а инфраструктура настраивается через вход в облачные консоли и нажатие кнопок.
Этот разрыв создаёт трения. Разработчик добавляет новую колонку в таблицу, но миграционный скрипт отправляется по email DBA, который запускает его вручную. Серверу нужно изменить конфигурацию, но кто-то должен зайти по SSH и отредактировать файлы. Эти ручные шаги нарушают согласованность, которую вы выстроили везде. Они вносят риски, не имеют аудита и делают откаты практически невозможными.
Хорошая новость в том, что те же принципы пайплайна применимы к базам данных и инфраструктуре. Разница в деталях: что тестировать, как управлять рисками и как выполнять откаты.
Включение миграций базы данных в пайплайн
Изменения базы данных отличаются от кода приложения, потому что они работают с живыми данными. Баг в коде приложения может вызвать ошибки, которые легко исправить. Плохая миграция может повредить или удалить данные навсегда. Эта реальность заставляет команды колебаться с автоматизацией развёртывания БД, но альтернатива — ручное выполнение — ещё хуже.
Начните с того, чтобы рассматривать каждое изменение схемы как код. Каждая миграция должна быть скриптом, хранящимся в системе контроля версий, либо в том же репозитории, что и ваше приложение, либо в выделенном. Скрипт должен иметь чёткую версию, описание того, что он делает, и соответствующий скрипт отката.
Например, миграция для добавления колонки может выглядеть так:
-- V002__add_status_column.sql
-- Прямая миграция: добавление колонки status со значением по умолчанию
ALTER TABLE users ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active';
-- V002__add_status_column_rollback.sql
-- Откат миграции: удаление колонки status
ALTER TABLE users DROP COLUMN status;
Следующая диаграмма иллюстрирует, как этапы работы с БД и инфраструктурой вписываются в ваш существующий пайплайн:
Затем ваш пайплайн автоматически запускает эти миграции во всех средах: разработка, staging и production. Но поскольку ставки выше, вам нужны дополнительные шлюзы:
- Пробные прогоны в staging: Перед запуском миграции в production выполните её в staging с объёмом данных, зеркалирующим production. Это выявит проблемы производительности и неожиданное блокирующее поведение.
- Тесты совместимости: Проверьте, работает ли миграция с существующими данными. Миграция, добавляющая колонку NOT NULL без значения по умолчанию, завершится ошибкой, если в существующих строках в этой колонке есть NULL.
- Шлюзы утверждения для деструктивных изменений: Удаление колонки, изменение типа данных или удаление таблицы должно требовать ручного утверждения. Эти изменения сложнее или невозможно отменить.
Каждая миграция должна иметь протестированный скрипт отката. Добавление колонки обычно безопасно отменить. Удаление таблицы — нет. Ваш пайплайн должен уметь автоматически выполнять откат, если миграция не удалась или команда решила откатить изменения.
Инфраструктура как код: декларируйте, а не кликайте
Инфраструктура включает серверы, сети, балансировщики нагрузки, экземпляры баз данных и все компоненты, необходимые для работы вашего приложения. Когда вы подготавливаете их вручную через облачные консоли, вы создаёте несколько проблем:
- Среды расходятся. В разработке могут быть немного другие настройки, чем в production.
- Изменения трудно воспроизвести. Если сервер упадёт, сможете ли вы воссоздать его в точности?
- Нет аудита. Кто изменил правила файрвола на прошлой неделе?
Решение — декларировать инфраструктуру как код. Пишите конфигурационные файлы, описывающие, как должна выглядеть ваша инфраструктура, а затем позволяйте пайплайну применять эти конфигурации. Это и есть инфраструктура как код (IaC).
Инструменты вроде Terraform, AWS CloudFormation или Pulumi позволяют определять ресурсы в файлах. Эти файлы проходят тот же пайплайн, что и код вашего приложения: попадают в репозиторий, проходят ревью кода, тестируются в разработке, а затем применяются к staging и production.
Тестирование инфраструктуры отличается от тестирования приложений. Тесты приложений проверяют, правильно ли ведёт себя код. Тесты инфраструктуры проверяют, даёт ли конфигурация ожидаемую среду:
- Открыты ли требуемые порты?
- Правильно ли настроен файрвол?
- Корректна ли версия операционной системы?
- Соответствуют ли размеры ресурсов (CPU, память, диск) спецификации?
Некоторые команды идут дальше: подготавливают инфраструктуру в изолированной среде, запускают тесты против неё, а затем уничтожают её. Это даёт высокую уверенность перед применением изменений в production.
Шлюзы рисков для инфраструктуры следуют тому же шаблону, что и для баз данных. Изменение, корректирующее размер диска, может потребовать только автоматических тестов. Изменение, реструктурирующее сеть или заменяющее тип базы данных, требует ручного утверждения и более тщательной валидации.
Стратегии отката для базы данных и инфраструктуры
Откат кода приложения обычно прост: развернуть предыдущую версию. Откат миграции базы данных или изменения инфраструктуры требует большего планирования.
Для миграций базы данных скрипт отката должен быть написан одновременно с прямой миграцией. Тестируйте откат в вашем пайплайне, а не только в голове. Некоторые миграции являются аддитивными (добавление колонки) и откатываются чисто. Другие — трансформационными (разделение таблицы) и требуют тщательной логики отката. Если миграцию нельзя безопасно откатить, это сигнал перепроектировать подход к миграции.
Для инфраструктуры ваш пайплайн должен хранить предыдущее состояние вашей конфигурации. Когда нужно выполнить откат, пайплайн применяет предыдущую конфигурацию. Это хорошо работает для декларативных инструментов IaC, потому что они автоматически обрабатывают diff между текущим и желаемым состоянием.
Практический чек-лист для расширения пайплайна
| Область | Что добавить | Шлюз риска | Откат |
|---|---|---|---|
| База данных | Скрипты миграций в системе контроля версий | Пробный прогон в staging, утверждение для деструктивных изменений | Протестированный скрипт отката для каждой миграции |
| Инфраструктура | Файлы конфигурации IaC | Автоматическая валидация, утверждение для изменений архитектуры | Предыдущая конфигурация сохранена и может быть развёрнута |
Шаблон повторяется
Как только вы включите базу данных и инфраструктуру в пайплайн, вы заметите, что тот же шаблон применим к другим областям: конфигурация окружения, фича-флаги, релизы мобильных приложений. Конкретика меняется — что тестировать, как управлять рисками, как откатывать — но основная идея остаётся той же. Каждое изменение проходит согласованный, протестированный, обратимый путь.
Начните с одной миграции базы данных в вашем пайплайне. Затем с одного изменения инфраструктуры. Первые несколько будут казаться медленными, потому что вы строите процесс. Но каждый следующий делает следующий быстрее и безопаснее.
Цель — не автоматизация ради автоматизации. Это гарантия того, что когда что-то сломается — а это случится — вы точно будете знать, что изменилось, как это исправить и как предотвратить повторение.