Terraform state: хранение и блокировка
State-файл — это сердце Terraform. Он хранит маппинг между конфигурацией и реальными ресурсами. Понимание работы со state критически важно для командного использования и production-сред.
Почему state важен
Terraform использует state для определения текущего состояния инфраструктуры. Каждый ресурс, описанный в конфигурации, сопоставляется с реальным объектом в облаке или на сервере. Без state Terraform не сможет понять, что именно нужно изменить или удалить.
В командев командной среде state state должен быть доступен изолированно и с блокировкой, чтобы два инженера не применяли изменения одновременно.
Сравнение бэкендов
Local backend
Самый простой вариант — state хранится локально в файле terraform.tfstate. Подходит только для личного использования и прототипирования.
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
S3 backend
Стандартный выбор для AWS. State хранится в S3-баккете с версионированием и шифрованием. Часто комбинируется с DynamoDB для блокировки.
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "eu-west-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
Consul backend
Хранит state в KV-хранилище Consul. Хороший вариант, если Consul уже используется для service discovery.
PostgreSQL backend
State хранится в таблице PostgreSQL. Подходит, если нужна аудиторская отчётность и интеграция с существующей БД.
terraform {
backend "pg" {
conn_str = "postgres://user:pass@host/dbname?sslmode=disable"
}
}
State locking через DynamoDB
Блокировка предотвращает параллельные terraform apply. При использовании S3 backend блокировка реализуется через DynamoDB:
aws dynamodb create-table \
--table-name terraform-locks \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
При запуске terraform apply Terraform создаёт запись в DynamoDB. Если запись уже существует — операция блокируется с ошибкой.
Всегда настраивайте state locking для командного использования. Один повреждённый state-файл может привести к потере контроля над инфраструктурой.
Миграция между бэкендами
Для миграции state между бэкендами используется команда terraform init с параметром -migrate-state:
# Миграция с local на S3
terraform init -migrate-state
Terraform автоматически скопирует state, проверит целостность и обновит конфигурацию. При миграции на S3 с DynamoDB убедитесь, что таблица блокировок уже создана.
Практические советы
- Используйте
terraform state listдля просмотра всех ресурсов в state - Разделяйте state по окружениям (dev, staging, prod) — это снижает blast radius
- Включайте
encrypt = trueдля S3 backend - Настройте versioning в S3 — это позволит восстановить state после случайного удаления
- Используйте
terraform state rmдля удаления ресурсов из state без удаления реальных объектов
Удалённые state операции
# Просмотр списка ресурсов
terraform state list
# Просмотр конкретного ресурса
terraform state show aws_instance.web
# Переименование ресурса
terraform state mv aws_instance.old_name aws_instance.new_name
# Удаление ресурса из state (ресурс не удаляется в облаке)
terraform state rm aws_instance.web
# Импорт существующего ресурса
terraform import aws_instance.web i-1234567890abcdef0
Регулярно проверяйте state через terraform plan. Если plan показывает неожиданные изменения — state мог рассинхронизироваться с реальностью.
Заключение
Правильная организация state — основа надёжной IaC-практики. Используйте удалённые бэкены с блокировкой, включайте шифрование и версионирование. Для команд избегайте local backend — это путь к конфликтам и потере данных.