# How to Use Terraform prevent_destroy to Protect Critical Infrastructure from Accidental Deletion

> Learn how to use Terraform prevent_destroy to protect critical infrastructure from accidental deletion. Prevent unintended resource removal with simple configuration.

- Repository: [HashiCorp/terraform](https://github.com/hashicorp/terraform)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Set `prevent_destroy = true` inside a `lifecycle` block within any Terraform resource to block accidental destruction during plan and apply operations.**

The `terraform prevent_destroy` lifecycle argument acts as a critical safety mechanism for infrastructure resources managed by HashiCorp Terraform. When enabled, this meta-argument prevents Terraform from destroying protected resources even if configuration changes or explicit destroy commands would normally remove them. Understanding how to implement and manage this protection requires examining the actual implementation in the `hashicorp/terraform` repository.

## Understanding the Terraform prevent_destroy Lifecycle Meta-Argument

The `prevent_destroy` argument is part of Terraform's `lifecycle` meta-argument block, which controls how Terraform manages specific resource instances during create, update, and destroy operations.

### How prevent_destroy Works Under the Hood

According to the `hashicorp/terraform` source code, the protection mechanism operates in three distinct phases:

1. **Configuration Parsing**: When Terraform parses your configuration files, the `lifecycle` block containing `prevent_destroy` is decoded in [`internal/configs/resource.go`](https://github.com/hashicorp/terraform/blob/main/internal/configs/resource.go). The parser stores this flag in the resource's managed meta-state as `Managed.PreventDestroy`.

2. **Plan Validation**: During the planning phase, Terraform constructs a graph of proposed actions. Each resource instance node (`NodeAbstractResourceInstance`) executes the `checkPreventDestroy` method defined in [`internal/terraform/node_resource_abstract_instance.go`](https://github.com/hashicorp/terraform/blob/main/internal/terraform/node_resource_abstract_instance.go). This method inspects the planned action and the stored flag.

3. **Error Generation**: If the planned action involves destruction (including replacement operations that require deletion) and `prevent_destroy` is set to `true`, Terraform returns a diagnostic error that halts the plan execution. The error message instructs users to either remove the protection or narrow the plan scope using `-target`.

## Implementing Terraform prevent_destroy in Your Configuration

Adding protection to critical resources requires minimal syntax changes to your Terraform configuration files.

### Basic Syntax and Usage

Place the `lifecycle` block inside any resource definition and set `prevent_destroy = true`:

```hcl
resource "aws_s3_bucket" "production_logs" {
  bucket = "company-production-logs"
  
  tags = {
    Environment = "production"
    Critical    = "true"
  }

  lifecycle {
    prevent_destroy = true
  }
}

```

This configuration prevents accidental destruction of the S3 bucket even if someone removes the resource block from the configuration or runs `terraform destroy`.

### Verifying Protection with Terraform Plan

After applying the configuration with `prevent_destroy` enabled, attempt to destroy the resource to verify the protection works:

```bash

# This will fail with an error

terraform plan -destroy -target=aws_s3_bucket.production_logs

```

Terraform outputs an error similar to:

```

Error: Instance cannot be destroyed
Resource aws_s3_bucket.production_logs has lifecycle.prevent_destroy set,
but the plan calls for this resource to be destroyed. To avoid this error,
continue to use the resource in your configuration, or remove the
lifecycle.prevent_destroy setting.

```

## Bypassing prevent_destroy When Necessary

While the protection is designed to prevent accidents, legitimate scenarios require destroying protected resources. The `hashicorp/terraform` source code provides specific mechanisms for these situations.

### Configuration-Level Override

The standard method for removing protection involves modifying the configuration:

1. Remove the `lifecycle` block entirely, or
2. Set `prevent_destroy = false`:

```hcl
resource "aws_s3_bucket" "production_logs" {
  bucket = "company-production-logs"
  
  lifecycle {
    prevent_destroy = false  # Protection removed

  }
}

```

After applying this change, destruction operations will proceed normally.

### Targeted Destruction and Internal Overrides

According to [`internal/terraform/context_plan.go`](https://github.com/hashicorp/terraform/blob/main/internal/terraform/context_plan.go), Terraform supports an `OverridePreventDestroy` option within `PlanOpts`. This boolean flag is reserved for internal use and specific edge cases:

- **Destroy-only plans**: When running `terraform destroy -target=...`, Terraform can set this override to allow destruction of specifically targeted protected resources while maintaining protection for others.
- **Test harnesses**: The Terraform test framework uses this option to clean up resources after test completion.

Normal user workflows cannot access this override directly through CLI flags. The intended user-facing approach for destroying protected resources remains modifying the configuration or using targeted operations that respect the lifecycle constraints.

## Summary

- **Terraform prevent_destroy** is a lifecycle meta-argument that blocks destruction of critical resources during plan and apply operations.
- The protection mechanism parses the `lifecycle` block in [`internal/configs/resource.go`](https://github.com/hashicorp/terraform/blob/main/internal/configs/resource.go) and validates destruction attempts in [`internal/terraform/node_resource_abstract_instance.go`](https://github.com/hashicorp/terraform/blob/main/internal/terraform/node_resource_abstract_instance.go) via the `checkPreventDestroy` method.
- When enabled, any plan that would destroy or replace the protected resource fails with a diagnostic error, forcing explicit configuration changes to proceed.
- To destroy a protected resource, either remove the `prevent_destroy` argument from the configuration or use targeted destruction workflows that leverage internal override mechanisms reserved for specific use cases.
- The `OverridePreventDestroy` option in [`internal/terraform/context_plan.go`](https://github.com/hashicorp/terraform/blob/main/internal/terraform/context_plan.go) exists for internal tooling and destroy-target operations, but standard users should modify configuration files to remove protection.

## Frequently Asked Questions

### What happens if I try to destroy a resource with prevent_destroy set to true?

Terraform halts the plan execution and returns an error stating that the resource has `lifecycle.prevent_destroy` set, but the plan calls for destruction. The error message instructs you to either continue using the resource in your configuration or remove the `prevent_destroy` setting. This check occurs in [`internal/terraform/node_resource_abstract_instance.go`](https://github.com/hashicorp/terraform/blob/main/internal/terraform/node_resource_abstract_instance.go) within the `checkPreventDestroy` method.

### Can I override terraform prevent_destroy without modifying the configuration?

Standard CLI workflows require modifying the configuration to remove protection. However, Terraform's internal planning engine in [`internal/terraform/context_plan.go`](https://github.com/hashicorp/terraform/blob/main/internal/terraform/context_plan.go) supports an `OverridePreventDestroy` flag within `PlanOpts` that bypasses the check. This override is reserved for internal use cases such as `terraform destroy -target` operations and test framework cleanup, and is not exposed as a user-facing command-line flag.

### Does prevent_destroy protect against resource replacement?

Yes. Terraform treats replacement operations as a delete followed by a create. The `checkPreventDestroy` method in [`internal/terraform/node_resource_abstract_instance.go`](https://github.com/hashicorp/terraform/blob/main/internal/terraform/node_resource_abstract_instance.go) checks if the planned action includes a delete operation. If `prevent_destroy` is enabled and the plan requires replacement (which destroys the existing instance), Terraform blocks the operation with the same error used for pure destruction.

### Where is the prevent_destroy setting stored in the Terraform state?

The `prevent_destroy` value is not stored in the Terraform state file itself. Instead, it is parsed from the configuration during the decoding phase in [`internal/configs/resource.go`](https://github.com/hashicorp/terraform/blob/main/internal/configs/resource.go) and stored in the resource's managed meta-state (`Managed.PreventDestroy`) within the internal configuration representation. Terraform evaluates this flag during the planning phase by checking the configuration meta-state against the planned actions, not by referencing the state file.