我可以强制CloudFormation删除非空的S3 Bucket吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我可以强制CloudFormation删除非空的S3 Bucket吗?相关的知识,希望对你有一定的参考价值。

有没有办法强制CloudFormation删除非空的S3 Bucket?

答案

您可以创建一个lambda函数来清理您的存储桶,并使用CustomResource从您的CloudFormation堆栈调用您的lambda。

在lambda示例下面清理你的桶:

#!/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))

在上面创建lambda之后,只需将CustomResource放在CloudFormation堆栈中:

 ---
 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

请记住将角色附加到您的lambda,该角色有权从您的存储桶中删除对象。

此外,请记住,您可以使用lambda函数cli2cloudformation创建一个接受CLI命令行的lambda函数。您可以从here下载并安装。使用它你只需要像下面这样创建一个CustomResource:

"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",
        

另一答案

我认为你的DependsOn是错误的资源,至少它对我不起作用,因为在堆栈删除(通过控制台),它会尝试先强制删除桶,这将失败,然后将尝试删除自定义资源,这会触发lambda清空水桶。这将清空存储桶,但堆栈删除将失败,因为它尝试在存储桶为空之前删除存储桶。我们想首先启动自定义资源删除,然后在删除自定义资源后尝试删除存储桶,所以我这样做了,它对我有用:

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: my-test-bucket-cleaning-on-delete
  DependsOn: myBucketResource

通过这种方式,您可以确保不会首先删除存储区,因为存在依赖于它的另一个资源,因此首先删除依赖资源(触发lambda以清空存储区),然后删除存储区。希望有人发现它有用。

另一答案

你应该清空水桶:

$ aws s3 rm s3://bucket-name --recursive

然后删除Bucket

$ aws cloudformation delete-stack --stack-name mys3stack
另一答案

这个怎么样:

import boto3

s3 = boto3.client('s3')
res = boto3.resource('s3')

buckets = s3.list_buckets()

try:
    for bk in buckets['Buckets']:
            bucket = res.Bucket(bk['Name'])
            bucket.objects.all().delete()
            bucket.delete()

except Exception as e:
    print e

以上是关于我可以强制CloudFormation删除非空的S3 Bucket吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何用rmdir删除文件夹?

强制删除文件夹

如何使用 Cloudformation 强制重新部署我的 API 网关

CloudFormation yaml - 如何强制数字类型?

windows 定时删除N天前日志脚本

如何在更新参数时强制 CloudFormation 堆栈更新?