Skip to content
Go back

AWSアカウント間でのS3 to S3ファイルコピー

Published:  at  12:00 AM

自分のAWSアカウント内のS3から、別アカウントのS3へファイルをコピーする機会があったので方法を残しておく。

今回は送信元アカウントのIAMユーザーに対して、送信先アカウントで権限を付与してもらい、このIAMユーザーを使ってファイルをコピーする方法を取った。

内容としてはこちらの記事にも詳しく説明されている:

準備

まず、送信先のアカウントの管理者から、送信先のバケット名、バケット内のどのPrefixにファイルをコピーするのかを確認しておく。ここでは仮に

とする。

*実務的には、1回限りの連携と思っても、実際には何度かデータ再送信することもある。なのでPrefixは適宜ネームスペースを切っておくと良い。例えば、copy/here/${送信日}/${ファイルバージョン名}/みたいに。

送信元については、

とする。

送信元: IAMユーザー作成と権限付与

次に、ファイルを送信するためのIAMユーザーを作成する。

適当な名称でIAMユーザーを払い出し、以下のPolicyをアタッチする。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:GetObject", "s3:GetObjectTagging"],
      "Resource": [
        "arn:aws:s3:::bucket-from",
        "arn:aws:s3:::bucket-from/copy/from/here/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:PutObject", "s3:PutObjectAcl"],
      "Resource": [
        "arn:aws:s3:::bucket-to",
        "arn:aws:s3:::bucket-to/copy/to/here/*"
      ]
    }
  ]
}

ここで、参考記事にも記載されているが、s3:GetObjectTaggingについては、送信元のS3バケットでバージョニングを有効化している場合は必要となる。その他、権限でエラーが出た場合の対応についても参考記事に詳しく載っている。

発行したらIAMユーザーのARNを送信先アカウントの管理者に連携する。 ARNはこのような形式になるはず: arn:aws:iam::123456789:user/copy-user

送信先: バケットの権限設定

送信先のバケットのS3 Object OwnerShipをbucket owner prefferedに設定する。 これでbucket-owner-full-controlオプション付きでUploadされたオブジェクトは、送信先アカウントの所有となる。

次に、送信先バケットのバケットポリシーを設定する。

{
  "Version": "2012-10-17",
  "Id": "Policy123456789",
  "Statement": [
    {
      "Sid": "Stmt123456789",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789:user/copy-user"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::bucket-to/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      }
    },
    {
      "Sid": "Stmt123456789",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789:user/copy-user"
      },
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::bucket-to"
    }
  ]
}

ここでも、先ほどのアカウントと同様、ObjectTaggingなど必要な権限は環境によって異なる可能性があるので、適宜修正する。

送信元: ファイル送信

以上で設定は完了したので、ファイルを送信できる。

自分のケースではショットでの対応だったので、作業PCからaws cliを叩いて実行した。適宜キーを発行してaws cliでの認証を通しておく。今回は--profile copy-userに設定したものとする。

まずは実行前に--dryrunを使ってコマンドを確認するのがおすすめ。

aws s3 cp --dryrun \\
   --profile copy-user \\
   --recursive \\
   --expected-size 107374182400 \\
   --acl bucket-owner-full-control \\
      s3://bucket-from/copy/from/here/ s3://bucket-to/copy/to/here/

ここで、

dryrun結果に問題がなければ、--dryrunオプションを消して実行する。 データ量が多い場合は、かなり時間がかかることもあるので、作業PC上で実行する際はtmuxを活用すると、PCがスリープしてもバックグランドで実行を継続してくれる。

tmux new -s s3-operation

自分の場合は、tmuxで実行したが、社内VPNが途中で切れてしまってErrorになってしまった。可能であればVPNは最初から切っておくのが良さそうだ。

送信が完了したら、最後に念の為、ファイル数とサイズが一致するか確認しておくと良いだろう。

# ファイル数の一致確認
aws s3 ls --profile copy-user --recursive s3://bucket-from/copy/from/here/  | wc -l
aws s3 ls --profile copy-user --recursive s3://bucket-to/copy/to/here/  | wc -l

# ファイルサイズの一致確認
aws s3 ls --profile copy-user --recursive --summarize s3://bucket-from/copy/from/here/  | grep "Total Size"
aws s3 ls --profile copy-user --recursive --summarize s3://bucket-to/copy/to/here/  | grep "Total Size"

上記結果がそれぞれ一致していれば、ミスなくコピーできているはずだ。



Previous Post
Github Actionsから別のリポジトリにコミットする
Next Post
DenoKVとSupabaseでTodoリストアプリを作ってみる