自分のAWSアカウントからS3オブジェクトを相手のAWSアカウントのS3へコピーする(相手はその後、所有権も取りたい)


まずはAWS公式

他の AWS アカウントから S3 オブジェクトをコピーする
https://aws.amazon.com/jp/premiumsupport/knowledge-center/copy-s3-objects-account/

・・・これの逆ってできないの?

逆にすればいいだけ

記事では

  1. アカウント A のソースバケットに、バケットポリシーを添付します。
  2. アカウント B のユーザーまたはロールに AWS Identity and Access Management (IAM) ポリシーを添付します。
  3. アカウント B の IAM ユーザーまたはロールを使用して、クロスアカウントコピーを実行します。

となっているので(添付、って翻訳は置いといて;原文は attach です)
これを

  1. アカウント B のソースバケットに、バケットポリシーを添付します。
  2. アカウント A のユーザーまたはロールに AWS Identity and Access Management (IAM) ポリシーを添付します。
  3. アカウント A の IAM ユーザーまたはロールを使用して、クロスアカウントコピーを実行します。

で良かった。そりゃそうなんですが、まぁそうか。

サンプルでいうと

1. アカウント B のソースバケットに、バケットポリシーを添付します。

"arn:aws:iam::111111111111:user/Bob"はアカウント A のユーザーです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DelegateS3Access",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::111111111111:user/Bob"},
            "Action": ["s3:PutObject"],
            "Resource": [
                "arn:aws:s3:::awsexampledestinationbucket/*",
                "arn:aws:s3:::awsexampledestinationbucket"
            ]
        }
    ]
}

2. アカウント A のユーザーまたはロールに AWS Identity and Access Management (IAM) ポリシーを添付します。

アカウントAのユーザー(またはロール)なのですが、アカウントBのバケットに対する操作権限を付与するイメージ。(ここがわかりにくいポイントかもしれない)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::awsexampledestinationbucket",
                "arn:aws:s3:::awsexampledestinationbucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::awsexamplesourcebucket",
                "arn:aws:s3:::awsexamplesourcebucket/*"
            ]
        }
    ]
}

3. アカウント A の IAM ユーザーまたはロールを使用して、クロスアカウントコピーを実行します。

これはサンプルと一緒。

さらに

アカウントB側でオブジェクトオーナー取ることを強制できます。上記1.で

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DelegateS3Access",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::111111111111:user/Bob"},
            "Action": ["s3:PutObject"],
            "Resource": [
                "arn:aws:s3:::awsexampledestinationbucket/*",
                "arn:aws:s3:::awsexampledestinationbucket"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

と付けてやると、アカウントAがACLを渡してくれないコピーは拒否できます。
(参照:https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html

$ aws s3 cp s3://awsexamplesourcebucket/test.txt s3://awsexampledestinationbucket
copy failed: s3://awsexamplesourcebucket/test.txt to s3://awsexampledestinationbucket /test.txt An error occurred (AccessDenied) when calling the CopyObject operation: Access Denied

$ aws s3 cp s3://awsexamplesourcebucket/test.txt s3://awsexampledestinationbucket --acl bucket-owner-full-control
copy: s3://awsexamplesourcebucket/test.txt to s3://awsexampledestinationbucket /test.txt

とコピーする側がbucket-owner-full-controlを付けることを強制できます。

さらに

このままではコントロールはアカウントBが取れるのですが、オブジェクト所有者は依然としてアカウントAのままでした。
先日のアップデートで自動で所有権も取ることができるようになりました。

【2020/10/02アップデート】 Amazon S3 Object Ownership が利用可能になり、バケットにアップロードされたオブジェクトの所有権をバケット所有者が自動的に引き受けることが可能に

ドキュメントはこちら。
https://docs.aws.amazon.com/AmazonS3/latest/user-guide/add-object-ownership.html

めでたしめでたし。