Multi-Region S3 Replication vti cloud

Amazon Simple Storage Service (hay còn gọi là Amazon S3) là một dịch vụ nổi tiếng của Amazon Web Services (AWS) để khách hàng có thể sử dụng để lưu trữ dữ liệu an toàn và đáng tin cậy. Sử dụng Amazon S3, doanh nghiệp sẽ có thể xây dựng một giải pháp lưu trữ chi phí thấp, nhưng khả dụng cao. Để xứng đáng với 11 số 9 (99.999999999%) về SLA, Amazon S3 cung cấp tính năng có sẵn để sao chép (replicate) sang một region khác, tính năng này cho phép dễ dàng sao lưu tự động nhiều region khác nhau (Multi-region S3 Replication).

Tổng Quan 

Bài viết dưới đây tham khảo một dự án AWS CDK (Cloud Development Kit) sử dụng TypeScript. Sử dụng AWS CDK cùng với AWS CloudFormation StackSets, khách hàng có thể triển khai các tài nguyên sau đây:

  • Amazon S3 Bucket trên region chính (primary region) với custom KMS key.
  • AWS CloudFormation StackSet để replicate các bản sang nhiều region khác nhau.
  • AWS IAM Role với quyền truy cập cho khu vực chính và các bản sao.

Điều thú vị là, bạn có thể triển khai những tài nguyên này trên những Region mong muốn (trong đó sẽ đáp ứng Multi-Region S3 Replication), CHỈ VỚI 01 DÒNG LỆNH DUY NHẤT!!!

Các bước tiến hành triển khai Multi-Region S3 Replication

Bước 1: Bắt buộc ban đầu

Để sử dụng StackSets tự quản lý (self-managed StackSets), trước tiên bạn cần tạo hai IAM roles. Bạn có thể tạo chúng theo cách thủ công bằng AWS Management Console hoặc sử dụng các template CloudFormation chính thức do AWS cung cấp, click vào để tải:

iam roles for cloudformation

Dự án này được lấy từ một Repository chứa template được đóng gói sẵn trên Github, link tại đây. Chỉ cần điều chỉnh một số thông số cho CloudFormation Stack là có thể sử dụng được.

// Configured ./aws/index.ts

const option = {
  env: {
    region: 'ap-southeast-1'
  },
  replications: [
    'ap-northeast-1',
    'ap-southeast-2',
    '...'
  ]
}

Sau đó, chạy bằng lệnh bên dưới để triển khai mọi thứ.

npx cdk deploy

Bước 2: Sửa thông số Primary Region và Data Source

Những thay đổi tới dữ liệu bên trong Amazon S3 bucket tại primary region được replicate sang những region khác của AWS, ví dụ ở đây region đang thực hiện là ap-southeast-1 (Singapore) và các region khác lần lượt là ap-northeast-1 (Tokyo) và ap-southeast-2 (Sydney).

Tại primary region, bạn cần có Amazon S3 bucket có custom KMS (Key Management System) key để mã hóa.

Tìm hiểu thêm về AWS KMS tại đây: https://aws.amazon.com/kms/.

import * as s3 from '@aws-cdk/aws-s3'
import * as kms from '@aws-cdk/aws-kms'

const key = new kms.Key(this, 'Key')
const alias = key.addAlias('archive')

const bucket = new s3.Bucket(this, 'Bucket', {
  bucketName: `${props.prefix}-archive`,
  encryption: s3.BucketEncryption.KMS,
  encryptionKey: alias,
  blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
  bucketKeyEnabled: true,
  versioned: true,
  removalPolicy: cdk.RemovalPolicy.RETAIN
})

Để sử dụng tính năng S3 bucket replication, bạn cần tạo IAM role với quyền permission để truy cập được dữ liệu trong Amazon S3 và sử dụng được KMS key:

import * as iam from '@aws-cdk/aws-iam'

const role = new iam.Role(this, 'ReplicationRole', {
  assumedBy: new iam.ServicePrincipal('s3.amazonaws.com'),
  path: '/service-role/'
});


role.addToPolicy(
  new iam.PolicyStatement({
    resources: [
      bucket.bucketArn
    ],
    actions: [
      's3:GetReplicationConfiguration',
      's3:ListBucket'
    ]
  })
);

role.addToPolicy(
  new iam.PolicyStatement({
    resources: [
      bucket.arnForObjects('*')
    ],
    actions: [
      's3:GetObjectVersion',
      's3:GetObjectVersionAcl',
      's3:GetObjectVersionForReplication',
      's3:GetObjectVersionTagging'
    ]
  })
);

role.addToPolicy(
  new iam.PolicyStatement({
    resources: [
      key.keyArn
    ],
    actions: [
      'kms:Decrypt'
    ]
  })
);

Sau khi hoàn tất các bước trên, công đoạn tiếp theo là tạo một Amazon S3 bucket với KMS key có thể sử dụng trong mọi region mà bạn muốn replicate, ở đây cấu hình KMS key trong region ap-northeast-1 (Tokyo) và ap-southeast-2 (Sydney).

Bước 3: Tạo CloudFormation StackSet cho Multi-Region S3 Replication

Để tránh trường hợp phải tạo từng CloudFormation Stack tại từng region bạn muốn replicate dữ liệu Amazon S3 bucket, AWS CloudFormation StackSet được sử dụng để tự động hóa công đoạn triển khai từ region. Hiện tại, AWS CDK chỉ hỗ trợ quyền truy cập thấp (low-level access) vào tài nguyên CloudFormation StackSet:

