Почему Terraform нужен файл состояния (и почему его нельзя хранить на ноутбуке)
Вы только что выполнили terraform apply и успешно создали сервер и базу данных. Всё работает. Вы закрываете ноутбук, довольный. Завтра вам нужно добавить балансировщик нагрузки. Вы открываете конфигурацию, добавляете ресурс и запускаете terraform plan.
Terraform смотрит на вас и выдает план, в котором хочет пересоздать всё с нуля.
Что случилось? У Terraform нет памяти о том, что он построил вчера. Он не знает, что сервер существует. Он не знает, что база данных работает. У него нет записи об инфраструктуре, которую он только что создал.
Это тот момент, когда большинство команд понимают, что им нужен файл состояния.
Что на самом деле делает файл состояния
Файл состояния — это рабочая память Terraform. В нем записаны все ресурсы, созданные Terraform, включая уникальные идентификаторы, последнюю известную конфигурацию и связи между ресурсами. Когда вы запускаете terraform plan, Terraform не обращается к вашему облачному провайдеру с вопросом "что существует?" — это было бы медленно, непоследовательно и ненадежно для разных провайдеров. Вместо этого он читает файл состояния и сравнивает его с текущей конфигурацией.
Представьте это как чек. После каждой покупки вы получаете чек, в котором указано, что вы купили, когда и за сколько. Без этого чека вам пришлось бы осматривать весь дом, чтобы понять, что вам принадлежит. С Terraform то же самое. Без файла состояния ему приходится сканировать весь ваш облачный аккаунт, чтобы выяснить, чем он управляет. И даже тогда он не может быть уверен, какие ресурсы создал он, а какие — кто-то другой вручную.
Вот визуальное сравнение двух рабочих процессов:
Файл состояния содержит подробную информацию о каждом ресурсе. Для облачного сервера это идентификатор сервера, IP-адрес, тип машины, зона доступности и сетевые настройки. Для базы данных — эндпоинт, порт, размер хранилища и настройки резервного копирования. Эта информация является источником истины для следующей операции Terraform.
Проблема с ноутбуком
Многие разработчики начинают с хранения файла состояния локально. Это проще всего. Terraform создает файл terraform.tfstate в вашей рабочей директории, и вы продолжаете работу.
Это работает до тех пор, пока:
- Ваш ноутбук не сломается или не будет украден.
- Вы случайно не удалите файл.
- Вы не переключитесь на другой компьютер и не забудете скопировать файл.
- Коллега не запустит Terraform со своей машины и не создаст другой файл состояния.
Когда файл состояния исчезает, Terraform теряет все знания о вашей инфраструктуре. Он считает, что ничего не существует. Если вы снова запустите terraform apply, он попытается создать всё с нуля. В результате вы получаете дублирующиеся ресурсы, конфликтующие конфигурации и счет за облако, который внезапно удваивается.
Хуже того, если кто-то вручную изменит ресурс в облачной консоли без обновления файла состояния, Terraform рассинхронизируется. Он думает, что у сервера 4 ГБ ОЗУ, а на самом деле — 8 ГБ. Следующий terraform plan выдаст план, не соответствующий реальности.
Удаленное состояние: единственный разумный подход
Решение простое: храните файл состояния в общем месте, доступном всем членам вашей команды. Это называется удаленным состоянием.
Удаленное состояние означает, что файл состояния находится в сервисе хранения, таком как Amazon S3, Azure Storage или Google Cloud Storage. Каждый член команды и каждый CI/CD-пайплайн читает и записывает один и тот же файл состояния. Это гарантирует, что все работают с одним источником истины.
Настройка удаленного состояния обычно выполняется один раз в блоке backend вашей конфигурации Terraform:
terraform {
backend "s3" {
bucket = "my-team-terraform-state"
key = "production/terraform.tfstate"
region = "us-east-1"
}
}
После настройки Terraform автоматически загружает файл состояния из удаленного хранилища перед каждым планом и отправляет обновления после каждого apply. Никому не нужно вручную копировать файлы или беспокоиться о конфликтах версий.
Блокировка состояния: предотвращение коллизий
С удаленным состоянием несколько человек могут запускать Terraform одновременно. Это создает новую проблему: два человека, запускающие terraform apply одновременно, могут повредить файл состояния или создать несогласованную инфраструктуру.
Блокировка состояния предотвращает это. Когда один процесс запускает terraform apply, он блокирует файл состояния. Другие процессы должны ждать, пока блокировка не будет снята. Большинство бэкендов удаленного состояния поддерживают блокировку. S3 использует DynamoDB для блокировки. Azure Storage имеет встроенную поддержку аренды. Google Cloud Storage использует номера поколений объектов.
Без блокировки вы рискуете столкнуться с такими сценариями:
- Два пайплайна развертывают разные изменения одновременно.
- Разработчик запускает ручной apply, пока CI/CD-пайплайн находится в середине развертывания.
- Частичные обновления, когда записывается только половина изменений.
Блокировка состояния не является опциональной для командной работы. Это обязательное требование.
Чувствительные данные в файлах состояния
Файлы состояния содержат всё, что Terraform знает о вашей инфраструктуре. Это включает чувствительную информацию, такую как пароли баз данных, ключи API и строки подключения. Terraform хранит эти значения в открытом виде внутри файла состояния.
Это означает, что ваш файл состояния представляет угрозу безопасности. Любой, у кого есть доступ к файлу состояния, может прочитать ваши секреты. Бэкенды удаленного состояния обычно поддерживают шифрование в покое и при передаче. S3 поддерживает серверное шифрование с KMS. Azure Storage поддерживает шифрование в покое по умолчанию. Всегда включайте шифрование для вашего хранилища состояния.
Некоторые команды также разделяют файлы состояния по окружениям. Разработка, стейджинг и продакшн получают свои собственные файлы состояния, хранящиеся в отдельных местах. Это предотвращает влияние изменений в одном окружении на другое. Это также ограничивает радиус поражения в случае компрометации файла состояния.
Как файлы состояния работают в CI/CD
В CI/CD-пайплайне пайплайну нужен доступ к файлу состояния для запуска Terraform. Пайплайн аутентифицируется в бэкенде удаленного состояния с помощью учетных данных или IAM-ролей. Он загружает файл состояния, запускает terraform plan и, если одобрено, запускает terraform apply и отправляет обновленное состояние обратно.
Вот почему удаленное состояние необходимо для автоматизации. CI/CD-пайплайн, работающий в эфемерном контейнере, не может полагаться на файл состояния, хранящийся на ноутбуке разработчика. Ему нужно согласованное, доступное место, существующее независимо от любой отдельной машины.
Практический чек-лист для управления файлами состояния
- Храните файлы состояния в удаленном хранилище, а не на локальных машинах.
- Включите шифрование в покое и при передаче для бэкенда хранилища.
- Настройте блокировку состояния для предотвращения одновременных изменений.
- Используйте отдельные файлы состояния для каждого окружения.
- Ограничьте доступ к файлам состояния с помощью IAM-политик или контроля доступа.
- Никогда не коммитьте файлы состояния в систему контроля версий.
- Регулярно создавайте резервные копии файлов состояния, особенно перед крупными изменениями.
Что это значит для вашей команды
Файлы состояния — это не деталь реализации, которую можно игнорировать. Это основа способности Terraform надежно управлять инфраструктурой. Без правильно управляемого файла состояния ваши рабочие процессы Terraform будут давать непредсказуемые результаты, дублирующиеся ресурсы и трудноотлаживаемые сбои.
Как только у вас появляется более одного человека, запускающего Terraform, или как только вы добавляете CI/CD-пайплайн, переносите файл состояния в удаленное хранилище. Это занимает десять минут на настройку и избавляет от часов восстановительных работ, когда что-то идет не так.
Ваша инфраструктура слишком важна, чтобы доверять ее файлу на ноутбуке.