CFNでマルチAZ DBクラスターRDSを作成する

CloudFormationを使用して、マルチAZ DBクラスター構成のRDSを作成する

以下のページで、マルチAZ配置を取り上げました。

あわせて読みたい
CFNでマルチAZ配置のRDSを作成する 【CloudFormationを使用して、マルチAZ配置のRDSを作成する】 RDSが提供する機能の1つにマルチAZ配置があります。 Amazon RDS マルチ AZ 配置では、Amazon RDS はプライ...

2022年3月にマルチAZ DBクラスターがリリースされました。

あるマルチ AZ DB クラスターの配置は、2 つの読み取り可能なスタンバイ DB インスタンスを持つ Amazon RDS の高可用性の配置モードです。

マルチ AZ DB クラスター配置

本ページでは、CloudFormationを使用して、マルチAZ DBクラスターを作成します。

構築する環境

Diagram of Multi-AZ DB Cluster RDS Using CloudFormation.

マルチAZ DBクラスターを作成します。
クラスターはMySQLタイプとします。

EC2インスタンスも作成します。
DBクラスターに接続するクライアントとして使用します。
インスタンスは最新版のAmazon Linux 2です。

2種類のVPCエンドポイントを作成します。

1つ目はSSM用です。
SSM Session Managerを使用して、プライベートサブネット内のEC2インスタンスに接続するためです。

2つ目はS3用です。
S3バケット上に構築されたyumリポジトリにアクセスするためです。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/112

テンプレートファイルのポイント解説

RDS

DBサブネットグループ

Resources:
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupName: !Sub "${Prefix}-dbsubnetgroup"
      DBSubnetGroupDescription: Test DB SubnetGroup.
      SubnetIds:
        - !Ref DBSubnet1
        - !Ref DBSubnet2
        - !Ref DBSubnet3
Code language: YAML (yaml)

RDSのサブネットグループです。
ポイントは関連付けるサブネット数です。

DB クラスターで選択する DB サブネットグループは、少なくとも 3つのアベイラビリティーゾーンを対象とする必要があります。この設定により、DB クラスターの各 DB インスタンスが別のアベイラビリティーゾーンに配置されます。

マルチ AZ DB クラスターの作成

上記の引用に従い、サブネットグループに3つのサブネットを設定します。

DBクラスター

Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    DeletionPolicy: Delete
    Properties:
      AllocatedStorage: !Ref DBAllocatedStorage
      AutoMinorVersionUpgrade: true
      DatabaseName: !Ref DBName
      DBClusterIdentifier: !Sub "${Prefix}-dbcluster"
      DBClusterInstanceClass: !Ref DBClusterInstanceClass
      DBClusterParameterGroupName: !Ref DBClusterParameterGroup
      DBSubnetGroupName: !Ref DBSubnetGroup
      Engine: !Ref DBEngine
      EngineVersion: !Ref DBEngineVersion
      Iops: !Ref DBIops
      MasterUsername: !Ref DBMasterUsername
      MasterUserPassword: !Ref DBMasterUserPassword
      Port: !Ref DBPort
      StorageType: io1
      VpcSecurityGroupIds:
        - !Ref DBSecurityGroup
Code language: YAML (yaml)

ポイントを取り上げます。

ストレージのタイプはポイントです。

マルチ AZ DB クラスターは、プロビジョンド IOPS ストレージのみをサポートします。

マルチ AZ DB クラスターの制限事項

上記の引用に従い、StorageTypeプロパティに「io1」を指定します。

確保するストレージとIOPSもポイントです。
AWS公式ページによりますと、MySQLタイプの場合、両パラメータの取り得る値は以下の通りです。

  • ストレージ:100 GiB – 64 TiB
  • プロビジョンドIOPS:1,000-256,000 IOPS

ですから今回はAllocatedStorageプロパティに「100(GiB)」を、Iopsプロパティに「1000(IOPS)」を指定します。

