マネジメントコンソール上でS3オブジェクトをクロスアカウントコピーする方法

記事タイトルとURLをコピーする

クラウドインテグレーション部の大穂です。

普段エンジニアをやっているとこんな場面に出くわすことありませんか?

「このS3のデータを使いたいけど、本番環境にあってなかなかいじりずらい、、
検証環境にあったらなー
そうか!S3を検証環境(別アカウント)にコピーしよう!!」

CLIでコピーをする方法に関してはAWS公式で出ていたり、弊社ブログにも記載されていたりするのですが、コンソール上でも実は可能なのにその方法は記載されていなかったので今回ブログにしていきたいと思います。

クロスアカウントでのIAMを通したS3へのアクセスにおいては、バケットポリシーとIAMPolicy両方での明示的な許可設定が必要です。もちろん今回もその設定を入れますが、コンソール上でクロスアカウントコピーするにおいてはこれだけでは足りないというのがこのブログのミソになります。

構成

構成はシンプルですが以下です。
アカウントBにあるバケット内のオブジェクトをアカウントAにコピーすることを目指します。

前提条件

以下を前提条件とします。(本ブログでは触れません)

  • 移行元S3にデータが格納済みであること
  • 移行先(アカウントA)にコピー用S3バケットが作成済みであること
  • アカウントBにログインできるIAM Userが存在していること

コピー元(アカウントB)の準備

IAM ポリシーの作成→IAM Userにアタッチ

バケットコピーを実施する許可をするためのIAMポリシーを作成します。今回はアカウントBのS3データを参照し、アカウントAのS3に格納するので以下のようなPolicyを作成します。

"Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::<アカウントBのS3バケット名>",
                "arn:aws:s3:::<アカウントBのS3バケット名>/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::<アカウントAのS3バケット名>",
                "arn:aws:s3:::<アカウントAのS3バケット名>/*"
            ]
        }
    ]

作成したらアカウントBのIAM Userにアタッチします。
これでアカウントB側の準備は完了です。

※ちなみにアカウントBのS3のバケットポリシーは記載しなくてOKです。同一アカウント上であればIAMポリシーの許可があればバケットポリシーの許可がなくてもS3にアクセスできます。
参考

コピー先(アカウントA)の準備

バケットポリシーの作成

アカウントBにあるIAM Userからの書き込みの許可を与えないといけません。 書き方は以下のようになります

{
    "Version": "2012-10-17",
    "Id": "test",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "[アカウントBのIAM UserのARN]"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "[アカウントAのS3のARN]/*",
                "[アカウントAのS3のARN]"
            ]
        }
    ]
}

さて、CLIでS3コピーを実行する場合はこの後以下のようなコマンドを実行すれば、コピーが実施できます。

aws s3 cp --profile <profile名> S3://<アカウントBのS3バケット名>/<フォルダ> S3://<アカウントAのS3バケット名>/<フォルダ>

しかし、コンソールでS3コピー(具体的な方法は下で記載) で実行しようとすると、エラーが発生し実行できません。

CLIでできていたのになぜ、、 もう一つ設定が必要なのです。

ACL(アクセスコントロールリスト)の設定

アクセスコントロールリスト(以下ACL)とは、AWSアカウントもしくは事前定義済みグループに対して、バケット・オブジェクトへのアクセスを許可するものになります。

※今回は「事前定義グループ」の説明は省略いたします。

今回は別アカウントからS3アクセスが必要なので、アカウントBに対してバケットへの書き込み権限を付与する必要があります。

ACLの有効化

ACLを使用するためにはACLを有効化する必要があります。 有効化するにはコンソール上で「アクセス許可」タブの中にある「オブジェクトの所有者」の項目から設定します。

ACL 有効を押下し、確認にチェックを入れたうえで「変更の保存」を押下します。

ACLの有効化

ACLの設定

ACLを有効化したら先ほど編集した「オブジェクトの所有者」のすぐ下に「アクセスコントロールリスト(ACL)」の項目があるのでそちらを編集します。

ACLの編集へ

一番下に「ほかのAWSアカウントのアクセス」があるので「被付与者の追加」を押下します。

ほかのAWSアカウントのアクセス

被付与者の項目にアカウントBのS3のACLにある「バケット所有者(AWSアカウント)」の正規IDを入力します。

オブジェクトの「リスト」「書き込み」にチェックを入れ、「変更の保存」を押下します。

これで、準備完了です。

コンソール上でコピー実施

では、コピーする準備が整いましたのでここからは実際にコピーする手順をお伝えします。

まず、アカウントBのS3のコンソール画面に移動し、コピーしたいフォルダ orファイルにチェックを入れた状態で、アクションの「コピーする」を押下します。

送信先にアカウントAのS3 URIを入力し、「コピーする」を押下します。

これでコピー完了です!

ただ、このままだとコピー先のオブジェクトの所有者がアカウントB(コピー元)となったままになっています。
コピー完了後にACLの設定で実施した非付与者IDの削除と、オブジェクト所有者の設定にてACL無効としていただくと、オブジェクト所有者がアカウントA(コピー元)となります。

おわり

コンソール上でS3のクロスアカウントコピーをする方法を紹介しました! CLIでは設定が必要ないがコンソールではこのような設定が必要ということがわかっていただけましたでしょうか? 皆様のご参考になりましたら幸いです。