複数AWSアカウントを運用しているとアカウントAからアカウントBのS3にファイルをアップロードする、といったことが発生することがあります。
今回は特定のアカウント内にあるEC2から別のアカウントのS3にファイルをアップロードしてみたいと思います。
実施作業
構成
構成としてはすごいシンプルで、アカウントAにあるEC2からCLIを使用してアカウントBのS3に対して直接ファイルをアップロードします。
VPCEndpointを使用する想定です。

アカウントA設定
まずはファイルをアップロードするアカウントA側の設定をします。
IAMロール作成
EC2にアタッチするIAMロールを作成します。
今回は検証なので、AdministratorAccessを設定しています。
地味にハマりどころなのですが、EC2にアタッチするときはインスタンスプロファイルが作成されていないといけないので、その点は注意が必要です。

EC2構築
EC2はコンソールのガイドに導かれるままに構築します。
OSは使い慣れているWindows Server 2019にしました。
構築する際は先ほど作成したIAMロールをEC2にアタッチするのを忘れないようにします。

EC2に設定するSGはインバウンドの自分のIPからのRDPのみです。アウトバウントはそのままにします。

キーペアからWindowsパスワードを生成し、RDPでログインします。
ログイン後AWS CLIが使えるようにインストールをしておきます。

CLIが使えるようになったら、使用するための認証設定をします。
ユーザフォルダ直下に.awsフォルダにあるconfigファイルに、アタッチされたIAMロールを使用して認証されるように設定します。(コマンドからも可能ですが割愛)

以下のように設定します。
プロファイル名は適当にIAMロールと同じ名前にしています。

以下のように表示されれば設定完了です。

最後にアカウントBのS3バケットポリシーに設定するために、IAMロールのRoleIdを確認します。
以下のコマンドをEC2のPowerShellなどで実行します。
$ aws iam get-role --role-name [アタッチしたIAMロール名] --profile [プロファイル名]
以下のように出力されるので、RoleIdの値をメモしておきます。
これでアカウントAでの設定は完了です。
PS C:\Users\Administrator> aws iam get-role --role-name XXXXX_role --profile XXXXX_role
{
"Role": {
"Path": "/",
"RoleName": "XXXXX_role",
"RoleId": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"Arn": "arn:aws:iam::XXXXXXXXXXXX:role/XXXXX_role",
"CreateDate": "2021-05-19T09:41:34+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"s3.amazonaws.com",
"ec2.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
},
"Description": "XXXXX_role",
"MaxSessionDuration": 3600,
"Tags": [
{
"Key": "Name",
"Value": "XXXXX_role"
}
],
"RoleLastUsed": {
"LastUsedDate": "2021-05-20T02:25:08+00:00",
"Region": "ap-northeast-1"
}
}
}
アカウントB設定
まずはアップロード先のS3があるアカウントBの設定を実施します。
バケットポリシー設定
アクセス許可タブを押下し、バケットポリシーを設定します。


今回は以下のようなポリシーを設定しました。
特筆すべき点を記載します。
①→アカウントAのIDを設定
②→メモしたRoleIdを設定
③→自PCとアカウントAのEC2のIPを設定
④→アカウントA上のS3 VPCEndpointのIDを設定
※バケットポリシーの設定は一歩間違うとアクセスできなくなるため、注意しながら実施してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow Policy",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::XXXXXXXXXXX:root",
"arn:aws:iam::YYYYYYYYYYYY:root"①
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::test-tmp-20210519",
"arn:aws:s3:::test-tmp-20210519/*"
]
},
{
"Sid": "Deny Policy",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::XXXXXXXXXXX:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::test-tmp-20210519",
"arn:aws:s3:::test-tmp-20210519/*"
],
"Condition": {
"StringNotLike": {
"aws:userid": "ABCDEFGHIJKLMNOPQRSTUVWXYZ:*"②
},
"NotIpAddress": {
"aws:SourceIp": [③
"AAA.AAA.AAA.AAA",
"BBB.BBB.BBB.BBB"
]
},
"StringNotEquals": {
"aws:sourceVpce": [④
"vpce-00000000000"
]
}
}
}
]
}
EC2からS3にファイルアップロード
まずはEC2からコマンドでS3バケットが確認できるかコマンドで試してみます。
$ aws s3 ls s3://test-tmp-20210519/ --profile XXXXX_role
S3の中身が見えているので問題なくアクセスできてそうです。

では実際に以下のコマンドを実行してファイルをS3にアップロードしてみます。
※ファイルは適当に作成しました。
$ aws s3 cp .\test.txt s3://test-tmp-20210519/ --profile XXXXX_role
アップロードが完了しました。

コンソールからもS3を確認してみましたが、問題なくアップロードされてました。

感想及び所感
一部VPC Endpointの作成等、手順を省略しているところはありますが、無事に異なるアカウントからファイルのアップロードができました。
他にもやり方はあるとは思いますが、今回はアップロード元のIAMロール権限を使用したアップロードを試してみました。
