S3レプリケーションのポイントとして重要なのが、ソース/レプリケート先両方のバケットでバージョニングを有効にすること。異なるアカウントへのレプリケーションの場合、レプリケート先のバケットポリシーでソースバケットからのアクセスを許可すること。

レプリケート先アカウントのバケポリでは、ソースバケット所有者の AWSアカウントIDとレプリケート先バケット名を指定する。

 

大前提の設定
ソース/レプリケート先両方のバケットで以下の設定とする。

・ バージョニング:有効
・ ACL : 無効
・ パブリックアクセス :ブロック ※要件次第

 

基本的な構成
(1) ソースバケット
・ バケット名:source-bucket-name
・ AWS リージョン:ap-northeast-1
・ バケットのバージョニング:有効にする

(2) レプリケーションバケット
・ バケット名:replication-bucket-name
・ AWS リージョン:ap-northeast-1 ※クロスリージョンの設定も可能。
・ バケットのバージョニング:有効にする

 

レプリケーションルール
対象バケットの「管理」タブから、レプリケーションルールを作成する。

レプリケーションルール名:TestRule
ステータス:有効(デフォルト)
優先順位:1 (デフォルト)

「ソースバケット」セクション
ルールスコープを選択:「このルールは、バケット内のすべてのオブジェクトに適用されます」を選択

送信先セクション
「別のアカウントのバケットを指定する」にチェック
送信先のバケット名を入力
送信先リージョン:(想定するリージョン名になっていること)

IAMロール
レプリケーション設定時に新しいIAMロールの自動作成が可能だが、要件に応じて予め作成しておく。

レプリケーションロール用の信頼ポリシー

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Principal":{
            "Service":"s3.amazonaws.com"
         },
         "Action":"sts:AssumeRole"
      }
   ]
}

IAMロールにアタッチするIAMポリシー。(ソースAWSアカウントで設定)

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "s3:GetObjectVersionForReplication",
            "s3:GetObjectVersionAcl"
         ],
         "Resource":[
            "arn:aws:s3:::ソースS3バケット名/*"
         ]
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListBucket",
            "s3:GetReplicationConfiguration"
         ],
         "Resource":[
            "arn:aws:s3:::ソースS3バケット名"
         ]
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListBucket",
            "s3:GetReplicationConfiguration",
            "s3:GetObjectVersionForReplication",
            "s3:GetObjectVersionAcl",
            "s3:GetObjectRetention",
            "s3:ReplicateObject",
            "s3:GetObjectVersionTagging",
            "s3:GetObjectLegalHold",
            "s3:ReplicateDelete",
            "s3:ObjectOwnerOverrideToBucketOwner",
            "s3:ReplicateTags"
         ],
         "Resource":"arn:aws:s3:::レプリケート先S3バケット名/*"
      }
   ]
}

 

オプション設定
デフォルトのレプリケーション設定は、ソースバケット側のオブジェクト削除をレプリケート先では反映しない。このため、削除をレプリケート先で反映させたい場合はルールを変更する必要がある。レプリケーションルール–>追加のレプリケーションオプション->「削除マーカーのレプリケーション」にチェックを入れる。

上記は要件に応じてやればよいが、「レプリケーション時間のコントロール(RTC)」「レプリケーションメトリクスと通知」はほぼ有効にしておくべきと思われる。

 

所有者の変更
デフォルトでソース元アカウントがレプリカの所有権を持つが、レプリケート先のアカウントが所有権を保持するように設定することも可能。実現するには、送信先S3バケットのバケットポリシーに、オブジェクト所有者を変更できる権限(ObjectOwnerOverrideToBucketOwner)を追加する。

