Learn how to safely and efficiently delete non-empty AWS S3 buckets using Terraform with this step-by-step guide.
This guide provides solutions to the common issue of Terraform being unable to delete a non-empty S3 bucket. We'll explore various methods, from manual deletion using the AWS CLI to leveraging Terraform's lifecycle rules and the force_destroy option. We'll also discuss handling versioned buckets, best practices to ensure data safety, and troubleshooting tips for common problems.
Understand the Problem: Terraform can't delete an S3 bucket if it's not empty. This includes actual files and "delete markers" (if versioning is enabled).
Manual Deletion (Easiest):
terraform destroy. Use the AWS CLI command: aws s3 rm s3://your-bucket-name --recursive. Replace your-bucket-name with the actual bucket name.Terraform Lifecycle Rules (For Objects):
lifecycle_rule to your aws_s3_bucket resource: This allows you to define rules for automatically expiring or deleting objects in your bucket.  You can set rules to expire objects after a certain time or on a specific date.force_destroy Option (Use with Caution):
force_destroy = true to your aws_s3_bucket resource: This tells Terraform to delete the bucket even if it's not empty. Warning: This will permanently delete all data in the bucket.Handling Versioned Buckets:
force_destroy might not work reliably with versioned buckets: There have been reported issues with force_destroy not consistently deleting versioned buckets.Best Practices:
force_destroy with extreme caution and only if you understand the implications.Troubleshooting:
This document provides examples of how to delete AWS S3 buckets using Terraform, including methods for handling non-empty buckets. It covers manual deletion using the AWS CLI, automated deletion using Terraform lifecycle rules, and forced deletion using the force_destroy option (use with caution). It also explains how to empty versioned buckets using the AWS CLI. The document emphasizes best practices such as backing up data, using lifecycle rules, and using force_destroy cautiously. It concludes with troubleshooting tips, including checking for hidden objects, reviewing Terraform logs, and checking for dependencies.
This example demonstrates different approaches to deleting S3 buckets with Terraform, addressing the common issue of non-empty buckets.
1. Manual Deletion (AWS CLI):
This is the simplest approach, but it requires manual intervention outside of Terraform.
aws s3 rm s3://your-bucket-name --recursive2. Terraform Lifecycle Rules:
This approach uses Terraform to define rules for automatically expiring or deleting objects in your bucket.
resource "aws_s3_bucket" "example" {
  bucket = "my-bucket"
  lifecycle_rule {
    enabled = true
    prefix = "logs/"
    expiration {
      days = 30
    }
  }
}3. force_destroy Option (Use with Caution):
This approach forces Terraform to delete the bucket even if it's not empty. Use with extreme caution!
resource "aws_s3_bucket" "example" {
  bucket = "my-bucket"
  force_destroy = true  # Use with extreme caution!
}4. Handling Versioned Buckets (AWS CLI):
Emptying versioned buckets requires deleting all versions of all objects, including delete markers.
aws s3api delete-objects --bucket your-bucket-name --delete '{"Objects": [{"Key": "object-key"}, {"Key": "another-object-key", "VersionId": "object-version-id"}]}'5. Best Practices:
force_destroy cautiously: Use force_destroy with extreme caution and only if you understand the implications.6. Troubleshooting:
Remember to replace placeholders like your-bucket-name, object-key, and object-version-id with your actual values.
force_destroy: While force_destroy is an option, consider these alternatives for a cleaner approach:
for_each: Use a aws_s3_bucket_objects data source to fetch objects and delete them with a aws_s3_object resource within a for_each loop. This provides more control and visibility.s3:DeleteBucket, s3:DeleteObject) to delete buckets and objects.Remember to adapt these notes and examples to your specific needs and environment. Always prioritize data safety and thoroughly understand the implications of your actions before deleting S3 buckets.
This document outlines methods for deleting AWS S3 buckets using Terraform, addressing the challenge of non-empty buckets.
Key Points:
aws s3 rm s3://your-bucket-name --recursive before running terraform destroy.aws_s3_bucket resource using lifecycle_rule to prevent future accumulation.force_destroy Option (Use Cautiously):  Adding force_destroy = true to your aws_s3_bucket resource forces deletion even if the bucket is not empty. Warning: This permanently deletes all data.force_destroy may not work reliably.force_destroy, understanding its implications.Deleting S3 buckets with Terraform requires careful consideration due to the "bucket not empty" constraint. While manual deletion using the AWS CLI is the simplest approach, Terraform offers lifecycle rules for automated object expiration. The force_destroy option exists but should be used with extreme caution as it bypasses safety checks and permanently deletes all data. Versioned buckets present additional complexity, necessitating the deletion of all object versions and delete markers. Always prioritize data safety by backing up important information and understanding the implications of each deletion method. When encountering issues, investigate potential hidden objects, review Terraform logs, and ensure no resource dependencies exist. Remember to adapt these practices to your specific environment and prioritize a thorough understanding of your actions before deleting S3 buckets.
 Terraform: Handling the deletion of a non-empty AWS S3 Bucket ... | This article applies to Terraform v1.1.4  When using Terraform to manage your infrastructure you will...
 Terraform HOWTO: delete a non-empty AWS S3 bucket | Alan D ... | The Amazon AWS S3 service provides a number of different ways to delete a non-empty S3 bucket; some of the approaches involve “emptying” the bucket prior to deleting it. The process can also vary a bit depending on whether or not the bucket has versioning enabled.
 How to prevent an s3 bucket from being destroy on apply - AWS ... | Given a bucket like so:  resource aws_s3_bucket nfcisbenchmark_config {   bucket        = "${var.name}-config"   acl           = "private"    #  ensure the CloudTrail S3 bucket has access logging is enabled.   logging {     target_bucket = aws_s3_bucket.log_bucket_config.id     target_prefix = "log/"   }    server_side_encryption_configuration {     rule {       apply_server_side_encryption_by_default {         kms_master_key_id = aws_kms_key.nfcisbenchmark.arn         sse_algorithm     = "aws:k...
 How to fix : « … operation error S3: DeleteBucket, https response ... | You might come across this error if you make a bucket with Terraform, add files, and then try to delete it using “terraform destroy”.