Terraform HOWTO - Delete A Non-Empty AWS S3 Bucket
Terraform HOWTO - Delete A Non-Empty AWS S3 Bucket
Salewski (writings)
When managing your infrastructure using Terraform, one common way to get rid
of an
infrastructure resource (cause it to be destroyed) is to simply remove
it from your Terraform
configuration (either by commenting-out it’s
configuration block or by deleting it from the
configuration file entirely).
Non-empty S3 buckets throw a monkeywrench into that process. The data stored
as S3 objects
within the bucket can be considered as separate (possibly
precious!) artitfacts, so a little extra
convincing is needed to let Terraform
know that you really do want it to delete an S3 bucket
resource and any data
objects it contains.
If you simply get rid of the configuration block for the bucket, the
terraform plan command
will succeed in telling you that it would remove the
bucket (as you might expect):
$ terraform plan
The refreshed state will be used to calculate this plan, but will not be
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
Note: You didn't specify an "-out" parameter to save this plan, so when
salewski.email/2017/04/30/terraform-howto-delete-a-non-empty-aws-s3-bucket.html 1/5
9/14/21, 2:42 PM Terraform HOWTO: delete a non-empty AWS S3 bucket | Alan D. Salewski (writings)
- aws_s3_bucket.your_tf_s3_bucket_resource_name
However, if you were then run terraform apply you might be surprised by the
error:
$ terraform apply
1 error(s) occurred:
Instead, your Terraform state file has been partially updated with
Despite the “delete all versions in the bucket” language of the error message,
the above error
will appear regardless of whether or not the bucket has
versioning enabled.
The Solution
Terraform will happily delete all of the objects in the bucket for you, but
you have to explicitly
tell it to do so, and you have to know how to ask.
Let’s say you have the following as your S3 bucket configuration block in your
Terraform
configuration file:
bucket = "my-bucket-name"
salewski.email/2017/04/30/terraform-howto-delete-a-non-empty-aws-s3-bucket.html 2/5
9/14/21, 2:42 PM Terraform HOWTO: delete a non-empty AWS S3 bucket | Alan D. Salewski (writings)
acl = "private"
versioning {
enabled = true
tags {
Name = "whatev-name"
Environment = "whatev-env"
lifecycle {
prevent_destroy = true
bucket = "my-bucket-name"
force_destroy = true
acl = "private"
versioning {
enabled = true
tags {
Name = "whatev-name"
Environment = "whatev-env"
salewski.email/2017/04/30/terraform-howto-delete-a-non-empty-aws-s3-bucket.html 3/5
9/14/21, 2:42 PM Terraform HOWTO: delete a non-empty AWS S3 bucket | Alan D. Salewski (writings)
# lifecycle {
# #
# prevent_destroy = true
# }
Now you can see the plan for destroying that bucket (and its dependencies)
with the command:
And then to actually have the bucket, its content, and its dependencies
destroyed:
[Terraform will prompt you to confirm, warning that there is no 'undo' for th
aws_s3_bucket.my_s3_bucket_resource
You may be wondering what would happen if we did not comment-out the
'lifecycle'
setting prevent_destroy = true while having
force_destroy = true set at the same time.
The answer is that Terraform
would do what you would want it to do: it would refuse to delete
the S3
bucket:
The refreshed state will be used to calculate this plan, but will not be
* aws_s3_bucket.my_s3_bucket_resource: aws_s3_bucket.my_s3_bucket_resource: t
Additional Reading
The rationale for Terraform not blindly deleting S3 objects was discussed in
hashicorp/terraform#1977; the discussion there includes
the need for some sort of “force”
option.
Alan D. Salewski (writings) salewski Al's misc. thoughts, notes, and other writings
[email protected]
salewski.email/2017/04/30/terraform-howto-delete-a-non-empty-aws-s3-bucket.html 5/5