linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/kb/State/tf-state

kb/state ── State ── beginner

State: память Terraform о созданном

State. JSON-файл terraform.tfstate, где Terraform записывает, что он создал в облаке. Без него Terraform не знал бы, какой бакет «его», а какой чужой. Содержит ID ресурсов, все атрибуты, и часто секреты. Самая чувствительная часть проекта.

view as markdown

Зачем нужен state

Представьте: вы написали HCL с одним S3-бакетом и сделали apply. Бакет создался, имя, my-bucket-12345. Запускаете apply ещё раз. Откуда Terraform узнает, что бакет: тот же самый бакет?

  • Из HCL? Нет, в HCL только желаемое описание.
  • Из API AWS? Нет, в AWS миллион бакетов, и какой из них «ваш». Terraform не знает.

Ответ: из state-файла. После первого apply Terraform запомнил в terraform.tfstate: «Ресурс aws_s3_bucket.demo → реальный бакет с именем my-bucket-12345, ARN такой-то, создан тогда-то».

Без этой записи Terraform каждый раз пытался бы создавать всё заново, и падал бы на «bucket already exists».

Где живёт state

По умолчанию, файл terraform.tfstate в той же директории, что HCL. Это называется local backend.

my-project/
├── main.tf
├── terraform.tfstate         # ← вот он
└── terraform.tfstate.backup  # копия с предыдущего apply

В реальных проектах state выносят в remote backend. S3, Terraform Cloud, и т.п. Чтобы команда могла работать с одним state'ом и не конфликтовать. См. tf-init-backends.

Что внутри

Это JSON. Можно посмотреть руками, но не редактируйте:

json
{
  "version": 4,
  "terraform_version": "1.9.8",
  "serial": 5,
  "lineage": "abc-123-...",
  "resources": [
    {
      "mode": "managed",
      "type": "aws_s3_bucket",
      "name": "demo",
      "instances": [
        {
          "attributes": {
            "id": "my-bucket-12345",
            "bucket": "my-bucket-12345",
            "arn": "arn:aws:s3:::my-bucket-12345",
            "region": "us-east-1",
            "tags": { "Owner": "student" }
          }
        }
      ]
    }
  ]
}

Ключевые поля:

  • serial, счётчик. Каждый apply увеличивает на 1. Для проверки актуальности.
  • lineage, уникальный UUID этого state'а. Защита от случайной подмены файла.
  • resources, массив всех ресурсов под управлением. Тип, имя, атрибуты.

Команды для работы со state

Сам файл руками не трогаем. Есть CLI:

bash
# Список всех ресурсов в state
terraform state list
# Показать атрибуты одного ресурса
terraform state show aws_s3_bucket.demo
# Целиком state в JSON (для скриптов)
terraform show -json

Опасные (нужны в исключительных случаях):

bash
# Удалить ресурс из state (НЕ из облака)
terraform state rm aws_s3_bucket.demo
# Переименовать ресурс в state
terraform state mv aws_s3_bucket.demo aws_s3_bucket.renamed
# Импортировать существующий ресурс в state (resource уже в HCL описан)
terraform import aws_s3_bucket.demo my-existing-bucket

Эти команды напрямую правят terraform.tfstate. Перед ними делайте бэкап файла.

Drift, расхождение state и реальности

State, это снапшот того, что Terraform думает. Реальность в облаке может уйти.

Примеры drift'а:

  • Кто-то руками удалил бакет через AWS Console.
  • Auto-scaling сам изменил desired_capacity.
  • Включился ALB Auto-Scaling target.

При следующем plan Terraform читает state и сравнивает с HCL. Если реальность отличается от state, plan -refresh=true (default) сначала обновит state из API, потом покажет diff.

Это нормально, но требует внимания. См. tf-resource-lifecycle про ignore_changes для атрибутов, которые меняются вне Terraform.

Секреты в state

Это критично понять: state содержит все атрибуты, включая чувствительные.

  • Пароль БД (aws_db_instance.password): в state.
  • Токены, ключи, secret values, в state.
  • sensitive = true маскирует только в CLI-выводе. В JSON-файле, открытым текстом.