import * as cdk from '@aws-cdk/core'

new cdk.CfnStackSet(this, "StackSet", {
  stackSetName: `${props.prefix}-archive-replication`,
  permissionModel: "SELF_MANAGED",
  parameters: [
    {
      parameterKey: 'Prefix',
      parameterValue: props.prefix
    },
    {
      parameterKey: 'ReplicationRole',
      parameterValue: role.roleArn
    }
  ],
  stackInstancesGroup: [
    {
      regions: props.replications,
      deploymentTargets: {
        accounts: [AccountId],
      },
    },
  ],
  templateBody:templateReplicationData,  #đây là template chứa Amazon S3 và KMS cho mọi region
});

Thông số ReplicationRole là bắt buộc để cấp quyền truy cập vào KMS key theo vùng mà IAM role sử dụng để thực hiện công đoạn replication.

Parameters:
  Prefix:
    Type: String
  ReplicationRole:
    Type: String

Resources:
  Key:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Version: 2012-10-17
        Id: access-account
        Statement:
          - Sid: Enable IAM User Permissions
            Effect: Allow
            Principal:
              AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
            Action: kms:*
            Resource: '*'
          - Sid: Replication
            Effect: Allow
            Principal:
              AWS: !Ref ReplicationRole
            Action:
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
              - kms:DescribeKey
            Resource: '*'

  KeyAlias:
    Type: AWS::KMS::Alias
    Properties:
      AliasName: alias/archive/replication
      TargetKeyId: !Ref Key

  Bucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    Properties:
      BucketName: !Sub ${Prefix}-archive-replication-${AWS::Region}
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: Yes
        BlockPublicPolicy: Yes
        IgnorePublicAcls: Yes
        RestrictPublicBuckets: Yes
      VersioningConfiguration:
        Status: Enabled
      BucketEncryption:
        ServerSideEncryptionConfiguration:
        - BucketKeyEnabled: Yes
          ServerSideEncryptionByDefault:
            SSEAlgorithm: aws:kms
            KMSMasterKeyID: !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:${KeyAlias}

Tài nguyên AWS trong region được replicate sử dụng những name pattern riêng để phân biệt, ví dụ ap-northeast-1 trong cấu hình sau:

  • KMS Key
    arn:aws:kms:ap-northeast-1:11223344:alias/archive/replication
  • S3 Bucket
    arn:aws:s3:::prefix-archive-replication-ap-northeast-1

Sử dụng name pattern này, bạn có thể mở rộng IAM role sử dụng cho các region replication từ role tại primary region:role.addToPolicy(

  new iam.PolicyStatement({
    resources: props.replications.map(
      region => `arn:aws:kms:${region}:$(AccountId):alias/archive/replication`
    ),
    actions: [
      'kms:Encrypt'
    ]
  })
);

role.addToPolicy(
  new iam.PolicyStatement({
    resources: props.replications.map(
      region => `arn:aws:s3:::${props.prefix}-archive-replication-${region}/*`
    ),
    actions: [
      's3:ReplicateDelete',
      's3:ReplicateObject',
      's3:ReplicateTags'
    ]
  })
);

role.addToPolicy(
  new iam.PolicyStatement({
    resources: props.replications.map(
      region => `arn:aws:s3:::${props.prefix}-archive-replication-${region}`
    ),
    actions: [
      's3:List*',
      's3:GetBucketVersioning',
      's3:PutBucketVersioning'
    ]
  })
);

Bước 4: Cấu hình Multi-Region S3 Replication 

Thiết lập S3 Replication Configuration tại Amazon S3 bucket tại vị trí chính (primary region). Ở bước này, AWS CDK vẫn có thể sử dụng những object low-level để cấu hình replication:

const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;

cfnBucket.replicationConfiguration = {
  role: role.roleArn,
  rules: props.replications.map(
    (region, index) => (
      {
        id: region,
        destination: {
          bucket: `arn:aws:s3:::${props.prefix}-archive-replication-${region}`,
          encryptionConfiguration: {
            replicaKmsKeyId: `arn:aws:kms:${region}:${AccountID}:alias/archive/replication`
          }
        },
        priority: index,
        deleteMarkerReplication: {
          status: 'Enabled'
        },
        filter: {
          prefix: ''
        },
        sourceSelectionCriteria: {
          sseKmsEncryptedObjects: {
            status: 'Enabled'
          }
        },
        status: 'Enabled'
      }
    )
  )
}

Bước 5: Triển khai

Như đã nói ở trên, sau khi chạy bằng lệnh bên dưới, mọi thứ sẽ được triển khai.npx cdk deploy

Tổng Kết

Chỉ với AWS Cloud Development Kit, bạn có thể tạo ra AWS CloudFormation template.

Từ template này, bạn tạo được AWS CloudFormation Stack. Stack này sẽ giúp bạn triển khai các dịch vụ như Amazon S3 bucket, AWS Identity & Access Management role, an AWS Key Management Service key và 01 AWS CloudFormation StackSet.

AWS CloudFormation StackSet sau đó sử dụng template ở trên để tạo AWS CloudFormation Stack cho các region khác nhau, và Stack này lại tiếp tục được dùng để tạo các tài nguyên như S3 bucket, IAM role và KMS key, trong đó Amazon S3 bucket có tính năng S3 Replication Configuration.