Когда изменения инфраструктуры приводят к сбою: варианты восстановления — от повторного применения до переключения на резерв

Вы только что выполнили terraform apply на продакшен-инфраструктуре. Вывод чистый. Никаких ошибок. И тут срабатывает алерт мониторинга: пользователи не могут подключиться к базе данных. Изменение, которое вы внесли в security group, случайно заблокировало доступ для прикладного уровня.

Что теперь?

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

Давайте разберём четыре варианта восстановления — от самого простого до наиболее сложного. Каждый подходит для разных ситуаций, и у каждого есть компромиссы, которые нужно понимать до того, как они понадобятся.

Повторное применение старого состояния

Самый прямой подход: вернуть инфраструктуру к конфигурации, которая была до изменения.

Если вы используете Terraform, это означает запуск terraform apply с предыдущим файлом состояния или конфигурацией. Тот же принцип применим к Pulumi, CloudFormation и любым другим инструментам infrastructure-as-code. Вы говорите системе восстановить известную рабочую версию вашего определения инфраструктуры.

Этот подход хорошо работает, когда изменение идемпотентно, а затронутые ресурсы не содержат критически важных данных. Например, правила security group, переменные окружения на вычислительных инстансах или настройки балансировщика нагрузки. Такие ресурсы можно переключать туда и обратно без побочных эффектов.

Вот конкретная последовательность команд для повторного применения старого состояния:

# 1. Проверяем, что предыдущий файл состояния существует
ls -la terraform.tfstate.backup

# 2. Восстанавливаем предыдущее состояние (перезаписывает текущее)
cp terraform.tfstate.backup terraform.tfstate

# 3. Просматриваем изменения, которые Terraform сделает для отката
terraform plan -state=terraform.tfstate

# 4. Применяем старое состояние для восстановления инфраструктуры
terraform apply -state=terraform.tfstate -auto-approve

Примечание: Всегда проверяйте, что файл резервного состояния корректен, перед применением. Выполните terraform state list -state=terraform.tfstate.backup, чтобы убедиться, что он содержит ожидаемые ресурсы.

Загвоздка: нужно, чтобы старое состояние всё ещё существовало. Если ваша команда удаляет старые файлы состояния или провайдер инфраструктуры сборщил мусор по части ресурсов, вам может быть нечего повторно применять. Кроме того, этот подход плохо работает с ресурсами, хранящими состояние (stateful). Нельзя просто повторно применить старую конфигурацию базы данных и ожидать, что данные вернутся в прежнее состояние.

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

Восстановление из снапшота

Когда ваше изменение затрагивает ресурсы, которые хранят данные, одного повторного применения недостаточно. Нужно восстановить сами данные.

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

Если изменение приводит к сбою, вы восстанавливаетесь из этого снапшота. База данных возвращается в состояние до изменения. Файловая система — к предыдущему содержимому.

Этот подход тяжелее, чем повторное применение. Восстановление из снапшота занимает время. В это время ресурс может быть недоступен. Пользователи видят ошибки или деградацию сервиса. Но для stateful-ресурсов восстановление из снапшота часто является единственным надёжным вариантом.

Он лучше всего работает, когда радиус поражения ограничен одним ресурсом или компонентом. Если вы изменили схему базы данных, и это сломало приложение, восстановление снапшота БД исправляет слой данных. Приложению, возможно, потребуется перезапуск, но данные возвращаются в норму.

Главный недостаток: вы теряете все данные, записанные между моментом создания снапшота и неудачным изменением. Если ваше приложение пишет непрерывно, этот разрыв имеет значение. Планируйте время создания снапшотов соответствующим образом.

DNS-откат

Иногда самое быстрое восстановление — это вообще не восстановление инфраструктуры. Это перенаправление трафика от сломанной версии.

DNS-откат работает на уровне маршрутизации трафика. Вместо того чтобы откатывать изменение инфраструктуры, вы направляете трафик обратно на старую инфраструктуру, которая всё ещё работает.

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

