Terraform: Destroy / Replace Buckets

In Terraform, you can easily destroy a resource by either running terraform destroy (with or without resource targetting), or removing the resource / changing the configuration.

When we are dealing with S3 buckets, there are multiple scenarios where we might now be able to destroy the bucket. Here are a few of them, and how to deal with each of them —

The Prevent Destroy flag is on

The purpose of the prevent_destroy flag is to mistakenly destroy S3 buckets that we did not really want to destroy. For example, let’s say you have the following snippet —

resource "aws_s3_bucket" "my_bucket" {
bucket = "my_new_terraform_bucket"
acl
= "private"
lifecycle
{
prevent_destroy = true
}
versioning {
enabled = true
}
}

Now, if you either change the name of the bucket, or run terraform destroy, terraform will reject the plan. This is because terraform wants you to not destroy a resource you’ve explicitly marked as non destroyable.

However, if you remove the whole block, terraform assumes that it’s a conscious action on the part of the developer and will remove it.

The bucket is versioned and/or contains objects

In the previous example, even if you change the prevent_destroy flag to off, and then try to delete the bucket, it will not let you do it if there is some version of some object in the bucket. Even if you delete the objects from console, the pervious version still exists, so it will not allow you to delete it.

The solution is to destroy it in 2 steps. First, change the prevent_destroy flag to false, and make force_destroy true.

resource "aws_s3_bucket" "build_artifacts" {
bucket = "${var.deployment_account}-build-artifacts"
acl
= "private"
force_destroy
= true
lifecycle
{
prevent_destroy = false
}
versioning {
enabled = true
}
}

Once the bucket is updated, terraform is not preventing you to destroy the bucket, and even if the bucket is not empty, terraform has force destroy enabled to help you get rid of the bucket.

Educator, Founder @ Interleap

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store