如何从另一个 AWS 账户中复制 S3 对象?

上次更新日期:2022 年 1 月 7 日

我想要在 AWS 账户间复制 Amazon Simple Storage Service (Amazon S3) 对象。然后,我想确保目标账户拥有复制的对象。该如何操作?

解决方法

重要提示:Amazon S3 中的对象不再自动归上载的 AWS 账户拥有。原定设置下,任何新建的存储桶都启用了存储桶拥有者强制设置。在更改对象所有权时,最佳实践还包括使用存储桶拥有者强制设置。但是,请注意,此选项会禁用所有存储桶 ACL 和存储桶中任何对象上的 ACL。

使用 S3 对象所有权中的存储桶拥有者强制设置后,Amazon S3 存储桶中的所有对象都自动归存储桶拥有者所有。存储桶拥有者强制功能还会禁用所有访问控制列表 (ACL),这简化了对存储在 S3 中的数据的访问管理。但是,对于现有存储桶,Amazon S3 对象仍归上载的 AWS 账户拥有,除非您显式禁用 ACL。要更改现有存储桶中对象的对象所有权,请参阅如何更改 S3 存储桶中公有对象的所有权?

如果您现有的对象共享方法依赖于使用 ACL,请确定使用 ACL 访问对象的主体。有关如何在禁用任何 ACL 之前查看权限的更多信息,请参阅禁用 ACL 的先决条件

如果您无法禁用 ACL,请按照以下步骤获取对象的所有权,直到您可以调整存储桶策略为止:

1.    在源账户中,创建 AWS Identity and Access Management (IAM) 客户托管策略,该策略向 IAM 身份(用户或角色)授予适当的权限。IAM 用户必须具有从源存储桶中检索对象并将对象放回目标存储桶的访问权限。您可以使用与以下内容类似的 IAM 策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::source-DOC-EXAMPLE-BUCKET",
                "arn:aws:s3:::source-DOC-EXAMPLE-BUCKET/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET",
                "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET/*"
            ]
        }
    ]
}

注意:此示例 IAM 策略仅包括在不同账户中列出对象和在存储桶之间复制对象所需的最低权限。您必须根据自己的使用案例自定义允许的 S3 操作。例如,如果用户必须复制具有对象标签的对象,您还必须授予 s3:GetObjectTagging 的权限。如果遇到错误,请尝试以管理员用户身份执行这些步骤。

2.    在源账户中,将客户托管策略附加到要用于将对象复制到目标存储桶的 IAM 身份。

3.    在目标账户中,将目标存储桶上的 S3 对象所有权设置为存储桶拥有者首选。设置 S3 对象所有权后,将访问控制列表 (ACL) 设置为 bucket-owner-full-control 时上传的新对象将自动由存储桶的账户拥有。

4.    在目标账户中,修改目标存储桶的存储桶策略,以授予源账户上传对象的权限。此外,在存储桶策略中包含一个条件,该条件要求上传对象才能将 ACL 设置为 bucket-owner-full-control。您可以使用如下语句:

注意:destination-DOC-EXAMPLE-BUCKET 替换为目标存储桶的名称。然后,将 arn:aws:iam::222222222222:user/Jane 替换为源账户中的 IAM 身份的 Amazon 资源名称 (ARN)

{
    "Version": "2012-10-17",
    "Id": "Policy1611277539797",
    "Statement": [
        {
            "Sid": "Stmt1611277535086",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:user/Jane"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        },
        {
            "Sid": "Stmt1611277877767",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:user/Jane"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET"
        }
    ]
}

注意:此示例存储桶策略仅包括上传具有所需 ACL 的对象所需的最低权限。您必须根据自己的使用案例自定义允许的 S3 操作。例如,如果用户必须复制具有对象标签的对象,您还必须授予 s3:GetObjectTagging 的权限

5.    配置 IAM 策略和存储桶策略后,源账户中的 IAM 身份必须将对象上传到目标存储桶。确保 ACL 被设置为 bucket-owner-full-control。例如,源 IAM 身份必须使用 --acl 选项运行 cp AWS CLI command

aws s3 cp s3://source-DOC-EXAMPLE-BUCKET/object.txt s3://destination-DOC-EXAMPLE-BUCKET/object.txt --acl bucket-owner-full-control

注意:如果在运行 AWS CLI 命令时收到错误,请确保您使用的是最新的 AWS CLI 版本

将 S3 对象所有权设置为存储桶拥有者首选后,使用 bucket-owner-full-control ACL 上传的对象将自动由目标存储桶的账户拥有。

重要提示:如果 S3 存储桶具有启用了 AWS Key Management Service (AWS KMS) 的默认加密,您还必须修改 AWS KMS 密钥权限。有关说明,请参阅我的 Amazon S3 存储桶具有使用自定义 AWS KMS 密钥的默认加密。我如何允许用户从存储桶下载和上传到存储桶?