Python AWS:如何在blob.upload中传递s3_resource?跨账号上传指引
问题解答
一、正确传递s3_resource到上传方法
你的代码中blob变量未定义,导致无法复用传入的s3_resource。正确做法是通过s3_resource生成对应的S3操作对象(Object或Bucket),再调用上传方法。以下是修正后的完整代码:
import os import boto3 def connection_to_another_acc(): sts_client = boto3.client('sts') assumed_role_object = sts_client.assume_role( RoleArn="arn:aws:iam::account-of-role-to-assume:role/name-of-role", RoleSessionName="AssumeRoleSession1" ) credentials = assumed_role_object['Credentials'] s3_resource = boto3.resource( 's3', aws_access_key_id=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_session_token=credentials['SessionToken'], ) file_path = "xyz" # 替换为实际本地文件路径 s3_path = "abx" # 替换为S3中的目标对象路径 bucket = "name" # 替换为目标账号的S3桶名 upload_to_s3(s3_resource, file_path, s3_path, bucket) def upload_to_s3(s3_resource, file_path, s3_path, bucket): # 方式1:通过s3_resource创建S3 Object并执行上传 s3_object = s3_resource.Object(bucket, s3_path) response = s3_object.upload_file(file_path) # 方式2:通过Bucket对象直接上传(二选一即可) # s3_bucket = s3_resource.Bucket(bucket) # response = s3_bucket.upload_file(file_path, s3_path) if os.path.isfile(file_path): os.remove(file_path) print("Removed the file from tmp directory") else: print("File not found") return response connection_to_another_acc()
修正说明:
- 移除未定义的
blob变量,改用传入的s3_resource生成合法的S3操作对象 - 提供两种基于Resource接口的上传方式,按需选择
- 确保导入
os模块以支持本地文件操作
二、其他跨AWS账号上传文件的方法
1. 使用Boto3 Client接口替代Resource
角色假设逻辑一致,但使用Boto3的客户端接口完成上传,适合更轻量化的操作:
def connection_with_client(): sts_client = boto3.client('sts') assumed_role = sts_client.assume_role( RoleArn="arn:aws:iam::account-of-role-to-assume:role/name-of-role", RoleSessionName="AssumeRoleSession2" ) creds = assumed_role['Credentials'] s3_client = boto3.client( 's3', aws_access_key_id=creds['AccessKeyId'], aws_secret_access_key=creds['SecretAccessKey'], aws_session_token=creds['SessionToken'], ) s3_client.upload_file("xyz", "name", "abx")
2. 目标桶配置跨账号Bucket Policy
无需角色假设,直接用源账号IAM凭证上传:
- 在目标账号的S3桶中添加Bucket Policy,允许源账号的IAM用户/角色执行
s3:PutObject操作 - 源账号直接使用自身凭证调用S3上传接口,目标路径指定为
目标桶名/对象路径
示例Bucket Policy(目标账号桶配置):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::源账号ID:user/源账号用户名" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::目标桶名/*" } ] }
3. 使用Presigned URL上传
源账号通过目标账号生成的预签名URL上传,无需持有目标账号的长期权限:
def upload_via_presigned_url(): # 目标账号生成预签名URL(需具备目标桶的s3:PutObject权限) s3_client = boto3.client('s3') presigned_url = s3_client.generate_presigned_url( 'put_object', Params={'Bucket': '目标桶名', 'Key': '对象路径'}, ExpiresIn=3600 # URL有效期1小时 ) # 源账号使用该URL上传文件(需安装requests库) import requests with open('本地文件路径', 'rb') as f: requests.put(presigned_url, data=f)
4. AWS CLI跨账号上传
通过命令行直接完成角色假设与上传:
# 方式1:先获取临时凭证并配置环境变量 aws sts assume-role --role-arn "arn:aws:iam::目标账号ID:role/角色名" --role-session-name "Session3" > creds.json export AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' creds.json) export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' creds.json) export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' creds.json) aws s3 cp 本地文件路径 s3://目标桶名/对象路径 # 方式2:直接在上传命令中指定角色 aws s3 cp 本地文件路径 s3://目标桶名/对象路径 --role-arn "arn:aws:iam::目标账号ID:role/角色名" --role-session-name "Session4"
内容的提问来源于stack exchange,提问作者Mia
相关产品推荐
相关产品推荐

