# How to disable AWS instance destroy with Terraform?

> Techniques to prevent infrastructure destroy in Terraform by protecting selected instances and resources from being accidentally destroyed.

- Source: https://www.itwonderlab.com/avoiding-instance-destroy-aws-with-terraform/
- Published: 2020-07-03
- Updated: 2026-10-05
- Author: Javier Ruiz Jiménez (https://www.javierruizjimenez.com/)
- Site: IT Wonder Lab (https://www.itwonderlab.com/)

---

## Protect your AWS infrastructure in Production from accidental deletion

Deleting infrastructure is perfectly normal during development, but **once you are in production it is important to protect some instances and resources from being accidentally destroyed by Terraform**.

Updates:

-   2020 Jul 03: Updated to Terraform 0.12
-   2026 Oct 05: Added the `prevent_destroy` lifecycle setting and reviewed the text for current Terraform and OpenTofu versions

![terraform logo200x100](https://www.itwonderlab.com/media/logos/Others/terraform_logo200x100.png)

Some might say that since we are using Terraform and infrastructure as code, the infrastructure can be recreated in minutes (depending on size and Cloud provider speed), and that is true, so it is not a problem to delete an instance, a database or a VPC, but I believe that once you are in production, it is not acceptable to have your systems and applications down.

Recreating an instance is really easy and a fast operation using AWS and Terraform, but then you have to install software, configure and deploy the application, maybe load data from backup and that can be really time consuming.

In a world of micro-services and cloud-native applications, adding instances and removing them from the pool is fast and desirable, but not everything is a micro-service or has many clones for high availability and fail-over.

Think, for example, of a Cassandra node or an Elasticsearch node, or a traditional Database node.

Your responsibility is to protect those nodes and only in the case of a hard failure or a planned maintenance replace them.

## How to prevent infrastructure destroy in Terraform

How do you protect AWS instances from being destroyed by Terraform, or by a user through the AWS control panel or other tools?

AWS instances have some configuration properties for this:

-   Preserve AWS EBS volumes on Termination
-   Enable AWS EC2 Instance Termination Protection
-   Enable AWS RDS instance Deletion protection (Available Sep 2018)

**By default, all AWS EBS root device volumes are deleted when the instance terminates. EC2 and RDS instances can be terminated using the AWS API or the AWS control panel**.

To change this behavior, in Terraform I like to include a global variable that indicates if the infrastructure is in production or not.

**terraform.tfvars**

```json
is_production = false
```

The variable is\_production will be false during the development of Terraform plans and will be changed to true as soon as the infrastructure is in production or live.

## Disable EC2 instance deletion

When creating instances, the value of is\_production will be used to set the disable\_api\_termination and delete\_on\_termination arguments as shown on the example.

**aws\_ec2\_pro\_srv1234.tf**

```json
resource "aws_instance" "srv1234" {
 ....
 disable_api_termination = var.is_production ? true : false
 instance_initiated_shutdown_behavior = "stop"
 ...
 root_block_device {
 ...
 delete_on_termination = var.is_production ? false : true
}
...
}
```

If this configuration is in place, the **is\_production** variable is true and the infrastructure has been deployed, you will have to use the AWS console or edit your Terraform resources to change the values of instance\_initiated\_shutdown\_behavior to be able to destroy the instances.

A third configuration property sets the behavior for an instance shutdown, the default behavior is to stop the instance but it can be changed to destroy if needed.

## Disable RDS instance deletion

It is also possible to **prevent the deletion of a database instance** by using the property `deletion_protection` of [RDS](https://www.itwonderlab.com/aws-rds/). The default value of the property if unspecified is false.

**aws\_rds\_pro\_rds789.tf**

```json
resource "aws_db_instance" "rds789" {
 ....
 deletion_protection  = var.is_production ? true : false
 ...
}
```

[Database deletion protection](https://aws.amazon.com/about-aws/whats-new/2018/09/amazon-rds-now-provides-database-deletion-protection/) is available in RDS since September 2018.

Controlling these variables can avoid many problems, like when having a Multi-AZ RDS database that has changed availability zone for maintenance or an upgrade from what is specified in Terraform local state. In this case, Terraform thinks that the database needs to be recreated, in the “configured” availability zone and proceeds to destroy the database if the plan is applied. Having **deletion\_protection** enabled will prevent the deletion.

## Prevent destroy in Terraform and OpenTofu: lifecycle

The properties above are enforced by AWS, for any tool or user. Terraform and OpenTofu also have their own protection, the `prevent_destroy` argument of the `lifecycle` block: any plan that would destroy the resource, including `terraform destroy`, fails with an error.

```hcl
resource "aws_db_instance" "ditwl-rds-001" {
  # ...
  deletion_protection = var.is_production

  lifecycle {
    prevent_destroy = true
  }
}
```

Be aware that `prevent_destroy` only works while the resource is in the code: if the resource block is removed, Terraform destroys the resource. The argument also cannot be set from a variable, so use it together with `deletion_protection` and the AWS termination protection. It is used, for example, in the [Terraform Backends](https://www.itwonderlab.com/aws-terraform-tutorial-terraform-backends/) tutorial to protect the bucket of the state. Other useful `lifecycle` arguments are `create_before_destroy` and `ignore_changes`.

See also [AWS EC2](https://www.itwonderlab.com/aws-ec2/) and [AWS RDS](https://www.itwonderlab.com/aws-rds/).
