簡體   English   中英

如何使用 boto3 在 2 個不同帳戶的 S3 存儲桶之間復制文件

[英]How to copy files between S3 buckets in 2 different accounts using boto3

我正在嘗試使用 boto3 將文件從供應商 S3 存儲桶傳輸到我的 S3 存儲桶。 我正在使用 sts 服務承擔訪問供應商 s3 存儲桶的角色。 我能夠連接到供應商存儲桶並獲取該存儲桶的列表。 復制到我的存儲桶時遇到CopyObject operation: Access Denied錯誤。 這是我的腳本

session = boto3.session.Session(profile_name="s3_transfer")
sts_client = session.client("sts", verify=False)
assumed_role_object = sts_client.assume_role(
    RoleArn="arn:aws:iam::<accountid>:role/assumedrole",
    RoleSessionName="transfer_session",
    ExternalId="<ID>",
    DurationSeconds=18000,
)

creds = assumed_role_object["Credentials"]
src_s3 = boto3.client(
    "s3",
    aws_access_key_id=creds["AccessKeyId"],
    aws_secret_access_key=creds["SecretAccessKey"],
    aws_session_token=creds["SessionToken"],
    verify=False,
)
paginator =src_s3.get_paginator("list_objects_v2")
# testing with just 2 items.
# TODO: Remove MaxItems once script works.
pages = paginator.paginate(
    Bucket="ven_bucket", Prefix="client", PaginationConfig={"MaxItems": 2, "PageSize": 1000}
)
dest_s3 = session.client("s3", verify=False)
for page in pages:
    for obj in page["Contents"]:
        src_key = obj["Key"]
        des_key = dest_prefix + src_key[len(src_prefix) :]
        src = {"Bucket": "ven_bucket", "Key": src_key}
        print(src)
        print(des_key)
        dest_s3.copy(src, "my-bucket", des_key, SourceClient=src_s3)

dest_s3.copy...行是我收到錯誤的地方。 我的 aws 用戶有以下政策允許復制到我的存儲桶

{
    "Version": "2012-10-17",
   "Statement": [
    {
        "Sid": "VisualEditor1",
        "Effect": "Allow",
        "Action": [
            "s3:*"
        ],
        "Resource": [
            "arn:aws:s3:::my-bucket/*",
            "arn:aws:s3:::my-bucket/"
        ]
    }
    ]
}

運行上述腳本時出現以下錯誤。

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the CopyObject operation: Access Denied

CopyObject()命令可用於在存儲桶之間復制對象,而無需上載/下載。 基本上,兩個S3存儲桶彼此通信並傳輸數據。

此命令還可用於在不同區域和不同AWS賬戶的存儲桶之間進行復制。

如果您希望在屬於不同AWS賬戶的存儲桶之間進行復制,那么您將需要使用一組具有以下身份的憑證

  • 源存儲桶上的GetObject權限
  • 目標存儲桶上的PutObject權限

另外,請注意, CopyObject()命令已發送到目標帳戶 目標存儲桶有效地從源存儲桶中拉出了對象

根據您的描述,您的代碼將承擔其他帳戶的角色,以獲取對源存儲桶的讀取權限。 不幸的是,這對於CopyObject()命令是不夠的,因為該命令必須發送到目標存儲桶。 (是的,很難從文檔中辨別出來。這就是為什么要專門命名源存儲桶,而不是目標存儲桶的原因。)

因此,在您的情況下,要能夠復制對象,您將需要使用來自Account-B (目標)的一組憑據,該憑據也具有從Bucket-A (源)中讀取的權限。 這將要求供應商修改Bucket-A關聯的Bucket策略

如果他們不希望這樣做,那么您唯一的選擇是使用假定的角色下載對象 ,然后使用來自您自己的Account-B憑據將文件分別上傳到您自己的存儲桶中。

我知道這很舊,但您的代碼運行良好,無需修改。 如果您有目標賬戶 (A) 和源賬戶 (B),那么您可以正確調用 A 中的 Lambda 以承擔 B 中的角色,並將文件從 B 中的 S3 復制到 A 中的 S3,就像您所做的一樣。 您問題的核心和實際解決方案是正確配置權限。 請參考這兩個實際解決問題的 AWS 文檔頁面:

https://aws.amazon.com/premiumsupport/knowledge-center/copy-s3-objects-account/ https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/

不過,我要添加的另一件事是 ACL。 這將確保從 B 復制到 A 的對象將由目標存儲桶的所有者擁有。

dest_s3.copy(
            CopySource=...,
            Bucket=...,
            Key=...,
            ExtraArgs={
                "ACL": "bucket-owner-full-control"
            }
        )
  1. 在源 AWS 賬戶上,將此策略添加到源 S3 存儲桶:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::SOURCE_BUCKET_NAME",
                "arn:aws:s3:::SOURCE_BUCKET_NAME/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::DESTINATION_BUCKET_NAME",
                "arn:aws:s3:::DESTINATION_BUCKET_NAME/*"
            ]
        }
    ]
}
  1. 使用目標帳戶的憑據:
boto3_session = boto3.Session(aws_access_key_id=<your access key>,
                              aws_secret_access_key=<your secret_access_key>)
s3_resource = boto3_session.resource('s3')
bucket = s3_resource.Bucket("<source bucket name>")

for obj in bucket.objects.all():
    obj_path = str(obj.key)

    copy_source = {
        'Bucket': "<source bucket name>",
        'Key': obj_path
    }
    s3_resource.meta.client.copy(copy_source, "<destination bucket name>", obj_path)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM