You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:35:27