В прошлый Q4 я переносил revenue-critical платформу между двумя тенантами Azure в самый горячий квартал года — и весь смысл в том, что вы читаете об этом сейчас, а не слышали тогда. Zero downtime миграция между тенантами — это не героический спринт на выходных. Это четыре месяца паранойи, 241 Terraform-модуль и план отката, которому я доверял больше, чем собственным рукам.
Ставки
Восемь сервисов. Два тенанта. 500+ активных пользователей. Приложение крутило бюджеты, клиентские данные, операционные процессы — тот случай, когда каждая минута даунтайма — это деньги, уходящие из компании. Бизнес выдал ровно одно предложение по скоупу: «Мигрируй, но чтобы ничего не сломалось». Без давления, ага.
Q4 — это пик трафика. Любой здравый человек назначил бы такую миграцию на тихие июльские выходные. У нас такой роскоши не было — календарь говорил сейчас, а выручка говорила не смей уронить ни один запрос.
Восемь слоёв зависимостей не переносятся «в лоб»
Наивная версия этой задачи — «выгрузить всё, загрузить всё, переключить DNS». Это работает, когда сервисы независимы. Мои — нет. Зависимости уходили на восемь слоёв вглубь, поэтому порядок миграции решал всё:
- Сначала слой данных — без него остальное не имеет смысла
- Вторыми — сервисы identity: всё сначала аутентифицируется, а потом уже что-то делает
- Третьей — бизнес-логика
- Ядро приложения — в последнюю очередь
Ошибись в порядке — получишь каскадный отказ: сервис A ждёт B, B ждёт C, и одно преждевременное переключение роняет всю конструкцию.
IaC-фундамент
Инфраструктура — это 241 Terraform-модуль под управлением Terragrunt, по модулю на сервис на окружение, и повторяемость тут намеренная. Скучная инфраструктура — надёжная инфраструктура.
Раз уж я всё равно был внутри, я вынес все секреты service principal. Их заменили OIDC и Workload Identity Federation, так что в финале нигде не хранилось ни одного долгоживущего креденшла. Если вы и так пересобираете тенант из кода — это самый дешёвый момент починить свою модель аутентификации. Не тащите старые секреты через границу.
Переключать трафик по-взрослому
Всё выполнялось параллельно: старый и новый тенант жили бок о бок, непрерывная синхронизация данных держала их в одном состоянии. Дальше я переводил реальный трафик порциями — 10%, 25%, 50%, 100% — с автоматическими gate-проверками на каждом шаге.
Любой gate срабатывал «в закрытую». Если проверка отклонялась — трафик откатывался автоматически. Автоматически — не «кому-то прилетел пейджер», не «человек в 2 ночи заметил, что дашборд покраснел, и начал что-то печатать». Страховочная сетка не требовала, чтобы я не спал.
До всего этого я прогнал каждый откат по три раза. Паранойя — это фича. Откат, который ты ни разу не выполнял, — это надежда, а надежда — не стратегия отката.
Самым сложным был не Terraform
Вот чего вам никто не говорит: Terraform не был сложным. Конфиг OIDC не был сложным. Синхронизация данных не была сложной. Сложным было тестирование.
У каждого сервиса были точки интеграции — другие внутренние сервисы, внешние API, сторонние вебхуки. Во время перехода каждая из них должна была работать и в старом, и в новом тенанте одновременно. Вебхук, который знает только старый эндпоинт, — это тихая потеря данных, которая просто ждёт своего часа. Поэтому мы неделями гоняли параллельную валидацию, прежде чем перевести хоть один байт боевого трафика. Большая часть этих четырёх месяцев ушла именно на это — не на стройку, не на переключение, а на доказательство, что оно работает во всех комбинациях, что мы смогли придумать.
Результат
Четыре месяца. Восемь сервисов. 241 модуль. Ноль инцидентов. Самый большой комплимент этой работе — тишина в понедельник утром: 500 человек делают своё дело и не подозревают, что земля под ними сдвинулась.
Что я сказал бы вам перед следующим окном миграции
Если ваш план — «сделаем на выходных и понадеемся на лучшее», то это не план. Это желание, а у желаний нет стратегии отката. Лучшая миграция — та, которую никто не заметил. Автоматизируйте страховочную сетку — или не трогайте прод.
И оставлю вас с тем же вопросом, который задаю себе перед каждым изменением на проде: какая у вас стратегия отката? Если не можете ответить одним предложением — вы ещё не готовы.