DBClusterInstanceClassでインスタンスクラスを指定します。
マルチAZ DBクラスターで指定可能なインスタンスクラスは「db.m6gd」または「db.m5d」です。
ですから今回は前者の最小サイズの「db.m6gd.large」を指定します。

EngineおよびEngineVersionプロパティで、作成するDBクラスターのエンジンタイプを指定します。
マルチAZ DBクラスターは2種類のDBエンジンをサポートしています。

マルチ AZ DB クラスターは MySQL および PostgreSQL DB エンジンでのみサポートされます。

マルチ AZ DB クラスターの作成

上記の引用にしたが、前者に「mysql」を、後者に「8.0.28」を指定します。

(参考) EC2インスタンス

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref InstanceSubnet
          GroupSet:
            - !Ref InstanceSecurityGroup
      UserData: !Base64 |
        #!/bin/bash -xe
        yum update -y
        yum install -y mariadb
Code language: YAML (yaml)

EC2インスタンスからDBインスタンスにアクセスするために、クライアントパッケージを準備する必要があります。
今回はユーザデータを使用して、パッケージをインストールします。

ユーザデータに関する詳細については、以下のページをご確認ください。

あわせて読みたい
Linuxインスタンスの初期化方法4選 【Linuxインスタンスを初期化する4つの方法】 EC2インスタンスの起動時に初期化処理を実行する方法を考えます。 EC2インスタンスを構築時に初期化する以下の4つの手法を...

Amazon Linux 2から各種RDSに接続するためのクライアントパッケージについては、以下のページをご確認ください。

あわせて読みたい
AL2で全RDSに接続する方法まとめ 【Amazon Linux 2からRDSの全DBエンジンに接続する方法】 2022年現在、RDSは以下の7種類のDBエンジンを提供しています。 Aurora(PostgreSQL) Aurora(MySQL) PostgreSQL ...

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • EC2インスタンス:i-0c11a6ebbe7a679c
  • DBクラスター:fa-112-dbcluster
  • DBクラスターの書き込み用エンドポイント:fa-112-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
  • DBクラスターの読み込み用エンドポイント:fa-112-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com

AWS Management Consoleから各リソースを確認します。

DBクラスターを確認します。

Detail of RDS 1.

正常にDBクラスターが作成されています。
クラスター内に3つのDBインスタンスが3つのAZに1つずつ作成されています。
インスタンス1が書き込み用で、残り2つのインスタンス(インスタンス2およびインスタンス3)が読み込み用であることもわかります。

エンドポイントも2種類用意されていることがわかります。
一方が書き込み用、もう一方が読み込み用です。

設定の詳細も確認します。

Detail of RDS 2.

インスタンスクラスやストレージ・IOPS等が、CloudFormationテンプレートで指定した通りに設定されています。

動作確認

DBクラスターに接続

EC2インスタンスからプライマリインスタンスに接続します。
EC2インスタンスへのアクセスはSSM Session Managerを使用します。

% aws ssm start-session --target i-0c11a6ebbe7a67b9c
...
sh-4.2$
Code language: Bash (bash)

SSM Session Managerの詳細につきましては、以下のページをご確認ください。

あわせて読みたい
LinuxインスタンスにSSM Session Manager経由でアクセスする 【LinuxインスタンスにSSM Session Manager経由でアクセスする】 EC2インスタンスにSSM Session Manager経由でアクセスする構成を確認します。 Session Manager は完全...

DBクラスターの2種類のエンドポイントの名前解決を行います。

sh-4.2$ nslookup fa-112-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Server:		10.0.0.2
Address:	10.0.0.2#53

Non-authoritative answer:
fa-112-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com	canonical name = fa-112-dbcluster-instance-1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com.
Name:	fa-112-dbcluster-instance-1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Address: 10.0.2.137

sh-4.2$ nslookup fa-112-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Server:		10.0.0.2
Address:	10.0.0.2#53

Non-authoritative answer:
fa-112-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com	canonical name = fa-112-dbcluster-instance-3.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com.
Name:	fa-112-dbcluster-instance-3.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Address: 10.0.3.101
Code language: Bash (bash)

