Перейти к содержанию
Innovialabs

Управление state в Terraform: remote backend, блокировки и workspaces

Продвинутое3 мин

Коротко

State — это карта соответствия между вашим кодом и реальной инфраструктурой. Храните его в remote backend с блокировкой и шифрованием, разделяйте по окружениям и компонентам, а расхождения исправляйте через plan, import и refresh, а не ручной правкой файла.

Что такое state и почему он важен

State (terraform.tfstate) — файл, в котором Terraform хранит соответствие между ресурсами в коде и реальными объектами в облаке: идентификаторы, атрибуты, зависимости. Без него Terraform не знает, что уже создано, и при следующем apply попытается создать всё заново.

Из этого следуют три правила:

  • State — критичный артефакт. Потеря state не удаляет инфраструктуру, но отрывает её от управления.
  • State содержит секреты. Пароли баз данных, ключи и другие чувствительные атрибуты могут храниться в нём открытым текстом.
  • С state должен работать один процесс одновременно. Два параллельных apply способны повредить его.

Remote backend с блокировкой

Локальный state подходит только для экспериментов. Для команды нужен remote backend: общее хранилище, к которому есть доступ у всех и у CI.

Что должен давать хороший backend:

ТребованиеЗачем
Блокировка (locking)Не даёт двум запускам менять state одновременно
ШифрованиеЗащищает секреты внутри state
ВерсионированиеПозволяет откатиться к предыдущей версии state
Контроль доступаОграничивает, кто может читать и менять state

Пример для AWS S3:

terraform {
  backend "s3" {
    bucket       = "company-terraform-state"
    key          = "prod/network/terraform.tfstate"
    region       = "eu-central-1"
    encrypt      = true
    use_lockfile = true
  }
}

Механизм блокировки зависит от backend и версии Terraform: в старых конфигурациях для S3 использовалась таблица DynamoDB. Сверяйтесь с документацией вашей версии. Альтернативы — GCS, Azure Blob, Terraform Cloud/HCP, GitLab-managed state.

Сам бакет для state лучше создать отдельно (вручную или отдельной конфигурацией) и включить в нём версионирование.

Разделение state по окружениям и компонентам

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

Два основных подхода:

  • Отдельные каталоги на окружение (envs/dev, envs/prod) с разными key в backend. Окружения изолированы явно, можно иметь разные права доступа.
  • Workspaces — несколько state в одной конфигурации, переключение через terraform workspace select. Удобно для однотипных копий, но легко случайно применить изменения не к тому окружению.

Для продакшена чаще выбирают отдельные каталоги или отдельные backend-конфигурации, а workspaces оставляют для временных и однотипных стендов. Внутри окружения полезно делить state по слоям: сеть, данные, приложения. Связь между ними — через terraform_remote_state или передачу outputs.

Импорт существующих ресурсов

Если ресурс создан вручную, его можно взять под управление без пересоздания:

import {
  to = aws_s3_bucket.assets
  id = "company-assets"
}

Порядок: описать ресурс в коде (или сгенерировать конфигурацию через terraform plan -generate-config-out=...), выполнить plan, убедиться, что изменений нет или они ожидаемы, затем apply. Для старых версий есть команда terraform import.

Drift: когда реальность разошлась с кодом

Drift — изменения, сделанные мимо Terraform: кто-то поправил правило firewall в консоли.

  1. Запустите terraform plan -refresh-only — он покажет, чем реальность отличается от state.
  2. Решите, что правильно: код или ручное изменение.
  3. Если правильно ручное — перенесите его в код. Если код — выполните обычный apply.
  4. Регулярно запускайте plan в CI по расписанию, чтобы замечать drift рано.

Для переименования ресурсов используйте блок moved или terraform state mv, для удаления из-под управления без удаления объекта — блок removed или terraform state rm.

Частые ошибки

  • Хранить terraform.tfstate в Git.
  • Править state вручную в текстовом редакторе.
  • Снимать блокировку (force-unlock), не убедившись, что другой процесс действительно завершился.
  • Давать всем разработчикам права на запись в продакшен-state.

Частые вопросы

Не стоит: в нём могут быть секреты, а Git не даёт блокировки, поэтому параллельные изменения приведут к конфликтам и повреждению state.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.