Лучший комплимент моей работе — это тишина.
Мы провели миграцию CI/CD без единой секунды даунтайма: 200 pipeline, 22+ репозитория, 15 команд переехали со старой платформы на современный стек. И самой громкой реакцией было равнодушное пожатие плечами. Никакого war room. Никакого отката в два часа ночи. Ни одного гневного треда в Slack. Если оценивать миграцию по числу недовольных разработчиков — у нас круглый ноль.
Люди слышат это и решают, что мы просто плохо всех оповестили. Всё наоборот. Когда земля уходит из-под ног, а никто этого не чувствует — вот это и есть победа.
С чего мы начинали
Двадцать два репозитория — и каждый уникальная снежинка. У каждого свой Jenkinsfile, свои причуды, свои неписаные знания в голове у одного человека. Куча Bitbucket-пайплайнов, которые мог отладить только их автор — а автор уволился полгода назад. Каждый сервис — исключение. Каждый деплой — маленькая молитва.
Знакомый типаж: работает, еле-еле, и трогать никто не хочет. Меняешь одну строчку — и ломаются три вещи в сервисе, который ты ни разу не открывал. Это не инфраструктура. Это дом с привидениями.
Один шаблон вместо двадцати двух
Цель формулировалась просто, а давалась тяжело: заменить весь этот зоопарк одним универсальным шаблоном pipeline на GitLab CI. Один файл на 634 строки, на который через include: ссылается каждый сервис. Меняешь шаблон один раз — обновление прилетает всем. Никакого расползания копипасты. Никаких «почему staging собирается не так, как prod».
И один пункт без права на компромисс: 75% покрытия тестами. Не пожелание, не «потом допишем». Не дотянул до планки — pipeline останавливается. Миграция стала заодно и моментом, когда мы наконец начали отдавать годами копившийся долг по тестам.
Чтобы довести этот файл до ума, ушло 350+ коммитов. Каждый частный случай, каждая шальная переменная окружения, каждая ротация секретов, каждый странный шаг сборки, который кто-то добавил в 2022-м и забыл, — всё это должен был закрывать сам шаблон, а не костыль-исключение. Шаблон имел смысл, только если он реально универсальный.
Мигрировать по зависимостям, а не по дедлайну
Вот здесь обычно всё и умирает. Кто-то назначает дату переключения. Команды в мыле. Что-то ломается. Откат. Доверие испарилось. Проект уполз на полгода вправо. Я видел ровно этот фильм трижды, в трёх разных компаниях.
Поэтому дедлайна мы не ставили вовсе. Вместо этого:
- Порядок по зависимостям. Восемь ключевых сервисов переезжали в строгой последовательности — сначала то, от чего зависят все, потребители в конце. Ошибись с порядком — и один сломанный билд каскадом валит всё вниз по цепочке.
- Новое рядом со старым. Новые пайплайны неделями крутились параллельно со старыми, ещё до того, как кого-то просили переключиться. Оба собирали один и тот же код одновременно.
- Автоматические parity-проверки. Мы сравнивали вывод старого и нового pipeline на каждом прогоне. Малейшее расхождение — стоп, разбираемся, и только потом трогаем следующий сервис.
- Откат одним флагом. Любая команда могла вернуться на старый pipeline, переключив один флаг. Без тикета, без совещания, без разрешения.
- «Переезжаем, когда готовы», а не «до четверга». Сроком распоряжалась каждая команда, а не диаграмма Ганта.
Начинали намеренно с малого — 3 неопасных пайплайна, потом 10, потом 50. Каждая партия, прошедшая тихо, покупала нам уверенность расширить следующую.
Главный секрет был не технический
Parity-проверки и флаг отката — всё это важно. Но по-настоящему сработало не то, что лежало в YAML.
Мы ни разу не попросили команду «поверить новой системе».
Вместо этого мы дали новой системе гонять их же реальные билды — корректно — целых две недели, прежде чем предложить переключиться. К моменту переезда новый pipeline уже две недели катал их код в прод. Верить было не во что. Было только то, что они и так своими глазами видели работающим.
Доверие не объявляют на кикоффе. Его тихо доказывают — прогон за прогоном, пока переключение не превращается в пустую формальность.
Что нам дала «скука»
Четыре месяца. 200 pipeline. Ноль инцидентов. Ни один сервис не потерял ни единого запроса за всю миграцию.
Лучшие миграции — скучные. Незаметные. Те, где единственный признак перемен — билды стали чуть быстрее, а дежурный телефон перестал звонить.
Если вы смотрите в глаза собственной легаси-платформе CI/CD — план короткий:
- Сведите всё к одному шаблону, чтобы фикс прилетал сразу всем.
- Гоняйте старое и новое параллельно и доверяйте parity-проверкам, а не мнениям.
- Сделайте откат одним флагом, чтобы переключение ничего не стоило отменить.
- Покажите, что система работает, прежде чем просить в неё поверить.
Сделаете так — и наградой будет самый тихий и невзрачный запуск в вашей карьере. Считайте эту тишину аплодисментами.