Это быстро. Очень быстро. Изменения DNS быстро распространяются в контролируемых средах, а обновления балансировщика нагрузки происходят почти мгновенно. Вам не нужно ничего пересобирать или восстанавливать.

Но есть критическое требование: старая инфраструктура должна всё ещё существовать. Если ваш процесс развёртывания уничтожает старые ресурсы при создании новых, DNS-откат невозможен. Эта стратегия естественным образом работает с blue-green развёртываниями или canary-релизами, где старая и новая версии работают параллельно.

DNS-откат также не устраняет первопричину проблемы. Сломанная инфраструктура всё ещё существует. Вам нужно будет разобраться и исправить её позже. Но для быстрого возврата пользователей в онлайн этот метод трудно превзойти.

Переключение на резервное окружение

Это самый сложный вариант восстановления и одновременно самый надёжный для критических систем.

Вы поддерживаете второе окружение, которое зеркалирует вашу продакшен-установку. Оно может находиться в другой зоне доступности, другом регионе или даже у другого облачного провайдера. Резервное окружение работает с той же инфраструктурой, той же версией приложения и имеет синхронизированные данные.

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

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

Инвестиции значительны. Резервное окружение стоит денег на поддержку. Синхронизация данных добавляет сложности. Нужны люди, которые понимают процесс переключения и могут выполнить его под давлением.

Но для инфраструктуры, которая должна оставаться доступной, переключение на резерв — самый надёжный вариант. Банки, системы здравоохранения и крупные e-commerce платформы используют этот подход, потому что стоимость простоя намного превышает стоимость поддержки резервного окружения.

Выбор правильного варианта

Каждый вариант восстановления подходит для разных сценариев:

  • Повторное применение старого состояния: Stateless-изменения, быстрые исправления, низкий риск для данных
  • Восстановление из снапшота: Stateful-изменения, влияние на один ресурс, требуется целостность данных
  • DNS-откат: Параллельные окружения, быстрое восстановление, старая инфраструктура ещё существует
  • Переключение на резерв: Критические системы, широкий радиус поражения, высокие требования к аптайму

Ваш выбор зависит от трёх факторов: типа вносимого изменения, потенциального радиуса поражения и необходимой скорости восстановления.

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

flowchart TD A[Сбой изменения инфраструктуры] --> B{Тип изменения?} B -->|Stateless| C{Старое состояние доступно?} B -->|Stateful| D{Потеря данных допустима?} C -->|Да| E[Повторно применить старое состояние] C -->|Нет| F{Старая инфраструктура ещё работает?} D -->|Нет| G[Восстановить из снапшота] D -->|Да| H[Повторно применить старое состояние] F -->|Да| I[DNS-откат] F -->|Нет| J{Существует резервное окружение?} J -->|Да| K[Переключиться на резерв] J -->|Нет| L[Ручное восстановление из бэкапов] E --> M[Проверить восстановление] I --> M G --> M K --> M L --> M

Практический чек-лист перед следующим изменением инфраструктуры

Прежде чем запускать очередной terraform apply или пушить изменение конфигурации, пройдитесь по этому чек-листу:

  • Знаю ли я, какой вариант восстановления предусмотрен для этого изменения?
  • Доступен ли старый файл состояния и корректен ли он?
  • Сделал ли я снапшот, если изменение затрагивает stateful-ресурсы?
  • Всё ли ещё работает старая инфраструктура на случай, если понадобится DNS-откат?
  • Тестировал ли я процесс переключения на резерв за последний месяц?
  • Знает ли команда, кто выполняет восстановление и как?

Конкретный вывод

Восстановление после сбоев инфраструктуры — это не вопрос одной идеальной стратегии. Это вопрос соответствия варианта восстановления тому изменению, которое вы вносите. Для изменения security group не нужно полное переключение на резерв. Для миграции базы данных, скорее всего, понадобится снапшот. Для canary-развёртывания пригодится DNS-откат.

Знайте свои варианты до того, как они понадобятся. Время решать, как восстанавливаться, — до внесения изменения, а не после того, как посыпались алерты.