はじめに
AWS S3には、別リージョンや別AWSアカウントのS3にオブジェクト(ファイルなど)をコピー(レプリケーション)する機能があります。
本記事では、以下の要件を前提として、S3のレプリケーションの設定方法を記載しています。
- 別AWSアカウントのS3へのコピー
- コピー元のAWSアカウントとコピー先のAWSアカウントでそれぞれ別のKMSを使用
上記に加えて、レプリケーション失敗時のログの出力方法についても記載しています。
本記事の情報は2025年2月時点のものです。
最新情報については公式ドキュメントをご確認ください。
目次
必要なリソース
重要ポイント
構築手順
検証ならびにメトリクス確認とログ出力
まとめ
必要なリソース
コピー元のAWSアカウント
- KMS(カスタマー管理型キー)
- S3(バージョニング有効:必須)
- IAMポリシー・ロール
- Lambda:ログ出力用(SNSなどでも代替可能)
コピー先のAWSアカウント
- KMS(カスタマー管理型キー)
- S3(バージョニング有効:必須)
本記事では、すべてのリソースは同一リージョン(ap-northeast-1)に作成しています。
重要ポイント
KMS
カスタマー管理型キーを選択してください。
AWSマネージド型キーはクロスアカウントレプリケーションに対応していません。
なお、同一アカウント内のレプリケーションはAWSマネージドキーでも可能です。
S3
バージョニングを有効にしないと、レプリケーションルールを作成できません。
必ず有効にしてください。
ログ出力
レプリケーションが失敗した場合のログがレプリケーションルール自体では確認ができません。
コピー元のS3のイベント通知を設定し、LambdaやSNSなどを利用してログを確認する必要があります。
構築手順
以下では、画面キャプチャとともに、詳細な設定手順を記載しています。
1.コピー元AWSアカウントの設定
1.1 コピー元AWSアカウントでKMSの作成
- 該当のリージョンのKMSコンソール画面を開き、「カスタマー管理型キー」をクリック
カスタマー管理型キーを選択してください。
AWSマネージド型キーはクロスアカウントレプリケーションに対応していません。
- 「キーの作成」をクリック
- キーのタイプは「対称」を選択
- キーの使用法は「暗号化および複合化」を選択
- 詳細オプションはそのままで、右下の「次へ」をクリック
- エイリアスには任意のキー名を入力
- 説明やタグも任意で設定することが可能
- 上記2点を記載後、「次へ」をクリック
- キー管理者やキーの削除に関しては、案件や会社ごとの取り決めに従って設定
- 「次へ」をクリック
- キーユーザーはなくても問題なし
- 別のAWSアカウントも設定なし
- キーポリシーはデフォルトのままで「次へ」をクリック
- 確認画面が表示されるので、ページ右下の「完了」をクリック
1.2 コピー元AWSアカウントでS3バケットの作成
- 該当リージョンのS3コンソール画面を開く
- 「バケットを作成」をクリック
- バケットタイプは、本記事では「汎用」としています
- バケット名は任意のもの入力(グローバルで一意とする必要あり)
- オブジェクト所有者は、本記事では「ACL無効(推奨)」を選択
- このバケットのブロックパブリックアクセス設定は、「すべてブロック」にチェック(デフォルト)
- バケットのバージョニングを「有効にする」にチェック
バージョニングを有効にしないと、レプリケーションルールを作成できません。
必ず有効にしてください。
-
タグは任意で付与
-
デフォルトの暗号化の「暗号化タイプ」は「AWS Key Management Service キーを使用したサーバー側の暗号化 (SSE-KMS)」を選択
-
AWS KMSキーで「コピー元AWSアカウントでKMSの作成」で作成したキーを選択
- バケットキーは、本記事では「有効にする」を選択
- 上記の設定が完了後、画面右下の「バケットを作成」をクリック
1.3 コピー元AWSアカウントでIAMロールとポリシーの作成
- IAMのコンソール画面を開き、「ロール」を選択し、「ロールを作成」をクリック
- 信頼されたエンティティタイプは「AWSのサービス」、ユースケースは「S3」を選択
- 許可ポリシーはのちほど追加するので、選択せず、「次へ」をクリック
- ロール名および説明は任意のものを入力
- 信頼ポリシーではPrincipalがS3となっており、ActionがSTSのAssumeRole
- 画面右下の「ロールを作成」をクリック
2. コピー先AWSアカウントの設定
コピー先のAWSアカウントで作業を行います。
2.1 コピー先AWSアカウントでKMSの作成
カスタマー管理型キーを選択してください。
AWSマネージド型キーはクロスアカウントレプリケーションに対応していません。
基本的には「1.1 コピー元AWSアカウントでKMSの作成」と同様の手順で作成してください。
異なる点は以下です。
- キーポリシーは以下のJsonを参考にし、以下2点は環境ごとに変更してください
- Principalにコピー元IAMロールのARN
- Resourceにコピー先KMSのARN
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS":"<コピー元のAWSアカウントで作成したIAMロールのARN>"
},
"Action": "kms:CreateGrant",
"Resource": "<設定しているKMSのARN>",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
},
{
"Sid": "Allow use of the key for S3 replication from Amazon Connect AWS Account",
"Effect": "Allow",
"Principal": {
"AWS": "<コピー元のAWSアカウントで作成したIAMロールのARN>"
},
"Action": [
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "<設定しているKMSのARN>"
}
]
}
- キーポリシーの設定後、「次へ」をクリック
- 確認画面が表示されるので、ページ右下の「完了」をクリック
2.2 コピー先AWSアカウントでS3バケットの作成
バージョニングを有効にしないと、レプリケーションルールを作成できません。
必ず有効にしてください。
基本的には「コピー元AWSアカウントでS3バケットの作成」と同様の手順で作成してください。
異なる点はバケットポリシーの設定です。
- バケット作成後、バケット名をクリック
- 上部にある「アクセス許可」をクリック
- バケットポリシーを編集し、以下のJSONを追加
{
"Version": "2012-10-17",
"Id": "S3-replication-bucket-policy",
"Statement": [
{
"Sid": "S3-replication-bucket-policy",
"Effect": "Allow",
"Principal": {
"AWS": "<コピー元のAWSアカウントで作成したIAMロールのARN>"
},
"Action": [
"s3:GetBucketVersioning",
"s3:List*",
"s3:PutBucketVersioning",
"s3:ReplicateObject",
"s3:ReplicateDelete",<オプション:削除マーカーのレプリケーションを有効化の際に必要>
"s3:ObjectOwnerOverrideToBucketOwner"
],
"Resource": [
"<コピー先のAWSアカウントで作成したS3のARN>",
"<コピー先のAWSアカウントで作成したS3のARN>/*"
]
}
]
}
3. コピー元AWSアカウントでの最終設定
3.1 コピー元AWSアカウントのKMSのポリシー修正
- コピー元のAWSアカウントで作成したKMSの画面を開く
- 左サイドバーのカスタマー管理型キーをクリックし、KMSの一覧を開く
- 作成したKMSのエイリアス名をクリックし、詳細画面を開く
- キーポリシーのタブをクリックし、編集を行う
コピー元KMS
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": {
"Sid": "Allow use of the key for S3 replication",
"Effect": "Allow",
"Principal": {
"AWS": "<コピー元のAWSアカウントで作成したIAMロールのARN>"
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "<設定しているKMSのARN>"
}
}
- kms:Decryptは暗号化されているS3の複合化に必要です
3.2 コピー元AWSアカウントのIAMロールの修正
- コピー元AWSアカウントのIAMのコンソール画面を開く
- ロールから先ほど作成したIAMロールを検索し、詳細を開く
- 「許可」のタブをクリック
- 「許可を追加」をクリックし、「インラインポリシーを作成」をクリック
- ポリシーエディターで「Json」を選択
- 以下のJsonを追加
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:GetReplicationConfiguration",
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging",
"s3:GetObjectRetention",<オプション:保持ポリシーを設定する場合>
],
"Effect": "Allow",
"Resource": [
"<コピー元のAWSアカウントで作成したS3バケットのARN>",
"<コピー元のAWSアカウントで作成したS3バケットのARN>/*"
]
},
{
"Action": [
"s3:ReplicateObject",
"s3:ReplicateTags",
"s3:GetObjectVersionTagging",
"s3:ObjectOwnerOverrideToBucketOwner",
"s3:ReplicateDelete"<オプション:削除マーカーのレプリケーションを有効化の際に必要>
],
"Effect": "Allow",
"Condition": {
"StringLikeIfExists": {
"s3:x-amz-server-side-encryption":"aws:kms"
}
},
"Resource": [
"<コピー先のAWSアカウントで作成したS3バケットのARN>/*"
]
},
{
"Action": [
"kms:Decrypt"
],
"Effect": "Allow",
"Condition": {
"StringLike": {
"kms:ViaService": "s3.ap-northeast-1.amazonaws.com",
"kms:EncryptionContext:aws:s3:arn": [
"<コピー元のAWSアカウントで作成したS3バケットのARN>",
"<コピー元のAWSアカウントで作成したS3バケットのARN>/*"
]
}
},
"Resource": [
"<コピー元のAWSアカウントで作成したKMSのARN>"
]
},
{
"Action": [
"kms:Encrypt"
],
"Effect": "Allow",
"Condition": {
"StringLike": {
"kms:ViaService": [
"s3.ap-northeast-1.amazonaws.com"
],
"kms:EncryptionContext:aws:s3:arn": [
"<コピー先のAWSアカウントで作成したS3バケットのARN>",
"<コピー先のAWSアカウントで作成したS3バケットのARN>/*"
]
}
},
"Resource": [
"<コピー先のAWSアカウントで作成したKMSのARN>"
]
}
]
}
3.3 S3のレプリケーションルール作成
- コピー元のAWSアカウントにあるS3バケットの詳細画面を開く
- 「管理」タブをクリック
- レプリケーションルールのセクションにある「レプリケーションルールを作成」をクリック
- レプリケーションルール名は任意のものを入力
- ステータスは、本記事では、有効
- ソースバケットは、必要があれば設定
- 送信先のセクションで「別のアカウントのバケットを指定する」を選択
- コピー先のAWSアカウントIdとバケット名を入力
- 送信先に「別のアカウントのバケットを指定する」を選択し、コピー先のAWSアカウントIDとバケット名を入力
- 本記事では、「オブジェクト所有者を送信先バケット所有者に変更」を有効
- IAMロールは、コピー元のAWSアカウントで作成したIAMロールを選択
- 暗号化のセクションにある「AWS Key Management Service (AWS KMS)で暗号化されたオブジェクトをレプリケートする」にチェック
-
「送信先オブジェクトを暗号化するためのAWS KMSキー」はコピー先のAWSアカウントで作成したKMSのARNを入力
-
送信先ストレージクラスは、必要があれば設定
- 追加のレプリケーションオプション
- 本記事では、「レプリケーションメトリクス」のみ有効
- レプリケーション時間のコントロール (RTC)
- レプリケーションを99.99%、15分以内に行うことを保証するものです
- 追加費用がかかります
- 有効にしない場合でも、1,2分でレプリケーションされることが多いと感じていますが、要件によっては選択してください
- 削除マーカーのレプリケーション
- こちらを有効化すると、コピー元が特定のオブジェクトを削除した場合、コピー先のオブジェクトも削除されます
- デフォルトでは、コピー元のオブジェクトを削除した場合でも、コピー先のオブジェクトは残ります
- レプリカ変更の同期
- こちらは、コピー先のS3のオブジェクトに変更があった場合に、コピー元のオブジェクトにも変更を反映するものです
- デフォルトでは、コピー元のオブジェクトの変更のみが、コピー先に反映されます
- 設定が完了したら、ページ右下の「保存」をクリック
検証ならびにメトリクス確認とログ出力
4. 検証
コピー元S3バケットにファイルをアップロードし、コピー先バケットにレプリケートされるか確認してください。
メトリクス確認およびエラー検知方法については次のセクションを参照してください。
4.1 S3レプリケーションのメトリクス確認方法
本記事では、S3のレプリケーションルールで「レプリケーションメトリクス」を有効化していますが、残念ながらこちらのメトリクスでは失敗した理由がわかりません。
なお、レプリケーションメトリクスの確認方法は以下の通りです。
-
画面下部に「レプリケーションメトリクス」とあるので、確認したいレプリケーションルールを選択し、「グラフを表示」をクリック
-
以下のメトリクスを確認することが可能
- レプリケーション保留中のオペレーション
- レプリケーションのレイテンシー
- レプリケーションを保留中のバイト数
- オペレーションが失敗したレプリケーション
4.2 ログを出力させる方法
レプリケーションに関するログ出力は、S3のイベント通知を使用するため、SNS,SQS,Lambdaを使用して、確認する必要があります。
なおバッチレプリケーションを使用した場合は、レポートで確認することができます。
本記事では、Lambdaを利用して、CloudWatchにエラー内容のログを出力させる方法を記載しています。
4.2.1 Lambdaの作成
- 該当のリージョンのLambdaコンソール画面を開き、左サイドバーの「関数」をクリック
- 右上の「関数を作成」をクリック
- 本記事では、Pythonを選択
- 画面右下の「関数を作成」をクリック
- 以下のコードをコピーし、「デプロイ」をクリック
- 本記事では、詳細なエラーハンドリングは行っておりません
- 必要に応じて、修正してください
import json
def lambda_handler(event, context):
# TODO implement
print("----event----")
print(event)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
4.2.2 S3のイベント通知設定
-
コピー元AWSアカウントで作成したS3バケット名をクリック
-
イベント名は任意のものを入力
-
「イベントタイプ」のセクションで、「レプリケーション」があるので、「すべてのレプリケーションイベント」にチェック
-
画面右下の「保存」をクリック
-
失敗時は、CloudWatchのロググループでLambdaのログを確認してください
-
例えば、以下のような失敗理由が表示されます
- レプリケーションの失敗理由については、以下の公式ドキュメントを参考にし、権限などを見直してください
まとめ
本記事では、クロスアカウントでのS3レプリケーション時に、それぞれのAWSアカウントでKMSを利用する際の手順について記載しました。
KMSはカスタマー管理型を使用し、S3バケットはバージョニングを有効が必須です。
加えて、レプリケーションが失敗した場合のログがレプリケーションルール自体では確認ができないため、別途用意する必要があります。
レプリケーションが標準機能としてあるのはとても便利ですが、いくつかポイントを知らないと、なぜかできないということになるので、実施前に要件や現状の設定を確認しましょう。