lesson ── terraform-beginner ── ~8 мин ── 3 шагов
Destroy is apply with a minus sign. Terraform looks at the state, sees every resource it once created, and deletes them through the cloud API. You use it for ephemeral environments (spin up, check, tear down) and for closing out projects.
In real work destroy is dangerous: the data is gone, there is no undo.
That is why there is prevent_destroy, a guard against accidents. See
tf-destroy and tf-resource-lifecycle.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
resource "aws_s3_bucket" "demo" { bucket = "linuxlab-destroy-${random_id.suffix.hex}" tags = {Owner = "student"
}
}
resource "random_id" "suffix" {byte_length = 4
}
cd /home/student/tf-destroy
terraform init -input=false
terraform apply -auto-approve -input=false
The state will hold one resource (plus the random_id).
If apply fails: check the LocalStack logs with `docker logs localstack`.
✓ Bucket created. Now we will try destroy with protection.
Add a lifecycle block to the bucket:
resource "aws_s3_bucket" "demo" { bucket = "linuxlab-destroy-${random_id.suffix.hex}" tags = {Owner = "student"
}
lifecycle {prevent_destroy = true
}
}
Apply so that lifecycle lands in the state:
terraform apply -auto-approve
Now try to tear it down:
terraform destroy -auto-approve
It should fail with an error:
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.
This is protection, not a bug. In production it saves you from a typo in git rm.
If destroy went through: prevent_destroy did not take effect. Run `apply` again and check that the HCL was saved.
✓ Protection works: destroy is blocked. To tear it down, you first have to remove prevent_destroy.
OpenTofu keeps its CLI and state compatible with Terraform for the
commands in this step: migration usually goes through mv .terraform .terraform.bak; tofu init -upgrade. But on the first switch, back
up the state and run on a feature branch. The differences cluster
in the newer features (variables in backend, state encryption,
OCI registry-backed modules). See tf-opentofu-parity for the
full matrix.
To actually tear down the bucket, you first have to remove
prevent_destroy. Delete the lifecycle block from main.tf (or
change it to prevent_destroy = false). The file should look like
this again:
resource "aws_s3_bucket" "demo" { bucket = "linuxlab-destroy-${random_id.suffix.hex}" tags = {Owner = "student"
}
}
resource "random_id" "suffix" {byte_length = 4
}
Apply (lifecycle is removed from the state):
terraform apply -auto-approve
Now destroy works:
terraform destroy -auto-approve
At the end you will see:
Destroy complete! Resources: 2 destroyed.
If destroy still fails: prevent_destroy is still in the HCL. Delete the lifecycle block entirely or set it to false.
✓ All resources torn down. State is empty. This is the right path: a two-step guard.
If the terraform.tfstate file is lost (deleted, never committed,
the disk died): as far as Terraform is concerned, the created
resources no longer exist. You can no longer tear them down with
destroy (there is nothing to tear down). You can: (a) import them
back with terraform import (slow, one resource at a time);
(b) delete them by hand through the AWS Console or CLI. This is why
remote state with encryption and backups is a necessity in
production, not a luxury.
You saw destroy in action, then tried to protect a resource with
prevent_destroy = true and confirmed that Terraform really blocks
the deletion. This is your safety net in production.
команды
terraform destroy -auto-approvetear down every resource in stateterraform plan -destroyshow what would be torn down, without confirmingterraform apply -auto-approve -replace=<address>recreate one specific resourceконцепции