Поэтому:

  • Local state в git, нельзя. Никогда. Даже если репозиторий приватный, рано или поздно утечёт.
  • Local state на диске общего сервера, тоже плохо. Любой sudo-user прочитает.
  • Remote backend с шифрованием, обязательно для продакшена. S3 + SSE-KMS, Terraform Cloud с шифрованием на стороне, и т.п.

Lock, защита от одновременного apply

Если два человека одновременно запустят apply на одном проекте, state может побиться. Решается locking:

  • Local backend не имеет lock'а. Это риск даже на одном компьютере (открыли два терминала).
  • S3 backend + DynamoDB для lock'а, стандарт. Один apply удерживает запись в DynamoDB, второй ждёт.
  • Terraform Cloud делает lock автоматически.

При попытке параллельного apply вы увидите:

Error: Error acquiring the state lock
Lock Info:
  ID:        abc-123
  Path:      s3://my-bucket/terraform.tfstate
  Operation: OperationTypeApply
  Who:       user@host
  Created:   2026-05-20 14:00:00 +0000 UTC

Если знаете, что другой процесс мёртв, terraform force-unlock <lock-id>.

Подводные камни

  • Не редактируйте state руками. JSON выглядит простым, но Terraform проверяет внутренние инварианты (lineage, serial, hashes). Сломаете, будете долго чинить.

  • Не коммитьте state в git. Никогда. Даже local. Добавьте в .gitignore:

    terraform.tfstate
    terraform.tfstate.backup
    .terraform/
    .terraform.lock.hcl  # ← а это, наоборот, коммитьте
  • State синхронизирован только с одной точкой времени. Между apply'ями он не «следит» за облаком. Если хотите свежие данные, terraform refresh или terraform plan (тоже делает refresh).

  • state rm не удаляет ресурс в облаке. Только из state. Ресурс остаётся существовать «вне Terraform». Полезно при миграции, опасно при ошибке.

  • state mv нужен при переименовании. Если в HCL поменяли "demo" на "main", без state mv Terraform пересоздаст ресурс. После state mv, только обновит запись, без обращения в облако.

  • Lineage защищает от подмены, но можно сломать. Если случайно перетёрли state копией из другого проекта, lineage не совпадёт. Terraform откажется работать. Это защита, а не баг.

§ команды

bash
terraform state list

Список всех ресурсов под управлением. Первая команда при разборе незнакомого проекта.

bash
terraform state show aws_s3_bucket.demo

Все атрибуты одного ресурса: то, что Terraform думает о нём.

bash
terraform show -json | jq '.values.root_module.resources'

Все ресурсы в state через jq: для скриптов и анализа.

bash
terraform refresh

Обновить state из реального облака. Полезно перед опасным plan'ом.

bash
terraform state pull > backup.tfstate

Скачать текущий state в файл (работает с любым backend). Бэкап перед опасными операциями.

§ см. также

  • tf-initterraform init: первая команда в любом проектеterraform init скачивает плагины-провайдеры (AWS, GCP и т.д.), создаёт файл с зафиксированными версиями (lockfile) и подготавливает рабочую директорию. Без этого ни plan, ни apply не запустятся.
  • tf-init-backendsBackend в Terraform: где живёт stateBackend, это место хранения state-файла. По умолчанию local, рядом с HCL. Remote backends (S3, GCS, Terraform Cloud, http) дают совместный доступ и блокировку. В этом курсе используется только local; remote, обзорно.
  • tf-planterraform plan: посмотреть, что Terraform собирается сделатьplan, это сухая прогонка: Terraform читает ваш HCL, читает state, и показывает diff между ними. Ничего не меняет в облаке. Главный инструмент, чтобы не сломать прод по ошибке.
  • tf-applyterraform apply: применить план в реальном облакеapply берёт результат plan и реально вызывает API облака: создаёт, изменяет, удаляет ресурсы. После apply state обновляется. Это та команда, которая меняет деньги на инфру.
  • tf-resource-blockБлок resource: главный кирпич Terraformresource, это блок, который говорит Terraform «создай мне такую штуку в облаке». У него три части: тип ресурса (что это), имя (как зовём внутри), и аргументы (как настроить). 90% времени в Terraform, это написание таких блоков.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки