如何通过Lambda基于S3预签名URL实现跨S3桶文件上传并配置过期特性
问题诊断与修复方案
核心错误点
- 逻辑错误:生成
put_object预签名URL时的Key参数是目标存储桶内的文件存储路径,不能传入源文件的完整HTTP URL,否则会导致目标桶Key非法。且预签名URL仅用于上传授权,不会自动拉取源桶文件,你当前的逻辑缺少「源文件下载→向预签名URL上传」的核心步骤。 - 代码语法/变量错误:
- 缩进不符合Python规范:
time.sleep(10)、源桶变量定义等行缩进错误 - 变量名不匹配:调用
list_objects_v2时使用的桶变量是未定义的bucket_name2,返回值存入response变量后却用未定义的response2取内容 - 客户端/参数名不匹配:初始化的S3客户端是
s3,生成预签名URL时却调用了未定义的s3_client;目标桶变量定义为destination_bucket_to_send,传参时却用了未定义的destination_bucket
- 缩进不符合Python规范:
正确实现方案
要实现跨S3桶复制+目标桶文件自动过期,优先推荐方案1,性能更稳定、代码复杂度更低:
方案1:直接使用S3 copy_object接口实现跨桶复制(无需预签名URL)
目标桶的过期特性直接在S3控制台配置生命周期规则即可,不需要在代码中处理,文件复制完成后会自动按规则过期。
修复后代码:
import json import boto3 s3 = boto3.client('s3') def lambda_handler(event, context): # 源桶配置 source_bucket = 'mybucketname' # 目标桶配置 destination_bucket = 'my_destination_bucket' # 获取源桶内最新修改的文件 response = s3.list_objects_v2(Bucket=source_bucket) all_files = response['Contents'] latest_file = max(all_files, key=lambda x: x['LastModified']) source_file_key = latest_file['Key'] # 直接调用S3原生接口完成跨桶复制 s3.copy_object( Bucket=destination_bucket, Key=source_file_key, # 目标桶内的文件路径,可按需自定义 CopySource={ 'Bucket': source_bucket, 'Key': source_file_key } ) return { 'statusCode': 200, 'body': json.dumps('文件复制成功') }
注意:需要给Lambda执行角色配置源桶的s3:GetObject权限、目标桶的s3:PutObject权限。
方案2:必须使用预签名URL的修复方案
import json import requests import boto3 s3 = boto3.client('s3') def lambda_handler(event, context): source_bucket = 'mybucketname' destination_bucket = 'my_destination_bucket' # 获取源桶最新修改的文件 response = s3.list_objects_v2(Bucket=source_bucket) all_files = response['Contents'] latest_file = max(all_files, key=lambda x: x['LastModified']) source_file_key = latest_file['Key'] # 1. 读取源文件内容 file_content = s3.get_object(Bucket=source_bucket, Key=source_file_key)['Body'].read() # 2. 生成目标桶上传预签名URL,Key传目标文件路径 presigned_url = s3.generate_presigned_url( 'put_object', Params={ 'Bucket': destination_bucket, 'Key': source_file_key }, ExpiresIn=20000 ) # 3. 向预签名URL上传文件 upload_response = requests.put(presigned_url, data=file_content) upload_response.raise_for_status() return { 'statusCode': 200, 'body': json.dumps('文件上传成功') }
注意:需要提前给Lambda层添加requests依赖,同时配置对应S3权限。
目标桶过期配置说明
直接在目标S3桶的「管理」→「生命周期规则」中创建规则,指定对应前缀的文件过期天数即可,规则会自动生效,无需在代码中额外处理。
内容的提问来源于stack exchange,提问作者Bemz
相关产品推荐
相关产品推荐

