Состояние и планирование
Что это такое
Terraform хранит файл состояния, где записано, какие объявленные ресурсы соответствуют каким реальным, вместе с их атрибутами. Каждый план — это сравнение этой записи и с объявлением, и с тем, как реальность видит провайдер. Файл состояния — ещё и то, что ломается дороже всего: он содержит секреты, его нельзя редактировать вдвоём одновременно, а его потеря означает потерю соответствия между конфигурацией и созданными ею ресурсами.
Почему это важно
Плану можно доверять, только если состояние точное. Устаревшее или разошедшееся состояние даёт план, который либо предлагает пересоздать уже существующие ресурсы, либо сообщает об отсутствии изменений, пока реальность разошлась. Хуже того, в состоянии лежат значения, возвращённые API провайдера, включая пароли и ключи, так что это хранилище секретов под чужим именем. Осознанная работа с ним — удалённое, заблокированное, зашифрованное и резервируемое состояние — вот разница между инфраструктурой как кодом и инфраструктурой как догадками.
Ключевые идеи
Файл состояния связывает объявления с реальностью
Адрес ресурса в конфигурации сопоставляется через состояние с идентификатором у провайдера. Именно это сопоставление позволяет Terraform обновить ресурс, а не создать дубликат, и поэтому ресурс, убранный из конфигурации, предлагается к удалению. Всё остальное следует из одной этой идеи.
адрес в конфигурации network.main -> состояние -> id провайдера vpc-0a12...
Удалённое состояние обязательно, как только применяет больше одного человека
Локальный файл состояния работает для одного человека на одной машине и отказывает во всех остальных случаях. Удалённое состояние с блокировкой не даёт двум применениям перемешаться и делает состояние доступным конвейеру. Блокировка не опциональна: два одновременных применения — вот как у ресурсов появляются дубликаты, которые потом приходится согласовывать руками.
Состояние содержит секреты в открытом виде
Ответы провайдера сохраняются такими, какими их вернули, а туда регулярно попадают учётные данные, строки подключения и приватные ключи. Шифрование при хранении, ограниченный доступ и запрет на коммит — это минимум. Хранить состояние в обычном объектном хранилище без контроля доступа — распространённая и серьёзная ошибка.
Импорт переносит существующие ресурсы в состояние
Ресурсы, созданные до появления конфигурации, можно принять, а не пересоздавать, записав их идентификаторы в состояние. После этого объявление нужно написать так, чтобы оно совпадало с их реальными настройками, иначе следующий план предложит изменения. Импорт — осознанная операция по одному ресурсу за раз, а не массовая миграция.
Дрейф — это реальность, ушедшая от объявления
Кто-то правит правило в консоли, автоматический процесс меняет настройку или провайдер объявляет атрибут устаревшим. Обновление во время планирования показывает разницу, но постоянный дрейф — сигнал, что кто-то обходит инструмент. Либо настройка должна принадлежать конфигурации, либо изменение требует другого механизма.
Просмотр плана — это контроль, и он держится на гигиене состояния
План может быть ровно настолько хорош, насколько хорошо состояние за ним. Регулярно запускать планы, просматривать их даже когда изменений не задумано, и относиться с подозрением к плану, который показывает гораздо меньше ожидаемого, — вот привычки, которые держат сравнение честным.
Практика
Перенесите состояние в удалённый бэкенд
Возьмите конфигурацию с локальным файлом состояния и перенесите его в удалённый бэкенд с блокировкой, затем примените с двух машин, чтобы убедиться, что одновременно может идти только одно.
Готово, когда: второе применение отклоняется, пока первое держит блокировку, и состояние не хранится ни на одной из локальных машин.
Примите существующий ресурс
Создайте ресурс вручную, напишите его объявление, импортируйте его в состояние и получите план, показывающий отсутствие изменений.
Готово, когда: план после импорта пуст — значит, объявление совпадает с реальностью.
Частые ошибки
- Хранение состояния на ноутбуке — больше никто не может применить, и оно теряется вместе с машиной; исправить: используйте удалённый бэкенд с самого начала.
- Коммит состояния в репозиторий — оно содержит учётные данные в открытом виде; исправить: храните его удалённо с контролем доступа и шифрованием.
- Разрешение одновременных применений — ресурсы дублируются или изменяются частично; исправить: включите блокировку состояния.
- Импорт без совпадения с объявлением — следующий план предлагает изменить всё; исправить: напишите объявление по реальным настройкам и подтвердите пустой план.
- Игнорирование повторяющегося дрейфа — реальность и объявление расходятся, пока план не теряет смысл; исправить: переведите настройку под конфигурацию или зафиксируйте, почему она исключение.
Что читать дальше
- Декларирование инфраструктуры (06-cloud-devops/07-terraform/01-declaring-infrastructure) — конфигурация, которую записывает это состояние.
- Terraform (06-cloud-devops/07-terraform) — инструмент, чей план зависит от всего этого.
- CI/CD (06-cloud-devops/08-ci-cd) — где планы формируются, просматриваются и применяются с блокировкой и обращением с секретами, как требует этот урок.