Terraform prevent_destroy: The Safety Latch Most Engineers Misunderstand

When Terraform builds its execution graph, it decides which resources will be created, updated, replaced, or destroyed. If any action includes a destroy on a resource with prevent_destroy = true, the entire plan fails. No partial approval. No soft warning. A hard stop.

This matters because replacements include a destroy. If you modify a ForceNew attribute, Terraform treats that as a new identity. New identity means replacement. Replacement means destroy plus create. That destroy trips the safety latch.

The real nuance is the Refresh Gap.

If someone deletes a resource manually in the AWS console, Terraform’s next refresh will detect the object is missing and remove it from state. Once it is gone from state, the lifecycle rule disappears with it. prevent_destroy protects you from your own configuration, but it cannot protect you from external drift.

Use it to guard identity anchors such as VPCs, KMS keys, or production parameters. Do not apply it blindly. Overuse turns refactoring into operational deadlock.

Understanding this mechanism prevents outages and prevents false confidence.