Python Lambda实现S3跨桶JSON文件修改传输及只读报错解决
错误原因
AWS Lambda 运行时仅 /tmp 目录开放写入权限,其余目录均为只读。原代码直接在函数工作根目录写入awsEC2Pricebook.json、尝试写入部署包内./assets/路径下的文件,必然触发只读文件系统报错。除此之外原代码还有3个逻辑问题:
- 缺失
uuid模块导入,运行时会抛模块不存在错误 - 参考UUID文件存放在Lambda部署包内,本身是只读的,就算绕开权限写入,实例回收后修改也会丢失,下次冷启动还是会加载初始版本
- 处理完成后没有调用S3上传接口,无法实现文件跨桶传输的需求
修复后完整代码
以下代码完全跳过不必要的本地文件写入,直接在内存中完成JSON处理后上传到目标S3桶,从根源避免文件系统权限问题,同时修复了原有逻辑缺陷:
import json import boto3 import uuid s3_client = boto3.client('s3') # 替换为你的实际配置 TARGET_BUCKET = "替换为你的目标S3存储桶名称" REFERENCE_UUID_S3_KEY = "assets/referenceUUIDAwsEC2Prices.json" def lambda_handler(event, context): # 从触发事件获取源桶和待处理文件信息 source_bucket = event['Records'][0]['s3']['bucket']['name'] source_file_key = event['Records'][0]['s3']['object']['key'] # 读取源S3存储桶中的价格JSON文件 price_file_resp = s3_client.get_object(Bucket=source_bucket, Key=source_file_key) price_content = price_file_resp['Body'].read().decode("utf-8") ec2_price_data = json.loads(price_content) # 从目标S3桶拉取最新的参考UUID映射文件,避免使用部署包内的只读旧版本 ref_file_resp = s3_client.get_object(Bucket=TARGET_BUCKET, Key=REFERENCE_UUID_S3_KEY) ref_content = ref_file_resp['Body'].read().decode("utf-8") uuid_ref_data = json.loads(ref_content) # 原有ID匹配、生成逻辑 for item in ec2_price_data: grouping_code = f"{item['region']}_{item['operatingSystem']}_{item['name']}" match_id = None for ref_item in uuid_ref_data: if grouping_code == ref_item['groupingCode']: match_id = ref_item['uniqueID'] break if match_id: item['id'] = match_id else: new_id = str(uuid.uuid4()) item['id'] = new_id uuid_ref_data.append({ "groupingCode": grouping_code, "uniqueID": new_id }) # 上传处理完成的价格文件到目标S3桶 s3_client.put_object( Bucket=TARGET_BUCKET, Key="awsEC2Pricebook.json", Body=json.dumps(ec2_price_data).encode("utf-8"), ContentType="application/json" ) # 上传更新后的UUID映射文件回S3做持久化 s3_client.put_object( Bucket=TARGET_BUCKET, Key=REFERENCE_UUID_S3_KEY, Body=json.dumps(uuid_ref_data).encode("utf-8"), ContentType="application/json" ) return {"statusCode": 200, "body": "Processing completed"}
配置注意事项
- 提前给Lambda绑定的IAM执行角色添加对应S3权限:对源存储桶允许
s3:GetObject操作,对目标存储桶允许s3:GetObject、s3:PutObject操作 - 首次运行前,在目标存储桶的对应路径上传初始版本的
referenceUUIDAwsEC2Prices.json文件,文件内容为[]即可,后续运行会自动追加新的UUID映射 - 如果业务必须生成本地临时文件,所有文件路径必须添加
/tmp/前缀,例如/tmp/awsEC2Pricebook.json,除此路径外任何位置的写入操作都会触发只读报错
内容的提问来源于stack exchange,提问作者appm
相关产品推荐
相关产品推荐

