Understanding S3 Bucket Deletion in CDK

If you’ve been following this blog, you may have noticed that I consistently include two specific parameters when creating S3 buckets:

const someBucket = new s3.Bucket(this, "someBucket", {
  // ... more bucket properties, sometimes none
  removalPolicy: cdk.RemovalPolicy.DESTROY,
  autoDeleteObjects: true,
});

These parameters work together to ensure the bucket is completely removed when the CloudFormation stack is deleted. Let’s take a look at how each one works and why both are needed.

Removal Policies

The removalPolicy parameter determines what happens to a resource when it’s no longer managed by CloudFormation. It accepts four possible values:

  • DESTROY: The resource will be destroyed when removed from the stack, or when the stack is deleted.
  • RETAIN: The resource is kept, and it becomes orphaned from the stack.
  • SNAPSHOT: The resource will be removed, but a snapshot will be saved before deletion.
  • RETAIN_ON_UPDATE_OR_DELETE: A somewhat complicated flow, but the gist of it is that new resources will be deleted, but we will keep the ones that are currently in use.

The default for buckets (and some other resources that can store data) is RETAIN. It’s this way so that we do not accidentally lose critical data if we delete a stack without giving it much thought.

S3 Deletion Requirements

AWS S3 includes a built-in safety mechanism: you cannot delete a bucket unless it’s completely empty. This prevents accidental deletion of buckets containing important data.

Because of this restriction, setting removalPolicy: DESTROY alone isn’t enough. The bucket must be emptied before CloudFormation can successfully delete it, which is where autoDeleteObjects: true comes into play.

When you enable autoDeleteObjects, CDK creates a custom resource behind the scenes (a Lambda function) that handles object deletion. The lambda is called as part of the stack removal process, and makes sure that the bucket is empty by the time CloudFormation attempts to remove the bucket.

If you’ve deployed stacks with this configuration, you might have noticed an unexpected Lambda function in your AWS Lambda console that looks something like this:

Auto Deletion Lambda

This is that auto-generated function, the one responsible for emptying your S3 bucket during the cleanup process.

The takeaway

This may seem like a minor infrastructure detail, but understanding these mechanisms will give you a better idea of how you manage your resources, and enable you to make better design decisions.

Just remember to be careful with these options and use them mainly for development or staging infrastructure. Using the options in your production environments is quite risky, so I recommend you leave the default values in place. It’s better to have an orphaned bucket than realizing you accidentally lost gigabytes or terabytes of critical data for one of your clients!

I hope you find this useful!

Juan Luis Orozco Villalobos

Hey there, I'm Juan. A software engineer and consultant currently living in Budapest.