😺
複数のS3バケットへのレプリケーションをCloudFormationで設定しようとして躓いた話
概要
CloudFormation(実際はCDK)を使い、1つのS3バケットに対して複数のバケットへレプリケーションする設定をしようとして躓いた際の記録です。
事象
以下のようなCloudFormationテンプレート(一部抜粋)でデプロイしようとしたところ
{
"Resources": {
"S3ReplicationBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"ReplicationConfiguration": {
"Role": {
"Fn::GetAtt": [
"S3ReplicationRole",
"Arn"
]
},
"Rules": [
{
"Destination": {
"Bucket": "arn:aws:s3:::s3replicationdest1bucket"
},
"Id": "Rule1",
"Status": "Enabled"
},
{
"Destination": {
"Bucket": "arn:aws:s3:::s3replicationdest2bucket"
},
"Id": "Rule2",
"Status": "Enabled"
}
]
},
"VersioningConfiguration": {
"Status": "Enabled"
}
},
},
}
}
スタックで以下のようなエラーが発生してデプロイに失敗しました。
Number of distinct destination bucket ARNs cannot exceed 1
原因
Amazon S3はレプリケーション設定をXML形式で保存しています。
レプリケーション設定のXMLの最新バージョンはV2で、下位互換性のために引き続きXML V1のレプリケーション設定をサポートしています。
レプリケーション先を複数設定するには、ReplicationRulesにV2スキーマを使う必要があります。
ですが、上記テンプレートだとCloudFromationはV1スキーマでレプリケーションを設定するためエラーになってしまうようです。
解決方法
各ルールのFilterプロパティを指定することでReplicationRulesでV2スキーマを使用するよう強制することができるようです。
また、Filterプロパティを指定する場合は、PriorityプロパティとDeleteMarkerReplicationプロパティも含める必要があります。
以上を踏まえたテンプレート(例)は以下のようになります。
{
"Resources": {
"S3ReplicationBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"ReplicationConfiguration": {
"Role": {
"Fn::GetAtt": [
"S3ReplicationRole",
"Arn"
]
},
"Rules": [
{
"DeleteMarkerReplication": {
"Status": "Enabled"
},
"Destination": {
"Bucket": "arn:aws:s3:::s3replicationdest1bucket"
},
"Id": "Rule1",
"Status": "Enabled",
+ "Filter": {},
+ "Priority": 0
},
{
"DeleteMarkerReplication": {
"Status": "Enabled"
},
"Destination": {
"Bucket": "arn:aws:s3:::s3replicationdest2bucket"
},
"Id": "Rule2",
"Status": "Enabled",
+ "Filter": {},
+ "Priority": 1
}
]
},
"VersioningConfiguration": {
"Status": "Enabled"
}
},
},
}
}
参考
Discussion