Что делает destroy
terraform destroy, это «apply наоборот». Он смотрит в state, видит все ресурсы, которые когда-то создавал, и удаляет их через API облака. После destroy state становится пустым.
По сути это эквивалент:
Plan: 0 to add, 0 to change, N to destroy.
где N, все ресурсы, которыми управляет Terraform.
Когда это полезно
- Учебные задачи. Поэкспериментировал, снёс, повторил. Никаких следов.
- Эфемерные окружения. Поднял preview-окружение для PR, прогнал тесты, снёс.
- Конец проекта. Заказчик закрыл проект,
destroy, не оставляем висящие ресурсы. - Откат неудачного эксперимента. Создал не то,
destroy, начинаем заново.
Как это выглядит
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, сначала сносится бакет, потом ключ.
Точечное удаление
Иногда нужно снести только один ресурс, не всё:
terraform destroy -target=aws_s3_bucket.demo
Это эквивалентно: «убери из HCL только этот блок и сделай apply». Применяется редко, но бывает полезно, например, ресурс «застрял» и его проще пересоздать.
Альтернативно, если ресурс нужно пересоздать, лучше используйте terraform apply -replace=aws_s3_bucket.demo. Это «снести и создать заново в одном apply».
Защита от случайного destroy: prevent_destroy
В блоке lifecycle можно поставить флаг:
resource "aws_rds_instance" "prod_db" {# ... Параметры ...
lifecycle {prevent_destroy = true
}
}
Теперь terraform destroy (или любой apply, который пытается удалить этот ресурс) падает с ошибкой. Чтобы реально снести, придётся сначала убрать prevent_destroy = true, сделать apply, и только потом destroy.
Это лучший друг продакшена. См. tf-resource-lifecycle.
Подводные камни
-
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 кому попало.