Multi-AZ DB Cluster RDS Using CFN

Multi-AZ DB Cluster RDS Using CloudFormation. AWS_EN

Using CloudFormation to Create an RDS with a Multi-AZ DB Cluster Configuration

The following page covers multi-AZ deployment.

Multi-AZ DB clusters were released in March 2022.

A Multi-AZ DB cluster deployment is a high availability deployment mode of Amazon RDS with two readable standby DB instances.

Multi-AZ DB cluster deployments

In this page, we will create a multi-AZ DB cluster using CloudFormation.


Diagram of Multi-AZ DB Cluster RDS Using CloudFormation.

Create a multi-AZ DB cluster.
The cluster will be MySQL type.

Create an EC2 instance.
Use it as a client to connect to the DB cluster.
The instance is the latest version of Amazon Linux 2.

Create two types of VPC endpoints.

The first is for SSM.
This is to connect to an EC2 instance in a private subnet using SSM Session Manager.

The second is for S3.
This is for accessing yum repositories built on the S3 bucket.

CloudFormation template files

The above configuration is built with CloudFormation.
The CloudFormation templates are located at the following URL

awstut-fa/112 at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

Explanation of key points of the template files


DB Subnet Group

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 subnet group.
The point is the number of subnets to associate.

The DB subnet group that you choose for the DB cluster must cover at least three Availability Zones. This configuration ensures that each DB instance in the DB cluster is in a different Availability Zone.

Creating a Multi-AZ DB cluster

Follow the citation above and set up three subnets in the subnet group.

DB Cluster

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)

Points will be covered.

Storage type is point.

Multi-AZ DB clusters only support Provisioned IOPS storage.

Limitations for Multi-AZ DB clusters

Follow the quote above and specify “io1” for the StorageType property.

The storage and IOPS to be allocated are also important.
According to the official AWS page, for MySQL type, the possible values for both parameters are as follows

  • Storage: 100 GiB – 64 TiB
  • Provisioned IOPS: 1,000-256,000 IOPS

So this time we specify “100 (GiB)” for the AllocatedStorage property and “1000 (IOPS)” for the Iops property.

Specify the instance class in DBClusterInstanceClass.
The instance classes that can be specified for a multi-AZ DB cluster are “db.m6gd” or “db.m5d”.
Therefore, we will specify “db.m6gd.large,” which is the smallest size of the former.

Specify the engine type of the DB cluster to be created in the Engine and EngineVersion properties.
Multi-AZ DB clusters support two types of DB engines.

Multi-AZ DB clusters are supported only for the MySQL and PostgreSQL DB engines.

Creating a Multi-AZ DB cluster

As quoted above, specify “mysql” for the former and “8.0.28” for the latter.

(Reference) EC2 instance

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)

To access a DB instance from an EC2 instance, a client package must be prepared.
In this case, we will use user data to install the package.

For more information on user data, see the following page

For more information about client packages to connect to various RDS from Amazon Linux 2, please refer to the following page


Use CloudFormation to build this environment and check the actual behavior.

Create a CloudFormation stacks and check the resources in the stacks

Create CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following page

After checking the resources in each stack, information on the main resources created this time is as follows

  • EC2 instance: i-0c11a6ebbe7a679c
  • DB cluster: fa-112-dbcluster
  • Endpoint for writing DB cluster:
  • DB cluster read endpoint:

Check each resource from the AWS Management Console.

Check the DB cluster.

Detail of RDS 1.

The DB cluster has been successfully created.
Three DB instances have been created in the cluster, one in each of the three AZs.
You can also see that instance 1 is for writing and the other two instances (instance 2 and instance 3) are for reading.

We can also see that two types of endpoints are prepared.
One is for writing and the other is for reading.

We also check the configuration details.

Detail of RDS 2.

The instance class, storage, IOPS, etc. are set as specified in the CloudFormation template.

Checking the Action

Connect to the DB cluster

Connect to the primary instance from an EC2 instance.
Use SSM Session Manager to access the EC2 instance.

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

For more information on SSM Session Manager, please see the following page

Name resolution for two types of endpoints in a DB cluster.

sh-4.2$ nslookup Server: Address: Non-authoritative answer: canonical name = Name: Address: sh-4.2$ nslookup Server: Address: Non-authoritative answer: canonical name = Name: Address:
Code language: Bash (bash)

From the name resolution status, we can see that the endpoint for writing can connect to instance 1 and the endpoint for reading can connect to instance 3.

Check the execution status of the EC2 instance initialization process by user data.

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)

You will see that the MySQL client package has been successfully installed.

Use this client package to connect to the write endpoint.

sh-4.2$ mysql -h -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)

The connection has been made.

Create a test table and save test data.

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)

It worked fine.

Next, connect to the read endpoint.

sh-4.2$ mysql -h -P 3306 -u testuser -D testdb -p ... MySQL [testdb]>
Code language: Bash (bash)

This connection was also successful.

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)

The read was successful.
The contents written to instance 1, the primary instance, are also reflected in instance 3, the read replica.

On the other hand, write failed.
This is because instance 3 is a read-only instance.


Normally, when a write instance stops, it automatically fails over to the read instance.
In this case, we will use the AWS CLI to manually failover.

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

Check the status of the DB cluster again.

Detail of RDS 3.

The failover resulted in instance 3 becoming a writer instance and the other two instances becoming reader instances.

The event log shows that instance 3 has been promoted to writer.

Once again, we also check the name resolution status of each endpoint.

sh-4.2$ nslookup Server: Address: Non-authoritative answer: canonical name = Name: Address: sh-4.2$ nslookup Server: Address: Non-authoritative answer: canonical name = Name: Address:
Code language: Bash (bash)

We can see that the write endpoint can connect to instance 3 and the read endpoint can connect to instance 1.


We have created a Multi-AZ DB Cluster using CloudFormation.