クロスアカウントでS3クロスリージョンレプリケーションを設定してみた
西澤です。S3オブジェクトをクロスアカウント(異なるAWSアカウント間)で同期できるかを検証してみたので、注意事項をまとめておきたいと思います。S3のクロスリージョンレプリケーションの基本的な使い方は、下記記事が詳しいです。一部重複しているところもありますが、ご了承ください。
クロスリージョンレプリケーション機能でできないこと
そもそも機能としてできないこととして、下記に注意が必要となります。
- 同一リージョンのバケットをレプリケーションすることはできない
- 複数のバケットをレプリケーション先として指定することができない
- クロスアカウントでのレプリケーション設定は、SDKまたはAWS CLIからしか設定できない(AWSマネージメントコンソールでの設定不可)
同一リージョンでも使えると良さそうなのですが、リージョンが異なるレプリケーション先を指定しないとそもそも設定ができません。また、prefix指定により、複数のルールを指定することはできるものの、複数のバケットをレプリケーション先として設定することはできません。マネージメントコンソール設定の制約はそのうち解消されるかもしれません。
そもそも何がレプリケーションされるものかというところは公式ドキュメントをご確認ください。
概要
何をどこに設定しなければいけないかを確認しておきます。クロスアカウントでの設定となりますので、適切なパーミッションを設定しなければいけません。細かい手順を順を追って書くことはせず、ポイントだけを紹介したいと思いますので、最初にご紹介した記事や公式ドキュメントもご確認ください。
コピー元バケットへの設定
- バケットのバージョニングを有効化(前提条件)
- クロスリージョンレプリケーションを有効化
- 送信先バケットのリージョンとバケットを指定
- レプリケーションを実行するIAMロールを指定
コピー先バケットへの設定
- バケットのバージョニングを有効化(前提条件)
- バケットポリシーでレプリケーションを実行するIAMロールからの書き込みを許可
レプリケーションを実行するIAMロール
何が許可されたIAMロールなのかしっかり確認しておきましょう。このIAMロールはコピー元バケットを所有しているAWSアカウントで設定します。
信頼ポリシー
S3サービスから利用できるIAMロールとして定義したいのですが、AWSマネージメントコンソールからの"ロールの作成"では、"Principal": {"Service": "s3.amazonaws.com"}
を指定したIAMロールを作ることは現時点ではできなさそう?なので、一度適当なものを選んで作ってから、信頼ポリシーを修正するという形を取りました。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "s3.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
アクセス許可
S3バケット名は、全世界でユニークとなっている制約から、ARNにAWSアカウントIDは指定しません。コピー元、コピー先のバケットを意識して設定しましょう。
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "s3:GetReplicationConfiguration", "s3:ListBucket" ], "Resource":"arn:aws:s3:::cross-account-region-repl-src" }, { "Effect":"Allow", "Action":[ "s3:GetObjectVersion", "s3:GetObjectVersionAcl" ], "Resource":"arn:aws:s3:::cross-account-region-repl-src/*" }, { "Effect":"Allow", "Action":[ "s3:ReplicateObject", "s3:ReplicateDelete" ], "Resource":"arn:aws:s3:::cross-account-region-repl-dst/*" } ] }
コピー先バケットのバケットポリシー
ここで初めてクロスアカウントを意識した設定が必要となります。コピー先バケットには、レプリケーション実行をする(コピー元アカウントの)IAMロールから、書き込みを許可する設定が必要となります。バケットポリシーにて設定を行いますが、公式ドキュメントのサンプルでは、コピー元となるAWSアカウント全てからのレプリケーションを許可{"Principal":{"AWS":"arn:aws:iam::111111111111:root"}
する設定となっていたのですが、レプリケーションするIAMロールのみに許可{"Principal":{"AWS":"arn:aws:iam::111111111111:role/S3RepRole"}
する設定としてみました。
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal":{ "AWS":"arn:aws:iam::111111111111:role/S3RepRole" }, "Action":[ "s3:ReplicateObject", "s3:ReplicateDelete" ], "Resource":"arn:aws:s3:::cross-account-region-repl-dst/*" } ] }
クロスリージョンレプリケーションの有効化
クロスアカウントでクロスリージョンレプリケーションを設定する場合、AWSマネージメントコンソールからの設定はサポートされていません。一部遠回りをしたところもありましたが、この箇所以外は全てAWSマネージメントコンソールから設定できました。ここだけは、SDKまたはAWS CLIから設定する必要がありますので、今回はAWS CLIを利用して設定してみます。
レプリケーション設定ファイル(json)の作成
利用するIAMロールとレプリケーション先のバケットを下記形式でjsonファイルに定義します。S3バケット名はユニークなので、Regionの指定箇所はありませんが、レプリ先バケットのリージョンが同一だと設定時にエラーとなります。Ruleキーは、配列となっていて複数書くこともできますが、レプリ先が同じで、重複が無いprefixとなっていないと、設定時にエラーとなりました。下記例ではprefix指定はしていません。
cat > repconfig.json << EOF { "Role": "arn:aws:iam::111111111111:role/S3RepRole", "Rules": [ { "Prefix": "", "Status": "Enabled", "Destination": { "Bucket": "arn:aws:s3:::cross-account-regsion-repl-dst" } } ] } EOF
レプリケーション有効化
作成した設定ファイルを利用して、レプリケーションを有効化します。
aws s3api put-bucket-replication \ --bucket cross-account-region-repl-src \ --replication-configuration file://./repconfig.json
レプリケーション設定の確認
AWSマネージメントコンソールでは、確認することもできません。同一AWSアカウント内で、クロスリージョンレプリケーションを有効にした場合は、このように表示されますが、
クロスアカウントで設定した場合、有効となっていることしかわからず、詳細が表示されません。
設定した内容は、aws s3api get-bucket-replication
で確認してください。
$ aws s3api get-bucket-replication --bucket cross-account-region-repl-src { "ReplicationConfiguration": { "Rules": [ { "Status": "Enabled", "Prefix": "", "Destination": { "Bucket": "arn:aws:s3:::cross-account-region-repl-dst" }, "ID": "NzZiZDNkZGUtYTgyZi00N2I1LWI0MjEtNTIwNzUwYjgxYzQ3" } ], "Role": "arn:aws:iam::111111111111:role/S3RepRole" } }
aws s3api put-bucket-replication
を実行するときに、レプリケーション先のバケットが存在すること、バージョニングが有効になっていること、は確認してエラーを返してくれますが、適切なバケットポリシーが設定されているかまでは見てくれませんでした。一度設定した後は、レプリケーション先のバケットが削除されても、特にエラーを確認できる画面もログも無いようですので、同期状態を担保しなければいけないような用途では、別で確認の仕組みを検討する必要がありそうです。
まとめ
クロスアカウントでS3バケット内のオブジェクトを同期したいという要件はそれなりにあると思うのですが、同一リージョンになる場合が多そうですね。リージョンが異なる場合にしか使えないのですが、利用できる機能を上手く組み合わせて楽に仕組みを作っていきたいです。