Aurora Serverless v2のスナップショットからプロビジョニングされたAuroraクラスターを CloudFormation で復元してみた

2024.03.31

はじめに

タイトルの通りとはなりますが、先日Aurora Serverless v2からプロビジョニングされたAuroraに移行する機会がありました。
Aurora Serverless v2は、ワークロードに応じて自動的にスケーリングするため、リソース管理の手間が省けるメリットがあります。
しかし、コストが割高になったり一部機能が使えない場合があります。
今回はCloudFormationを利用して、Auroraの移行(復元)をしていきたいと思います。

Aurora Serverless v2とプロビジョンドされたAuroraの比較

ざっくりとした比較は以下のようになっています。

項目 Aurora Aurora Serverless
インスタンスタイプ 定義されたインスタンスタイプから選択 自動でスケール可能なインスタンス
スケールの方法 手動 自動
ユースケース 安定的なワークロード 可変のワークロード
料金体系 インスタンス数とインスタンスタイプに応じた従量課金 使用時間とリソース量に応じた従量課金
1 インスタンスあたりの時間単価(メモリ 32GB の場合 : 2024 年 2 月時点) 0.7 USD (db.r5.xlarge) v1: 1.6 USD (16 ACU)v2: 3.2 USD (16 ACU)

引用:Amazon Aurora Serverless をグラレコで解説

Aurora Serverless v2の利用を考えている場合は、以下のドキュメントを確認しましょう。
いくつかの考慮点があります。

実際にやってみる

データベースの作成

まずはじめにAurora Serverless v2のスナップショットを取得します。
今回はスナップショットさえ取得できればいいので、基本的にデフォルト値のままデータベースを作成しました。

ダミーデータの投入

検証用にデータベースを作成しているので、念の為テストデータを投入しておきます。
データの作成は生成AIのClaude3にお願いしました。
実際の復元では、本手順は不要になります。

-- データベースの作成
CREATE DATABASE sample_db;
USE sample_db;

-- 従業員テーブルの作成
CREATE TABLE employees (
  employee_id INT AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(50) NOT NULL,
  last_name VARCHAR(50) NOT NULL,
  email VARCHAR(100) UNIQUE NOT NULL,
  hire_date DATE NOT NULL,
  job_title VARCHAR(50) NOT NULL,
  salary DECIMAL(10, 2) NOT NULL
);

-- 部門テーブルの作成
CREATE TABLE departments (
  department_id INT AUTO_INCREMENT PRIMARY KEY,
  department_name VARCHAR(100) NOT NULL,
  location VARCHAR(100) NOT NULL
);