名前解決状況から、書き込み用エンドポイントはインスタンス1に、読み込み用エンドポイントはインスタンス3に接続できることがわかります。

ユーザーデータによるEC2インスタンスの初期化処理の実行状況を確認します。

sh-4.2$ sudo yum list installed | grep mariadb
mariadb.aarch64                       1:5.5.68-1.amzn2                 @amzn2-core
mariadb-libs.aarch64                  1:5.5.68-1.amzn2                 installed

sh-4.2$ mysql -V
mysql  Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (aarch64) using readline 5.1
Code language: Bash (bash)

正常にMySQLクライアントパッケージがインストールされていることがわかります。

このクライアントパッケージを使用して、書き込み用エンドポイントに接続します。

sh-4.2$ mysql -h fa-112-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com -P 3306 -u testuser -D testdb -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
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 [testdb]>
Code language: Bash (bash)

接続できました。

試しにテスト用テーブルを作成し、テストデータを保存します。

MySQL [testdb]> CREATE TABLE planet (id INT UNSIGNED AUTO_INCREMENT, name VARCHAR(30), PRIMARY KEY(id));

MySQL [testdb]> INSERT INTO planet (name) VALUES ("Mercury");

MySQL [testdb]> select * from planet;
+----+---------+
| id | name    |
+----+---------+
|  1 | Mercury |
+----+---------+
Code language: Bash (bash)

正常に動作しました。

次に読み込み用エンドポイントに接続します。

sh-4.2$ mysql -h fa-112-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com -P 3306 -u testuser -D testdb -p
...
MySQL [testdb]>
Code language: Bash (bash)

こちらも正常に接続できました。

MySQL [testdb]> select * from planet;
+----+---------+
| id | name    |
+----+---------+
|  1 | Mercury |
+----+---------+

MySQL [testdb]> INSERT INTO planet (name) VALUES ("Venus");
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
Code language: Bash (bash)

読み込みは成功しました。
プライマリインスタンスであるインスタンス1に書き込んだ内容が、リードレプリカであるインスタンス3にも反映されています。

一方で、書き込みには失敗しました。
これはインスタンス3が読み込み専用であるためです。

フェイルオーバー

通常、書き込み用インスタンスが停止した場合、自動的に読み込み用インスタンスにフェイルオーバーします。
今回はAWS CLIを使用して、手動でフェイルオーバーさせます。

$ aws rds failover-db-cluster \
--db-cluster-identifier fa-112-dbcluster
Code language: Bash (bash)

改めてDBクラスターの状況を確認します。

Detail of RDS 3.

フェイルオーバーによって、インスタンス3がライターインスタンスに、残りの2台がリーダーインスタンスになりました。

イベントログを見ても、インスタンス3がライターに昇格したことがわかります。

もう一度、各エンドポイントの名前解決状況も確認します。

sh-4.2$ nslookup fa-112-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Server:		10.0.0.2
Address:	10.0.0.2#53

Non-authoritative answer:
fa-112-dbcluster.cluster-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com	canonical name = fa-112-dbcluster-instance-3.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com.
Name:	fa-112-dbcluster-instance-3.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Address: 10.0.3.101

sh-4.2$ nslookup fa-112-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Server:		10.0.0.2
Address:	10.0.0.2#53

Non-authoritative answer:
fa-112-dbcluster.cluster-ro-cl50iikpthxs.ap-northeast-1.rds.amazonaws.com	canonical name = fa-112-dbcluster-instance-1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com.
Name:	fa-112-dbcluster-instance-1.cl50iikpthxs.ap-northeast-1.rds.amazonaws.com
Address: 10.0.2.137
Code language: Bash (bash)

書き込み用エンドポイントはインスタンス3に、読み込み用エンドポイントはインスタンス1に接続できることがわかります。

まとめ

CloudFormationを使用して、マルチAZ DBクラスターを作成しました。