1. はじめに

今回は、S3の同一リージョンレプリケーションについて学んでみました。

S3には、クロスリージョンレプリケーション(CRR), 同一リージョンレプリケーション(SRR)の二種類のレプリケーション方式があります。 2つのレプリケーションは名前の通り、CRRはリージョン間でS3のオブジェクトのコピーを行い、SRRは同一リージョン内でS3オブジェクトのコピーを行うことをいいます。

今回この記事を書こうとしたきっかけは、いまいちユースケースが思いつかなかったためです。

なのでドキュメントを読んでユースケースを書いていこうと思います。

2. 構成図

図の左:同一リージョンレプリケーション(SRR)、図の右:クロスリージョンレプリケーション

構成図

3. 同一リージョンレプリケーションとは(SRR)?

同一リージョンレプリケーション(SRR)とは、同じAWSリージョン内のS3バケット間でオブジェクトを自動的にコピーする機能です。

4. 同一リージョンレプリケーション(SRR)のユースケース

同一リージョンレプリケーションはどのようなユースケースで利用されるのでしょうか?

4.1. ログの集約

1つ目のユースケースは、複数のバケットや複数のアカウントにログを保管している場合、ログを簡単にコピーすることができます。

そうすることによって、ログの管理をシンプルにすることができます。

4.2. 本番稼働アカウントとテストアカウント間のライブレプリケーション

2つ目のユースケースは、アプリケーションの開発・検証中に本番環境のS3バケットのデータで検証を行いたいケースがあります。

同一リージョンレプリケーションを利用することによって、本番環境アカウントのS3バケットのデータを開発アカウントのS3バケットにコピーすることで、 開発・検証中に本番相当のデータを利用できるようになります。

4.3. データ主権に準拠する必要がある場合

S3のバックアップを遠隔地保管したいケースがあります。この場合、国外のリージョンへの保管を検討することがあるともいます。

しかし、法律やコンプライアンスの規制によりデータを国外のリージョンに保管できないケースがあります。

この場合、同一リージョンの別アカウントにS3のデータをコピーするケースがあります。

5. SRRの便利機能

5.1. S3 Replication Time Control

S3 Replication Time Control (S3 RTC) という機能があります。この機能を利用すると99.9%のオブジェクトが15分以内にコピーすることができます。

この機能は、ビジネス要件で15分以内にコピーを完了させる必要がある場合、利用されることがあります。

6. レプリケーションでコピーされる設定・コピーされない設定

6.1. レプリケーションでコピーされるもの

レプリケーション設定でコピーされる項目を一部列挙します。

  • レプリケーション設定の追加後に作成されたオブジェクト
  • 暗号化されていないオブジェクト
  • ユーザー提供のキー (SSE-C) を使用して暗号化されたオブジェクト、Amazon S3 マネージドキー (SSE-S3) の下で保管時に暗号化されたオブジェクト、および AWS Key Management Service (SSE-KMS) に保存されている KMS キーで暗号化されたオブジェクト
  • レプリケート元オブジェクトからレプリカへのオブジェクトメタデータ
    • 作成日、更新日付等
  • オブジェクトタグ、存在する場合。
  • S3 オブジェクトロックの保持情報

6.1. レプリケーションでコピーされないもの

レプリケーション設定前のオブジェクトはレプリケーション先にコピーされません。 もしコピーした場合は、別途レプリケーションを実行する必要があります。

以下は、私が勘違いしていたことです。 以前、バケットのライフサイクルルールもコピーされるのではと思っていましたが、 ライフサイクルルールは、バケットに対する設定なので、レプリケーションはコピーされません。 あくまでも、レプリケーションはオブジェクトのコピーを行う機能だからです。

これに関しては、私以外に勘違いする人はいないと思いますが。。

7. CDK参考コード(同一リージョンレプリケーション)

lib/s3_replication-stack.ts

import * as cdk from 'aws-cdk-lib';
import { S3ReplicationStack } from '../lib/s3_replication-stack';

const app = new cdk.App();

const project = "cdk-replication";

new S3ReplicationStack(app, "S3ReplicationStack", {
  projectName: project,
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
  },
});
bin/s3_replication.ts

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

export interface S3ReplicationStackProps extends cdk.StackProps {
  readonly projectName: string; 
}

export class S3ReplicationStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: S3ReplicationStackProps) {
    super(scope, id, props);

    const projectName = props.projectName.toLowerCase();
    const region = props.env?.region;
    const account = props.env?.account;
    const sourceBucketId = `${projectName}-SourceBucket`;
    
    const destinationBucketId = `${projectName}-DestinationBucket`;

     const destinationBucket = new s3.Bucket(this, destinationBucketId, {
      versioned: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true,      
      bucketName: `${projectName}-destination-bucket-${region}-${account}`.toLowerCase(),
    });

    const sourceBucket = new s3.Bucket(this, sourceBucketId, {
      versioned: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
      bucketName: `${projectName}-source-bucket-${region}-${account}`.toLowerCase(),
      replicationRules: [
        {
          destination: destinationBucket,
          priority: 1
        },
      ],
    });

    new cdk.CfnOutput(this, 'SourceBucketName', {
      value: sourceBucket.bucketName,
      description: 'The name of the source S3 bucket',
    });

    new cdk.CfnOutput(this, 'DestinationBucketName', {
      value: destinationBucket.bucketName,
      description: 'The name of the destination S3 bucket',
    });
  }
}

8. まとめ

SRRのレプリケーションはバックアップの意味合いが強いと個人的に考えてきましたが、ログの集約をすることでログ管理の簡素化やコンプライアンスを満たすための機能があると理解しました。

今後の設計業務に活かしていきたいと思います。

9. 参考ページ