-- 従業員と部門の関連テーブルの作成
CREATE TABLE employee_department (
  employee_id INT NOT NULL,
  department_id INT NOT NULL,
  PRIMARY KEY (employee_id, department_id),
  FOREIGN KEY (employee_id) REFERENCES employees(employee_id),
  FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

-- サンプルデータの挿入
INSERT INTO employees (first_name, last_name, email, hire_date, job_title, salary)
VALUES
  ('John', 'Doe', 'john.doe@example.com', '2020-01-01', 'Software Engineer', 80000.00),
  ('Jane', 'Smith', 'jane.smith@example.com', '2018-03-15', 'Product Manager', 90000.00),
  ('Michael', 'Johnson', 'michael.johnson@example.com', '2022-06-01', 'Data Analyst', 75000.00);

INSERT INTO departments (department_name, location)
VALUES
  ('Engineering', 'New York'),
  ('Marketing', 'Los Angeles'),
  ('Finance', 'Chicago');

INSERT INTO employee_department (employee_id, department_id)
VALUES
  (1, 1),
  (2, 2),
  (3, 1),
  (3, 3);

スナップショットの取得

続いてスナップショットを取得します。
今回はAuroraを使用しているので、クラスタースナップショットを取得します。
後ほどCloudFormation実行時にスナップショットのArnが必要になるので、控えておきましょう。

CloudFormationでの復元

CloudFormationは以下のコードを使用します。
パラメーターやオプション等は適宜追加してください。

rds.yaml

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  SystemName:
    Type: String

  Environment:
    Type: String

  DBInstanceClass:
    Type: String

  SnapshotIdentifier:
    Type: String

  SecurityGroupId:
    Type: String

  DBSubnetGroupName:
    Type: String

Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      SnapshotIdentifier: !Ref SnapshotIdentifier
      AvailabilityZones:
        - !Select
          - 1 # ap-northeast-1c
          - !GetAZs
            Ref: AWS::Region
        - !Select
          - 2 # ap-northeast-1d
          - !GetAZs
            Ref: AWS::Region
      BackupRetentionPeriod: 7
      DBClusterIdentifier: !Sub ${SystemName}-${Environment}-rds-cluster
      DBSubnetGroupName: !Ref DBSubnetGroupName
      Engine: aurora-mysql
      PreferredBackupWindow: 19:43-20:13
      PreferredMaintenanceWindow: thu:16:25-thu:16:55
      VpcSecurityGroupIds:
        - !Ref SecurityGroupId
      StorageEncrypted: true
      EngineVersion: 8.0.mysql_aurora.3.04.1
      EngineMode: provisioned
      DeletionProtection: true

  DBInstance01:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: !Sub ${SystemName}-${Environment}-rds-instance-01
      DBInstanceClass: !Ref DBInstanceClass
      Engine: aurora-mysql
      AvailabilityZone: !Select
        - 1 # ap-northeast-1c
        - !GetAZs
          Ref: AWS::Region
      PreferredMaintenanceWindow: sat:19:28-sat:19:58
      LicenseModel: general-public-license
      DBClusterIdentifier: !Ref DBCluster
      PromotionTier: 1
      EnablePerformanceInsights: true
      PerformanceInsightsRetentionPeriod: 7
      CACertificateIdentifier: rds-ca-rsa4096-g1

  DBInstance02:
    Type: AWS::RDS::DBInstance
    DependsOn: DBInstance01
    Properties:
      DBInstanceIdentifier: !Sub ${SystemName}-${Environment}-rds-instance-02
      DBInstanceClass: !Ref DBInstanceClass
      Engine: aurora-mysql
      AvailabilityZone: !Select
        - 2 # ap-northeast-1d
        - !GetAZs
          Ref: AWS::Region
      PreferredMaintenanceWindow: sat:19:28-sat:19:58
      LicenseModel: general-public-license
      DBClusterIdentifier: !Ref DBCluster
      PromotionTier: 1
      EnablePerformanceInsights: true
      PerformanceInsightsRetentionPeriod: 7
      CACertificateIdentifier: rds-ca-rsa4096-g1

デプロイには普段から愛用しているRainを使用します。

$ rain deploy rds.yaml test-rds
Deleted existing, empty stack.
Enter a value for parameter 'SystemName' "Please type System Name." (existing value: cm): 
Enter a value for parameter 'Environment' "Please type Environment Name." (existing value: test): 
Enter a value for parameter 'DBInstanceClass' (existing value: db.r6g.large): 
Enter a value for parameter 'DBSubnetGroupName': <masked>
Enter a value for parameter 'SecurityGroupId' (existing value: <masked>): 
Enter a value for parameter 'SnapshotIdentifier' (existing value: <masked>): 
CloudFormation will make the following changes:
Stack test-rds:
  + AWS::RDS::DBCluster DBCluster
  + AWS::RDS::DBInstance DBInstance01
  + AWS::RDS::DBInstance DBInstance02
Do you wish to continue? (Y/n) y
Deploying template 'rds.yaml' as stack 'test-rds' in ap-northeast-1.
Stack test-rds: CREATE_COMPLETE
Successfully deployed test-rds

無事デプロイが完了しました。

動作確認

EC2から両方のデータベースに接続して、テーブルを確認してみます。

Serverless v2

$ mariadb -u admin -p -h database-1.<masked>.ap-northeast-1.rds.amazonaws.com
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 119
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sample_db          |
| sys                |
+--------------------+
5 rows in set (0.002 sec)

MySQL [(none)]> USE sample_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MySQL [sample_db]> SHOW TABLES;
+---------------------+
| Tables_in_sample_db |
+---------------------+
| departments         |
| employee_department |
| employees           |
+---------------------+
3 rows in set (0.002 sec)

Provisioned

$ mariadb -u admin -p -h cm-test-rds-cluster.<masked>.ap-northeast-1.rds.amazonaws.com
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 109
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sample_db          |
| sys                |
+--------------------+
5 rows in set (0.001 sec)

MySQL [(none)]> USE sample_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MySQL [sample_db]> SHOW TABLES;
+---------------------+
| Tables_in_sample_db |
+---------------------+
| departments         |
| employee_department |
| employees           |
+---------------------+
3 rows in set (0.001 sec)

問題なく復元できていることが確認できました。

まとめ

CloudFormationを使って、Aurora Serverless v2のスナップショットからプロビジョニングされたAuroraを復元してみました。
Webコンソールのみで復元を行う場合は、以下のドキュメントを参考にしてみてください。