Почему откат инфраструктуры — это не то же самое, что откат приложения

Вы выкатили плохое обновление приложения. Пользователи видят ошибки. Команда переключает балансировщик обратно на предыдущую версию, или пайплайн переразворачивает старый артефакт. Через несколько минут приложение работает на старом коде. Данные целы. База данных не изменилась. Серверы — те же машины, что и раньше. Проблема исчезла.

Это откат приложения. Он работает, потому что приложения в основном не хранят состояние. Вы меняете код — и старое поведение возвращается. Без долгосрочных побочных эффектов.

А теперь представьте, что вы изменили правило файрвола, увеличили диск базы данных или обновили конфигурацию подсети. Что-то сломалось. Вы хотите вернуться назад. Можно ли просто применить старую конфигурацию и ожидать, что всё заработает?

Скорее всего, нет.

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

Состояние — первая проблема

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

Инфраструктура — наоборот. База данных сохраняет свои данные, даже если вы меняете её конфигурацию. Диск хранит файлы, даже если вы изменили его размер. Эти ресурсы хранят состояние. Они сохраняют его за пределами жизненного цикла любого изменения конфигурации.

Когда вы откатываете приложение, вы просто восстанавливаете код. Когда вы откатываете инфраструктуру, вы должны восстановить конфигурацию, не уничтожив данные, которые накопились внутри ресурса. Это не всегда возможно.

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

Разница становится очевидной, если сравнить два пути бок о бок.

flowchart TD A[Плохое изменение развёрнуто] --> B{Это приложение?} B -->|Да| C[Меняем код через LB или пайплайн] C --> D[Старый код работает, без последствий] D --> E[Откат успешен] B -->|Нет, это инфраструктура| F[Определяем ресурсы с состоянием] F --> G{Можно ли сохранить состояние?} G -->|Нет| H[Откат может уничтожить данные] G -->|Да| I[Проверяем зависимости] I --> J[Упорядоченная последовательность отката] J --> K[Частичное или сломанное состояние] K --> L[Нужно восстановление, а не просто откат]

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

Зависимости умножают риск

Ресурсы инфраструктуры редко существуют сами по себе. Одно изменение может затронуть десять взаимосвязанных ресурсов: VPC, подсеть, группу безопасности, балансировщик, несколько инстансов и базу данных. Каждый ресурс зависит от других определённым образом.

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

На практике это означает, что вы не можете просто запустить terraform apply со старым файлом состояния и уйти. Старое состояние может конфликтовать с текущим состоянием других ресурсов, которые не были откачены. Результат — часто частичное восстановление, которое оставляет инфраструктуру в сломанном состоянии.

Идемпотентный apply не означает безопасный откат

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

Рассмотрим размер диска. Вы указываете диск 100 ГБ, применяете — диск создан. Вы запускаете ту же конфигурацию снова — ничего не меняется. Это идемпотентность. Теперь вы меняете конфигурацию на 200 ГБ и применяете. Диск растёт. Затем вы меняете конфигурацию обратно на 100 ГБ и снова применяете. Что произойдёт?

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

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

Что это значит для вашей команды

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

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

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

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

Перед тем как применить любое изменение инфраструктуры, задайте эти вопросы:

  • Хранит ли этот ресурс состояние? Если да, можно ли сохранить состояние при откате конфигурации?
  • Какие другие ресурсы зависят от этого? Не сломает ли откат их связность?
  • Обратимо ли изменение? Может ли инструмент уменьшить диск, понизить инстанс или восстановить сетевой путь без уничтожения данных?
  • Каков фактический план восстановления в случае сбоя изменения? Это откат, миграция или пересборка?
  • Тестировали ли мы путь восстановления в среде, отличной от production?

Вывод

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