# terraform destroy: снести всё, что было создано _Основы Terraform · TerraformLab Knowledge Base_ **TL;DR:** destroy удаляет все ресурсы, которые описаны в HCL и есть в state. По сути это apply с минусом перед всем. Незаменим для учебных задач и эфемерных окружений; в проде, крайняя мера. ## Что делает `destroy` `terraform destroy`, это «apply наоборот». Он смотрит в state, видит все ресурсы, которые когда-то создавал, и удаляет их через API облака. После destroy state становится пустым. По сути это эквивалент: ``` Plan: 0 to add, 0 to change, N to destroy. ``` где N, все ресурсы, которыми управляет Terraform. ## Когда это полезно - **Учебные задачи.** Поэкспериментировал, снёс, повторил. Никаких следов. - **Эфемерные окружения.** Поднял preview-окружение для PR, прогнал тесты, снёс. - **Конец проекта.** Заказчик закрыл проект, `destroy`, не оставляем висящие ресурсы. - **Откат неудачного эксперимента.** Создал не то, `destroy`, начинаем заново. ## Как это выглядит ```bash terraform destroy ``` Terraform покажет план (как `plan`, но с минусами): ``` Terraform will perform the following actions: # aws_s3_bucket.demo will be destroyed - resource "aws_s3_bucket" "demo" { - bucket = "my-bucket-12345" -> null - tags = { ... } -> null - id = "my-bucket-12345" -> null } Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure... There is no undo. Only 'yes' will be accepted to confirm. Enter a value: ``` Обратите внимание на фразу **There is no undo**. Это правда: отката нет. Удалили S3-бакет, данные ушли. RDS-инстанс, снепшоты пропали (если не было `skip_final_snapshot = false`). Введите `yes`. Terraform начинает сносить в обратном порядке зависимостей. Если бакет ссылается на ключ KMS, сначала сносится бакет, потом ключ. ## Точечное удаление Иногда нужно снести только один ресурс, не всё: ```bash terraform destroy -target=aws_s3_bucket.demo ``` Это эквивалентно: «убери из HCL только этот блок и сделай apply». Применяется редко, но бывает полезно, например, ресурс «застрял» и его проще пересоздать. **Альтернативно**, если ресурс нужно пересоздать, лучше используйте `terraform apply -replace=aws_s3_bucket.demo`. Это «снести и создать заново в одном apply». ## Защита от случайного destroy: `prevent_destroy` В блоке `lifecycle` можно поставить флаг: ```hcl resource "aws_rds_instance" "prod_db" { # ... Параметры ... lifecycle { prevent_destroy = true } } ``` Теперь `terraform destroy` (или любой `apply`, который пытается удалить этот ресурс) **падает с ошибкой**. Чтобы реально снести, придётся сначала убрать `prevent_destroy = true`, сделать apply, и только потом destroy. Это лучший друг продакшена. См. [tf-resource-lifecycle](/terraform/kb/tf-resource-lifecycle.md). ## Подводные камни - **Destroy удаляет только то, что в state.** Если в облаке есть ресурсы, созданные вручную (не Terraform), он их не тронет. - **Destroy не удаляет state-файл.** После destroy `terraform.tfstate` остаётся, но в нём, пусто (`"resources": []`). Если хотите начать с чистого листа, удалите файл вручную. - **Зависимости могут блокировать destroy.** Если у вас S3-бакет с объектами внутри. AWS не даст удалить бакет без `force_destroy = true` в HCL. Это защита AWS, не Terraform'а; Terraform упадёт с ошибкой провайдера. - **`destroy -target`, это костыль.** Регулярное использование `-target` означает, что граф зависимостей у вас неправильный. - **В CI destroy запускайте с осторожностью.** Лучше отдельный пайплайн для destroy, доступный только нескольким людям, с двойным подтверждением. - **Auto-approve опасен.** `terraform destroy -auto-approve` без раздумий сносит всё. В проде, никогда. ## Восстановление после destroy Никак. Это не git revert. Если данные были, они пропали. Поэтому: - Перед destroy делайте бэкап (snapshot RDS, S3 versioning, EBS snapshot). - На критичные ресурсы вешайте `prevent_destroy = true`. - В прод-репозиториях вообще не давайте права на destroy кому попало. ## Команды ```bash terraform destroy ``` Снести все ресурсы из state с интерактивным подтверждением. ```bash terraform destroy -auto-approve ``` Без вопросов. Только для учебных/эфемерных окружений. ```bash terraform destroy -target=aws_s3_bucket.demo ``` Точечно снести один ресурс. Использовать редко. ```bash terraform plan -destroy ``` Показать, что снесётся, без подтверждения и без применения. Безопасный preview. ## См. также - [terraform apply: применить план в реальном облаке](/terraform/kb/tf-apply.md) - [terraform plan: посмотреть, что Terraform собирается сделать](/terraform/kb/tf-plan.md) - [State: память Terraform о созданном](/terraform/kb/tf-state.md) - [lifecycle: управляем поведением resource](/terraform/kb/tf-resource-lifecycle.md)