Is there any way to force CloudFormation to delete a non-empty S3 Bucket?
Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/. In the Buckets list, select the option next to the name of the bucket that you want to delete, and then choose Delete at the top of the page.
The CloudFormation service won't delete an S3 bucket that contains objects. This means that if your stack wrote to a bucket and you didn't manually delete the object before deleting the stack then it will fail.
You can create a lambda function to clean up your bucket and invoke your lambda from your CloudFormation stack using a CustomResource.
Below a lambda example cleaning up your bucket:
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import boto3 from botocore.vendored import requests def lambda_handler(event, context): try: bucket = event['ResourceProperties']['BucketName'] if event['RequestType'] == 'Delete': s3 = boto3.resource('s3') bucket = s3.Bucket(bucket) for obj in bucket.objects.filter(): s3.Object(bucket.name, obj.key).delete() sendResponseCfn(event, context, "SUCCESS") except Exception as e: print(e) sendResponseCfn(event, context, "FAILED") def sendResponseCfn(event, context, responseStatus): response_body = {'Status': responseStatus, 'Reason': 'Log stream name: ' + context.log_stream_name, 'PhysicalResourceId': context.log_stream_name, 'StackId': event['StackId'], 'RequestId': event['RequestId'], 'LogicalResourceId': event['LogicalResourceId'], 'Data': json.loads("{}")} requests.put(event['ResponseURL'], data=json.dumps(response_body))
After you create the lambda above, just put the CustomResource in your CloudFormation stack:
--- AWSTemplateFormatVersion: '2010-09-09' Resources: myBucketResource: Type: AWS::S3::Bucket Properties: BucketName: my-test-bucket-cleaning-on-delete cleanupBucketOnDelete: Type: Custom::cleanupbucket Properties: ServiceToken: arn:aws:lambda:eu-west-1:123456789012:function:clean-bucket-lambda BucketName: !Ref myBucketResource
Remember to attach a role to your lambda that has permission to remove objects from your bucket.
Furthermore keep in mind that you can create a lambda function that accepts CLI command line using the lambda function cli2cloudformation. You can download and install from here. Using that you just need to create a CustomResource like bellow:
"removeBucket": { "Type": "Custom::cli2cloudformation", "Properties": { "ServiceToken": "arn:aws:lambda:eu-west-1:123456789000:function:custom-lambda-name", "CliCommandDelete": "aws s3 rb s3://bucket-name --force", } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With