如何配置S3存储桶生命周期规则实现每7天删除文件夹?
解决S3文件夹7天自动删除的问题
先排查生命周期规则失效的原因
S3不存在真正的物理文件夹,所谓“文件夹”只是对象键的前缀(如backup/)。如果生命周期规则没生效,先检查以下核心点:
- 前缀配置错误:要删除
archive/下的所有对象,规则前缀必须设为archive/(带末尾斜杠),不能仅写archive - 版本化桶的规则逻辑:若桶开启版本化,
Expire current versions of objects会将当前对象转为非当前版本,此时Permanently delete non-current versions of objects的生效时间是非当前版本生成后的天数,而非对象原始创建时间 - 规则未启用:确认规则状态处于“Enabled”
如果以上配置均无问题但仍不生效,Lambda是更灵活的替代方案。
使用Lambda实现自定义过期删除
1. 创建Lambda函数
- 选择Python作为运行时,给Lambda配置S3操作权限:需要
s3:ListBucket(列出桶内对象)和s3:DeleteObject(删除对象)权限,权限策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:ListBucket", "s3:DeleteObject"], "Resource": [ "arn:aws:s3:::你的存储桶名称", "arn:aws:s3:::你的存储桶名称/目标前缀/*" ] } ] }
2. 编写删除逻辑代码
以下Python代码会删除指定前缀下创建时间超过7天的对象:
import boto3 from datetime import datetime, timedelta, timezone def lambda_handler(event, context): BUCKET_NAME = "你的存储桶名称" TARGET_PREFIX = "要删除的文件夹前缀/" # 例如 "temp_uploads/" EXPIRE_DAYS = 7 s3_client = boto3.client("s3") cutoff_time = datetime.now(timezone.utc) - timedelta(days=EXPIRE_DAYS) # 分页列出对象,避免单次请求数量限制 paginator = s3_client.get_paginator("list_objects_v2") for page in paginator.paginate(Bucket=BUCKET_NAME, Prefix=TARGET_PREFIX): if "Contents" not in page: continue # 筛选过期对象 expired_objects = [{"Key": obj["Key"]} for obj in page["Contents"] if obj["LastModified"] < cutoff_time] # 批量删除(单次最多支持1000个对象) if expired_objects: s3_client.delete_objects(Bucket=BUCKET_NAME, Delete={"Objects": expired_objects}) print(f"已删除 {len(expired_objects)} 个过期对象")
3. 配置定时触发
- 给Lambda添加EventBridge触发器,选择“Schedule”类型:
- 固定频率设为7天,或使用Cron表达式
0 0 */7 * ? *(每7天零点执行)
- 固定频率设为7天,或使用Cron表达式
- 也可以设置为每天触发一次,代码内仍按7天过期判断,这种方式更灵活
4. 版本化桶的额外处理
如果存储桶开启了版本化,需要补充以下操作:
- 在权限策略中添加
s3:ListObjectVersions和s3:DeleteObjectVersion权限 - 修改代码,处理非当前版本和删除标记,示例片段:
# 获取非当前版本与删除标记 versions_response = s3_client.list_object_versions(Bucket=BUCKET_NAME, Prefix=TARGET_PREFIX) # 删除过期的删除标记 if "DeleteMarkers" in versions_response: expired_deletes = [ {"Key": dm["Key"], "VersionId": dm["VersionId"]} for dm in versions_response["DeleteMarkers"] if dm["LastModified"] < cutoff_time ] if expired_deletes: s3_client.delete_objects(Bucket=BUCKET_NAME, Delete={"Objects": expired_deletes}) # 删除过期的非当前版本 if "Versions" in versions_response: expired_versions = [ {"Key": v["Key"], "VersionId": v["VersionId"]} for v in versions_response["Versions"] if v["LastModified"] < cutoff_time ] if expired_versions: s3_client.delete_objects(Bucket=BUCKET_NAME, Delete={"Objects": expired_versions})
注意事项
- Lambda默认执行时间限制为15分钟,若需删除的对象数量极多,需在函数配置中调整超时时间
- 遵循最小权限原则,仅授予Lambda目标前缀的操作权限,避免过度授权
- 测试时优先在测试存储桶验证逻辑,防止误删生产数据
内容的提问来源于stack exchange,提问作者Andrea Vitangeli
相关产品推荐
相关产品推荐

