👏

CloudFormationのスタックをS3があっても無理やり消すPythonスクリプト

2023/03/25に公開

動機など

  • S3を使ったCodePipelineのテストをしていて、何度も作り直すときにバケットの中身を消すのが面倒だった
  • バージョニングがあっても消せます

使い方

python /path/to/delete_cfn_stack_with_s3.py

スクリプト

delete_cfn_stack_with_s3.py
import boto3

"""
This script is for deleting an AWS CloudFormation stack with S3 buckets.
Usage: python /full/path/to/script.py
"""


def empty_bucket(bucket_name):
    s3 = boto3.resource("s3")
    bucket = s3.Bucket(bucket_name)

    # Check if bucket versioning is enabled
    bucket_versioning = s3.BucketVersioning(bucket_name)
    versioning_status = bucket_versioning.status

    if versioning_status == "Enabled":
        # Delete all object versions
        bucket.object_versions.delete()
        print(f"All objects and versions in bucket {bucket_name} have been deleted.")
    else:
        # Delete all objects
        bucket.objects.delete()
        print(f"All objects in bucket {bucket_name} have been deleted.")


def delete_stack(stack_name):
    cf = boto3.client("cloudformation")

    cf.delete_stack(StackName=stack_name)
    print(f"Stack deletion initiated for {stack_name}")


def get_s3_bucket_names(stack_name):
    cf = boto3.client("cloudformation")
    stack_resources = cf.describe_stack_resources(StackName=stack_name)

    bucket_names = []

    for resource in stack_resources["StackResources"]:
        if resource["ResourceType"] == "AWS::S3::Bucket":
            bucket_names.append(resource["PhysicalResourceId"])

    return bucket_names


if __name__ == "__main__":
    stack_name = input("Enter the AWS CloudFormation stack name: ")
    bucket_names = get_s3_bucket_names(stack_name)

    if bucket_names:
        for bucket_name in bucket_names:
            try:
                empty_bucket(bucket_name)
            except Exception as e:
                print(e)
    else:
        print(f"No S3 buckets found in stack {stack_name}")

    delete_stack(stack_name)

注意

  • ドリフトしてたりすると消せないときがあります。そういうときは手動でお願いします。

Discussion