クロスアカウントで S3 sync するための権限設定

こんにちは、菊池です。

小ネタですがクロスアカウント環境でS3 syncを実行する際の権限設定を紹介します。

はじめに

S3 sync コマンドではローカル環境とS3バケット、または異なる2つのS3バケットでオブジュエクトを同期することができます。

s3sync00

AWS CLIの場合には以下のようなコマンドで実行が可能です。

aws s3 sync {同期元のローカルパスまたは S3 URI} {同期先のローカルパスまたは S3 URI}

このS3 syncですが、異なる2つのAWSアカウント(クロスアカウント)のS3 バケット間で同期する際にはアクセス権限の設定に少し手間がありましたのでご紹介します。

クロスアカウントでの S3 sync

例えば以下の図のように、アカウントAのS3バケットからアカウントBのS3バケットにsyncする場合を考えます。コマンドを実行するEC2にはIAM Roleを割り当てて、IAM ポリシーでアカウントAのS3バケットにアクセス権があります。しかし、同期先であるアカウントBのS3バケットにはアクセス権限がないためsyncコマンドは失敗します。

s3sync01

そこで、STS AssumeRole を使って、アカウントBのIAM Roleの一時認証情報を取得し、アカウントBのIAM権限でアクセスすることを考えます。しかし、今度は同期元のアカウントAのS3バケットにもアカウントBのIAM権限でアクセスすることになるため、権限がなく拒否されてしまいます。

s3sync02

クロスアカウントの環境では、必要なIAM権限はSTSで一時認証情報を利用するのが一般的ですが、1つのコマンドで複数アカウントの権限を必要とする場合にはこの方法は利用できません。

バケットポリシーで異なるアカウントのIAMからアクセスを許可する

このような場合、片方のS3バケットへのアクセス権の付与にバケットポリシーを使います。アカウントBのS3バケットにアカウントAのIAM Roleに対するアクセス許可を与えます。

s3sync03

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "xxx",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::123456789012:role/testRole" //アカウントA の IAM Role の ARN
			},
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::examplebucketB/*"
		}
	]
}

※ 上記バケットポリシーでは例として"Action": "s3:*"で全ての操作権限を付与していますが、必要に応じて適切な操作のみを記述してください。

または、アカウントAのS3バケットにてアカウントBのIAM Roleを許可するバケットポリシーを設定し、アカウントBのIAM Roleの一時認証情報でアクセスすることも可能です。

s3sync04

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "xxx",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::987654321098:role/testRole" //アカウントB の IAM Role の ARN
			},
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::examplebucketA/*"
		}
	]
}

おわりに

いかがでしょうか。

AWSで異なるアカウントのAPI操作をする際にはAssumeRoleを使って権限を取得するのが一般的です。しかし、その際にはスイッチ前の元のIAM権限は継承されないため、今回のように複数のアカウントへ同時にアクセスする際にはちょっとした工夫が必要です。

他にもSQSなどでも同じようなケースがありえますので、以下も参考にしてください。