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/Основы Terraform/tf-plan

kb/core ── Основы Terraform ── beginner

terraform plan: посмотреть, что Terraform собирается сделать

plan, это сухая прогонка: Terraform читает ваш HCL, читает state, и показывает diff между ними. Ничего не меняет в облаке. Главный инструмент, чтобы не сломать прод по ошибке.

view as markdown

Зачем нужен plan

terraform plan, это примерка. Вы пишете HCL: «хочу один бакет с тегами». Terraform смотрит, что уже создано (это записано в state-файле), и показывает разницу: «нужно создать один новый бакет, изменений и удалений нет».

Главное: plan ничего не меняет. Он не звонит в AWS с командой «создай». Он только смотрит и сравнивает. Это безопасная команда, её можно запускать сколько угодно раз.

Что показывает plan

Допустим, вы написали:

hcl
resource "aws_s3_bucket" "demo" {
  bucket = "my-bucket-12345"
  tags = {
    Owner = "student"
  }
}

И запустили terraform plan. Вывод примерно такой:

Terraform will perform the following actions:
  # aws_s3_bucket.demo will be created
  + resource "aws_s3_bucket" "demo" {
      + bucket = "my-bucket-12345"
      + id     = (known after apply)
      + tags   = {
          + "Owner" = "student"
        }
    }
Plan: 1 to add, 0 to change, 0 to destroy.

Разбор:

  • + resource ..., этот ресурс будет создан. Знак + = добавить.
  • + bucket = "my-bucket-12345", значение, которое Terraform отправит в API.
  • + id = (known after apply), атрибут появится только после создания, сейчас его не знаем.
  • Plan: 1 to add, 0 to change, 0 to destroy, итоговая сводка. Это самая важная строчка.

Знаки в diff'е (запомните)

ЗнакЧто значит
+Создать новый ресурс или атрибут
-Удалить ресурс или атрибут
~Изменить значение (можно сделать без пересоздания)
-/+Удалить и создать заново (force replacement)

Самый опасный, -/+. Он значит «ресурс нужно пересоздать с нуля». Если это база данных, данные пропадут. Если EC2, потеряете IP-адрес. Всегда вчитывайтесь в строки с -/+.

Exit code: 0, 1, 2

По умолчанию terraform plan всегда возвращает exit code 0, даже если есть изменения. Это удобно для CI: команда не падает.

Но если запустить с флагом -detailed-exitcode, появляется новая логика:

  • 0, изменений нет, state == HCL. «No changes».
  • 1, ошибка (синтаксис, провайдер не отвечает, токен невалиден).
  • 2, план есть, изменения требуются.
bash
terraform plan -detailed-exitcode
echo $?   # 0, 1 или 2

Это незаменимо в скриптах: «если есть drift, пришли мне алерт».

Сохранение плана в файл

plan можно сохранить и потом применить ровно его (без пересчёта):

bash
terraform plan -out=tfplan.bin    # сохранили
terraform apply tfplan.bin        # применяем именно этот план

Зачем так делают:

  • В CI: ревьюер видит plan в PR, мержит, и apply применяет ровно то, что было показано. Между показом и применением никакой код не успеет «подсунуться».
  • tfplan.bin может содержать секреты (если они в state). Не коммитьте его в git.

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

  • «No changes», это инвариант, к которому надо стремиться после apply. Если сразу после apply повторный plan показывает изменения, значит, у вас drift (что-то изменилось вне Terraform), или ваш HCL не отражает реальность. Это плохой признак.

  • Plan читает state, а не реальный AWS. Если кто-то руками удалил бакет в консоли, plan этого не заметит, пока не сделаете terraform refresh или terraform plan -refresh=true (это default, но иногда отключают). См. tf-state.

  • Plan может выполняться долго. На больших проектах (тысячи ресурсов) plan может занимать минуты. Terraform опрашивает облако про каждый. Это нормально. Если очень больно, -target=resource.name для точечного плана.

  • Plan не предсказывает всё. Некоторые атрибуты вычисляются на стороне облака. Plan покажет (known after apply), это нормально, это не «секрет», просто значение появится после создания.

  • -target использовать редко. Это «костыль для непредвиденных ситуаций». Регулярное использование -target, признак, что ваш HCL неправильно структурирован.

§ команды

bash
terraform plan

Базовый запуск: показать diff между HCL и state.

bash
terraform plan -detailed-exitcode

Exit 0: нет изменений; 1: ошибка; 2, есть изменения. Для CI-скриптов.

bash
terraform plan -out=tfplan.bin

Сохранить план в файл: чтобы apply применил ровно его.

bash
terraform plan -no-color

Без ANSI-цветов: для логов в CI или сравнения diff'ов.

bash
terraform plan -target=aws_s3_bucket.demo

Точечный план только для одного ресурса. Использовать редко.

§ см. также

  • tf-initterraform init: первая команда в любом проектеterraform init скачивает плагины-провайдеры (AWS, GCP и т.д.), создаёт файл с зафиксированными версиями (lockfile) и подготавливает рабочую директорию. Без этого ни plan, ни apply не запустятся.
  • tf-applyterraform apply: применить план в реальном облакеapply берёт результат plan и реально вызывает API облака: создаёт, изменяет, удаляет ресурсы. После apply state обновляется. Это та команда, которая меняет деньги на инфру.
  • tf-destroyterraform destroy: снести всё, что было созданоdestroy удаляет все ресурсы, которые описаны в HCL и есть в state. По сути это apply с минусом перед всем. Незаменим для учебных задач и эфемерных окружений; в проде, крайняя мера.
  • tf-stateState: память Terraform о созданномState. JSON-файл terraform.tfstate, где Terraform записывает, что он создал в облаке. Без него Terraform не знал бы, какой бакет «его», а какой чужой. Содержит ID ресурсов, все атрибуты, и часто секреты. Самая чувствительная часть проекта.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки