能否通过CloudFormation模板导出闲置空S3存储桶列表到Excel
方案可行性确认
完全可以通过CloudFormation实现该需求,整体逻辑为CloudFormation模板统一部署所需的IAM权限、Lambda函数、可选的定时触发规则,由Lambda完成空/未使用S3桶的扫描、Excel生成、结果存储操作。
核心实现逻辑
- 首先为Lambda创建专属执行角色,授予
s3:ListAllMyBuckets、s3:ListBucket、s3:GetBucketLocation等扫描权限,以及输出存储桶的s3:PutObject权限、Lambda日志上报的基础权限。 - Lambda函数内集成Excel生成依赖(推荐使用
openpyxl库,可打包为Lambda层关联使用),核心执行流程如下:- 调用S3 API拉取当前账号全量存储桶列表
- 遍历每个桶,调用
ListObjectsV2接口判断桶内是否为空,可按需扩展未使用判断规则,比如对接CloudWatch指标校验最近N天无访问操作、对接CloudTrail校验无操作日志等 - 收集符合条件的桶的名称、所属区域、创建时间等信息写入Excel表格
- 将生成的Excel文件上传到提前指定的目标存储桶中
- 可选配置EventBridge定时规则,按天/周定期触发扫描,自动生成最新清单。
CloudFormation模板核心片段示例
Resources: # Lambda执行角色 S3EmptyBucketScannerRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: S3ScannerPermission PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:ListAllMyBuckets - s3:ListBucket - s3:GetBucketLocation Resource: "*" - Effect: Allow Action: - s3:PutObject Resource: "arn:aws:s3:::替换为你的输出存储桶名称/*" - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: "arn:aws:logs:*:*:*" # 扫描Lambda函数 EmptyBucketScannerLambda: Type: AWS::Lambda::Function Properties: Runtime: python3.9 Role: !GetAtt S3EmptyBucketScannerRole.Arn Handler: index.lambda_handler # 注意:openpyxl不是Python运行时内置依赖,此处代码仅为示例,实际使用需将openpyxl和代码一起打包为zip上传 Code: ZipFile: | import boto3 from openpyxl import Workbook from io import BytesIO s3_client = boto3.client('s3') # 替换为你的输出存储桶名称 TARGET_OUTPUT_BUCKET = "替换为你的输出存储桶名称" def lambda_handler(event, context): all_buckets = s3_client.list_buckets()["Buckets"] empty_bucket_list = [] for bucket in all_buckets: bucket_name = bucket["Name"] try: # 仅拉取1个对象即可判断桶是否为空 list_resp = s3_client.list_objects_v2(Bucket=bucket_name, MaxKeys=1) if "Contents" not in list_resp: region = s3_client.get_bucket_location(Bucket=bucket_name)["LocationConstraint"] create_time = bucket["CreationDate"].strftime("%Y-%m-%d %H:%M:%S") empty_bucket_list.append([bucket_name, region, create_time]) except Exception as err: print(f"访问桶{bucket_name}失败,跳过:{str(err)}") # 生成Excel文件 wb = Workbook() work_sheet = wb.active work_sheet.append(["存储桶名称", "所属区域", "创建时间"]) for bucket_info in empty_bucket_list: work_sheet.append(bucket_info) # 上传Excel到目标存储桶 output_stream = BytesIO() wb.save(output_stream) output_stream.seek(0) s3_client.put_object( Bucket=TARGET_OUTPUT_BUCKET, Key=f"空S3存储桶清单_{context.aws_request_id}.xlsx", Body=output_stream.getvalue() ) return { "statusCode": 200, "body": f"扫描完成,共找到{len(empty_bucket_list)}个空存储桶,清单已上传至目标桶" }
使用前请将模板内的替换为你的输出存储桶名称替换为你实际用来存放导出Excel的S3桶名称,内置openpyxl依赖的Lambda部署包可以在本地安装依赖后打包上传,也可以直接使用公共的openpyxl Lambda层。
内容的提问来源于stack exchange,提问作者shubham singh
相关产品推荐
相关产品推荐

