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/lessons/tf-beginner-06-destroy

lesson ── terraform-beginner ── ~8 мин ── 3 шагов

Destroy: безопасно сносим инфру

Destroy, это apply со знаком минус. Terraform смотрит в state, видит все ресурсы, которые когда-то создал, и удаляет их через API облака. Используется для эфемерных окружений (поднял → проверил → снёс) и для закрытия проектов.

В реальной работе destroy опасен: данных не вернёшь, отката нет. Поэтому есть prevent_destroy, защита от случайностей. См. tf-destroy и tf-resource-lifecycle.

▶ интерактивный sandbox

Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.

запустить sandbox →

stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Создай бакет, который потом снесём

    hcl
    resource "aws_s3_bucket" "demo" {
      bucket = "linuxlab-destroy-${random_id.suffix.hex}"
      tags = {
        Owner = "student"
      }
    }
    resource "random_id" "suffix" {
      byte_length = 4
    }
    bash
    cd /home/student/tf-destroy
    terraform init -input=false
    terraform apply -auto-approve -input=false

    В state будет один ресурс (плюс random_id).

    подсказка

    Если apply падает: посмотри логи LocalStack: `docker logs localstack`.

    ✓ Бакет создан. Теперь попробуем destroy с защитой.

  2. 02

    Добавь prevent_destroy и попробуй снести

    Добавь блок lifecycle в бакет:

    hcl
    resource "aws_s3_bucket" "demo" {
      bucket = "linuxlab-destroy-${random_id.suffix.hex}"
      tags = {
        Owner = "student"
      }
      lifecycle {
        prevent_destroy = true
      }
    }

    Применить чтобы lifecycle был в state:

    bash
    terraform apply -auto-approve

    Теперь попробуй снести:

    bash
    terraform destroy -auto-approve

    Должно упасть с ошибкой:

    Error: Instance cannot be destroyed
    Resource aws_s3_bucket.demo has lifecycle.prevent_destroy set,
    but the plan calls for this resource to be destroyed.

    Это защита, а не баг. В проде это спасает от опечаток в git rm.

    подсказка

    Если destroy прошёл: значит, prevent_destroy не применился. Сделай `apply` ещё раз и проверь что HCL сохранился.

    ✓ Защита работает: destroy заблокирован. Чтобы снести, придётся сначала убрать prevent_destroy.

    То же самое на OpenTofu

    OpenTofu держит CLI и state совместимыми с Terraform по командам этого шага: миграция обычно проходит через mv .terraform .terraform.bak; tofu init -upgrade. Но при первом переходе сделай backup state и прогон на feature-branch - расхождения концентрируются в новых фичах (variables в backend, state-encryption, OCI registry-backed модули). См. tf-opentofu-parity для полной матрицы.

    • → OpenTofu parity
  3. 03

    Сними защиту и снеси

    Чтобы реально снести бакет. Нужно сначала убрать prevent_destroy. Удали блок lifecycle из main.tf (или поменяй на prevent_destroy = false). Файл должен снова выглядеть как:

    hcl
    resource "aws_s3_bucket" "demo" {
      bucket = "linuxlab-destroy-${random_id.suffix.hex}"
      tags = {
        Owner = "student"
      }
    }
    resource "random_id" "suffix" {
      byte_length = 4
    }

    Применить (lifecycle уберётся из state):

    bash
    terraform apply -auto-approve

    Теперь destroy сработает:

    bash
    terraform destroy -auto-approve

    В конце увидишь:

    Destroy complete! Resources: 2 destroyed.
    подсказка

    Если destroy всё ещё падает: значит, prevent_destroy остался в HCL. Удали блок lifecycle полностью или замени на false.

    ✓ Все ресурсы снесены. State пуст. Это правильный путь: двухшаговая защита.

    Что произойдёт если потерять state

    Если файл terraform.tfstate потерян (удалили, не закоммитили, винт умер): для Terraform созданные ресурсы перестают существовать. Снести их через destroy уже не получится (нечего сносить). Можно: (а) импортнуть их обратно через terraform import (долго, ресурс за ресурсом); (б) удалить через AWS Console или CLI вручную. Поэтому remote state с шифрованием и резервированием, не roскошь, а необходимость для прода.

    • → Terraform state
    • → Backend для state

Что ты узнал

Ты увидел destroy в действии, потом попробовал защититься через prevent_destroy = true и убедился что Terraform реально блокирует попытку удаления. Это твоя страховка в проде.

команды

  • terraform destroy -auto-approveснести все ресурсы из state
  • terraform plan -destroyпоказать что снесётся без подтверждения
  • terraform apply -auto-approve -replace=<address>пересоздать конкретный ресурс

концепции

  • · Destroy = удалить всё что в state, в обратном порядке зависимостей
  • · prevent_destroy блокирует попытку удаления: не дальше плана
  • · После destroy state остаётся, но resources в нём пусто

← предыдущий

Infracost, оценка стоимости плана

следующий →

Remote state в S3 (на LocalStack)

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки