cd ..
TERRAFORM

Terraform Destroy: Undoing What Was Created

After putting init, plan, and apply into practice, the last piece of the cycle was missing: undoing what Terraform created. These are notes on terraform destroy, including a detail that has confused me before: the provider region.

flowchart LR
    Terraform["terraform"] -- init --> Init

    subgraph Init[".terraform"]
        Provider["provider"]
    end

    Terraform -- "plan or apply" --> State[("state file")]
    Terraform -- "plan or apply" --> HCL["HCL"]
    Terraform -- "plan or apply" --> API["API"] --> Cloud

    subgraph Cloud["Cloud"]
    end

A reminder about the provider region

When working with AWS, the region is important information in any operation, including when destroying resources. If the region is not explicitly configured in the code, Terraform might end up using a default region defined in the environment, rather than the one you expect.

This can cause confusion because a resource cannot be found (or destroyed) in a different region from where it was actually created. It’s always worth checking the provider block before running any destructive command.

Terraform Destroy

terraform destroy

The terraform destroy command is used to destroy resources managed by Terraform, meaning everything registered in that project’s state file.

Before destroying anything, Terraform shows a destruction plan and asks for confirmation, exactly like apply does. In the command output, resources to be removed are marked with the - symbol, the same symbol used in plan to indicate destruction.

This confirmation exists precisely to give a final chance to review what will be removed before the command proceeds.

Generating a separate destruction plan

It is also possible to generate a destruction plan before applying the removal of resources, without relying on the interactive confirmation of terraform destroy:

terraform plan -destroy -out destruir

This command creates a plan file indicating exactly what will be destroyed, in the same way that terraform plan -out saves a creation or alteration plan.

Afterward, this plan can be applied with:

terraform apply destruir

apply recognizes that file as a destruction plan and executes the removal of the resources listed in it, without needing to re-create the plan at the time.

Why separate plan and apply for destruction

The same logic as plan -out applies here: by saving the destruction plan to a file, what will be removed is recorded and reviewable before execution. This is especially useful in automated pipelines, where it makes sense to have a human step review the plan before a separate step applies the destruction, without relying on an interactive prompt in the middle of the process.

What destroy doesn’t reach

The terraform destroy command only knows how to destroy what is in the state file. Resources created manually via the AWS console, or by any other tool outside of Terraform, simply do not appear in this plan, because Terraform has no knowledge of them. This is another reason to keep the state file updated and, in real environments, remote: I talked about this in the post Terraform state, the file that can bring down your infra.

Conclusion

The terraform destroy command closes the cycle that starts with write and goes through plan and apply: just like creating and changing, removal also goes through a reviewable plan before anything truly happens. The most important takeaway is this: the - symbol in the plan output is the same warning, whether it’s part of a regular apply or a dedicated destroy, and it’s always worth pausing and reading before confirming.

References

What did you think?