amazon-web-servicesamazon-s3aws-cloudformationaws-codepipeline

AWS: How to delete S3 buckets when deleting CodePipeline


I use the CloudFormation template to create CodePipeline. The following snippet shows that it creates S3 bucket to store code artifacts:

CodePipelineArtifactsBucket:
  Type: AWS::S3::Bucket
  Properties:
    BucketEncryption:
      ServerSideEncryptionConfiguration:
        - ServerSideEncryptionByDefault:
            SSEAlgorithm: aws:kms
    PublicAccessBlockConfiguration:
      BlockPublicAcls: true
      BlockPublicPolicy: true
      IgnorePublicAcls: true
      RestrictPublicBuckets: true
  UpdateReplacePolicy: Delete
  DeletionPolicy: Delete

When I delete a CloudFormation stack created with this template, it fails to delete an associated S3 bucket because it contains code artifacts. Is there a way to force-delete a S3 bucket even if it is not empty?

There is a similar question, but I'd like to delete it using the CloudFormation template only, without creating Lambda function.


Solution

  • there is no direct way in CloudFormation to forcefully delete a non-empty S3 bucket without a Lambda function. The limitation is because CloudFormation lacks a built-in mechanism to empty a bucket before deletion.

    but you can use S3 lifecycle rules to automatically expire and delete objects in the bucket after a short period. This ensures the bucket gets emptied before stack deletion. However, the deletion process may still require manual intervention if objects haven’t expired by the time you delete the stack.

    LifecycleConfiguration:
            Rules:
              - Id: AutoDeleteObjects
                Status: Enabled
                ExpirationInDays: 1 
    

    using the help of a Lambda is the only way that can guarantee for you the deletion as it will delete the objects for you before the stack tries to delete the bucket using the cloudformation custom resource:

    BucketDeletionCustomResource:
        Type: Custom::S3BucketCleaner
        Properties:
          ServiceToken: !GetAtt CleanupLambda.Arn