フューチャー技術ブログ

S3でクロスアカウントアクセスする時に気をつけるポイント

はじめに

こんにちは。TIG/DXユニット 2020年新卒の渡辺です。

Amazon S3を利用したファイル連携を行う際、アカウント内に閉じた利用であれば特段問題ない場合でも、システム間連携となるとクロスアカウントが発生し、目的とした操作をするためには然るべき設定が必要になることがあります。

今回は、自アカウント(アカウントA)のS3バケットに対して他アカウント(アカウントB)から書き込みを行い、アカウントAから当該ファイルを参照する際に注意する設定について紹介していきます。

必要な設定は以下の2つです。

  • バケットポリシーの設定
  • オブジェクト所有者の変更
アカウントAのS3バケットへアカウントBからアクセスする様子

バケットポリシーの設定

クロスアカウントアクセスを許可する設定として公式では、それぞれバケットポリシー、ACL、AssumeRoleを用いた3つの方法が紹介されていいます。

今回はバケットポリシーを利用する方法を記載します。lambdaなどから利用する分には標準的で、多用される方法かと思います。リソースベースポリシーをサポートしていないAWSサービスを利用する際などは残りの方法を検討ください。

書き込み先であるアカウントAのS3バケットに設定するバケットポリシーの例は以下の通りです。

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": [
"s3:PutObject",
],
"Resource": [
"arn:aws:s3:::my-bucket/*",
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}

アカウントBに対して、アカウントAのS3バケット(my-bucket)へのPutObject権限を付与しています。

PrincipalにはアカウントBのIDを設定してください。IAMユーザーを指定する場合は、末尾のrootuser:userNameの形式に変更し、ユーザ名を設定してください。

また例のようにConditionを設定することで、オブジェクトのACLがbucket-owner-full-control(後述)に設定されている場合のみアップロードできるようになります。bucket-owner-full-controlが付与されていない書き込みはエラーとなるため、誤った書き込み自体を防ぐことが可能になります。

バケットポリシーの設定は以上ですが、アカウントBのユーザー権限が制限されていて、当該バケットへのPutObjectが許可されていない場合は、ユーザーへのIAMポリシーの追加が必要になるので忘れずに設定しましょう。

オブジェクト所有者の変更

バケットポリシーの設定により、アカウントBからアカウントAのS3バケットへの書き込みは可能になりました。しかし、単純に書き込むだけでは、書き込んだファイルがアカウントAから読めないという問題が発生します。

なぜなら、各オブジェクトにはそれぞれ所有者が決まっており、デフォルトでは書き出しを行なったアカウント(今回の場合はアカウントB)が所有者に設定されるためです。

現在の所有者は、オブジェクトの[プロパティ]から確認できます。

マネジメントコンソールからオブジェクトの所有者を確認

アカウントAからオブジェクトを見るためには、まずS3バケットの[アクセス許可]にある[オブジェクト所有者]を希望するバケット所有者に変更します。 この設定により、アカウントBから書き込みを行う際に、オブジェクト所有者を変更することが可能になります。

オブジェクトの所有者を確認

上記設定を行なった上で、アカウントBから書き込む際にbucket-owner-full-controlを付与することで、所有者をアカウントAに変更できます。CLIから付与する例は以下の通りです(プログラムから書き出す際も同様に付与する必要があります。付与する方法は各言語のaws-sdkリファレンスを参照ください)。

aws s3 cp sample.txt s3://my-bucket --acl bucket-owner-full-control

最後に

今回は、S3でクロスアカウントアクセスをする際に注意する設定について紹介しました。

特にオブジェクト所有者の変更(bucket-owner-full-controlの付与)は忘れやすく、「普段プログラムから書き込んでいるが、急遽CLIから書き込んでみたらエラーになり焦る」ということが発生しないように覚えておくといいと思います。