以下、所有者変更権限を付与したバケポリ。(レプリケート先アカウントのバケットに設定)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "destination_bucket_policy_sid",
      "Principal": {
        "AWS": "arn:aws:iam::ソースAWSのアカウントID:role/service-role/ソースAWSアカウントのIAMロール"
      },
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ObjectOwnerOverrideToBucketOwner",
        "s3:ReplicateTags",
        "s3:GetObjectVersionTagging"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::レプリケート先S3バケット名/*"
      ]
    }
  ]
}

 

暗号化の対応
レプリケート元バケット内のオブジェクトが SSE-S3、AWS KMSキーによるサーバー側の暗号化 (SSE-KMS)、または AWS KMS キーによる二層式サーバー側の暗号化 (DSSE-KMS) を使用して暗号化されている場合、レプリケート先バケットのレプリカオブジェクトはレプリケート元オブジェクトと同じタイプの暗号化を使用する。レプリケート先バケットのデフォルトの暗号化設定は使用されない。

デフォルトでは、Amazon S3 はAWS KMSキーによるサーバー側の暗号化 (SSE-KMS) を使用して暗号化されたオブジェクトをレプリケートしない。SSE-KMSで暗号化されたオブジェクトをレプリケートするには、別途設定が必要。

重要ポイント。KMSキーはレプリケート先バケットと同じAWSリージョン内で作成されている必要がある。
以下事例は同一リージョン内の設定となるが、非常に重要な参考例。KMKSキーは送信元・送信先両方で作成する必要がある模様。
SSE-KMSで暗号化したS3バケット同士のクロスアカウントレプリケーションでは、S3バケットキーの有無に注意してほしい ※classmethodブログ

それからレプリケート先でKMS CMKを設定することは可能な様子であるが、異なるリージョンでも設定可能かどうかは不明。以降、同一リージョン間レプリケーションと想定して…、レプリケート先でCMKを使用する場合、キーポリシーの「“Sid”: “Allow use of the key”,」、「“Sid”: “Allow attachment of persistent resources”」のPrincipalにソースAWSアカウントのIAMロールARNを追加する。

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:RevokeGrant",
                "kms:GenerateDataKey",
                "kms:ReEncryptTo",
                "kms:GenerateDataKeyWithoutPlaintext",
                "kms:DescribeKey",
                "kms:GenerateDataKeyPairWithoutPlaintext",
                "kms:GenerateDataKeyPair",
                "kms:CreateGrant",
                "kms:ReEncryptFrom",
                "kms:ListGrants"
            ],
            "Resource": "arn:aws:kms:ap-northeast-1:ソースAWSアカウントID:key/CMKキーID"
        }
    ]

ソースAWSアカウントのIAMロールでも、CMKによる暗号化を可能とするIAMポリシーを設定する必要がある。

 

参考
レプリケート元バケットとレプリケート先バケットが異なるアカウントによって所有されている場合での、レプリケーションの設定
ソースとレプリケート元とレプリケート先のバケットが異なるアカウントによって所有されている場合のレプリカの所有者の変更
サーバー側の暗号化 (SSE-C、SSE-S3、SSE-KMS、DSSE-KMS) で作成されたオブジェクトをレプリケートする

クロスアカウントによるS3レプリケーションのパターン別設定方法 ※classmethodブログ

 

暗号化 + クロスアカウントパターン
SSE-KMS暗号化したS3バケットのクロスアカウントレプリケーションをやってみた
SSE-KMSで暗号化したS3バケット同士のクロスアカウントレプリケーションでは、S3バケットキーの有無に注意してほしい ※classmethodブログ

 

CRR(クロスリージョンレプリケーション)用の設定 ※やることはほぼ同じ。
【備忘録】AWS S3 クロスリージョンレプリケーション(CRR)の設定方法
S3クロスリージョンレプリケーションをやってみた

 

レプリケーションに限らず、「カスタムKMSキーで暗号化したバケット + クロスアカウント」のS3操作は何かとハマりどころがある。必要な設定など以下参考。

他のアカウントのユーザーに KMS キーの使用を許可する
クロスアカウントユーザーがカスタム AWS KMS キーで暗号化された S3 オブジェクトにアクセスしようとするときに Access Denied エラーが発生するのはなぜですか?
KMS Not found Exception in AWS Cross Account S3 PutObject encrypted by AWS Managed Key

 


関連がありそうな記事