Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I force CloudFormation to delete non-empty S3 Bucket?

Is there any way to force CloudFormation to delete a non-empty S3 Bucket?

like image 810
Jamie Czuy Avatar asked Nov 02 '16 15:11

Jamie Czuy


People also ask

How do I force 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.

Will CloudFormation delete S3 bucket?

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.


1 Answers

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",         } } 
like image 109
Lucio Veloso Guimarães Avatar answered Oct 08 '22 02:10

Lucio Veloso Guimarães