Skip to main content

RDS Cluster Multi-AZ Deployment

Overview

This check verifies whether your Amazon RDS DB clusters are deployed in a Multi-AZ (Multi-Availability Zone) configuration. Multi-AZ DB clusters automatically maintain two readable standby instances in different Availability Zones, providing automatic failover and the ability to serve read traffic from the standbys.

Risk

Without Multi-AZ protection, your RDS cluster is vulnerable to single points of failure:

  • Extended downtime: If the Availability Zone hosting your database experiences an outage, your database becomes unavailable until the zone recovers or you manually restore from a backup.
  • No automatic failover: RDS cannot automatically fail over to a standby in another zone because no standby exists.
  • Data loss risk: Transactions that occurred since your last backup may be lost.
  • SLA violations: Unplanned downtime can breach service-level agreements with your customers.

Remediation Steps

Prerequisites

  • Access to the AWS Console with permissions to create or modify RDS clusters
  • A DB subnet group that spans at least three Availability Zones
Important considerations before enabling Multi-AZ
  • Supported engines: Multi-AZ DB clusters are supported for MySQL (8.0.28 and higher) and PostgreSQL (13.4 and higher).
  • Cost impact: Multi-AZ DB clusters include two reader instances, which increases costs compared to a single-instance deployment.
  • Instance class requirements: Multi-AZ DB clusters require specific instance classes (e.g., db.r6gd, db.r6g, db.m6g families) with local NVMe storage for some configurations.
  • Storage requirements: Multi-AZ DB clusters require Provisioned IOPS (io1) storage.
  • Cannot convert existing clusters: You cannot convert an existing single-AZ DB cluster to Multi-AZ. You must create a new Multi-AZ cluster and migrate your data.

AWS Console Method

Creating a new Multi-AZ DB Cluster:

  1. Open the Amazon RDS console.
  2. In the left navigation, click Databases.
  3. Click Create database.
  4. Select Standard create.
  5. Under Engine options, select MySQL or PostgreSQL.
  6. Under Availability and durability, select Multi-AZ DB cluster.
  7. In Settings, enter a DB cluster identifier (e.g., my-multiaz-cluster).
  8. Configure your credentials (use AWS Secrets Manager for production).
  9. Under Instance configuration, select a supported instance class (e.g., db.r6gd.large).
  10. Configure storage settings:
    • Storage type: Provisioned IOPS (io1)
    • Allocated storage: 100 GiB minimum recommended
    • Provisioned IOPS: 1000 or higher
  11. Select your VPC, DB subnet group, and Security groups.
  12. Review your settings and click Create database.

Migrating from a single-AZ cluster:

Since you cannot directly convert an existing cluster to Multi-AZ, you need to:

  1. Create a snapshot of your existing cluster
  2. Restore the snapshot to a new Multi-AZ DB cluster
  3. Update your applications to use the new cluster endpoint
  4. Delete the old cluster once migration is verified
AWS CLI (optional)

Create a new Multi-AZ DB cluster:

aws rds create-db-cluster \
--db-cluster-identifier my-multiaz-cluster \
--engine mysql \
--engine-version 8.0.39 \
--db-cluster-instance-class db.r6gd.large \
--allocated-storage 100 \
--storage-type io1 \
--iops 1000 \
--master-username admin \
--master-user-password <your-secure-password> \
--db-subnet-group-name <your-subnet-group> \
--vpc-security-group-ids <your-security-group-id> \
--storage-encrypted \
--deletion-protection \
--backup-retention-period 7 \
--region us-east-1

Replace:

  • <your-secure-password> with a strong password
  • <your-subnet-group> with your DB subnet group name
  • <your-security-group-id> with your VPC security group ID

Key parameters that enable Multi-AZ:

  • --db-cluster-instance-class: Setting this parameter creates a Multi-AZ DB cluster (as opposed to an Aurora cluster)
  • --storage-type io1: Required for Multi-AZ DB clusters
  • --allocated-storage and --iops: Required when using io1 storage

Check Multi-AZ status of existing clusters:

aws rds describe-db-clusters \
--db-cluster-identifier my-multiaz-cluster \
--query 'DBClusters[0].{ClusterID:DBClusterIdentifier,MultiAZ:MultiAZ,AvailabilityZones:AvailabilityZones}' \
--output table \
--region us-east-1

List all DB clusters and their Multi-AZ status:

aws rds describe-db-clusters \
--query 'DBClusters[*].{ClusterID:DBClusterIdentifier,Engine:Engine,MultiAZ:MultiAZ}' \
--output table \
--region us-east-1
CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: Multi-AZ RDS DB Cluster

Parameters:
DBClusterIdentifier:
Type: String
Description: Identifier for the Multi-AZ DB cluster
Default: my-multiaz-cluster
MasterUsername:
Type: String
Description: Master username for the database
Default: admin
DBSubnetGroupName:
Type: String
Description: Name of the DB subnet group
VPCSecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
Description: Security groups for the cluster

Resources:
MultiAZDBCluster:
Type: AWS::RDS::DBCluster
Properties:
DBClusterIdentifier: !Ref DBClusterIdentifier
Engine: mysql
EngineVersion: '8.0.39'
DBClusterInstanceClass: db.r6gd.large
AllocatedStorage: 100
StorageType: io1
Iops: 1000
MasterUsername: !Ref MasterUsername
ManageMasterUserPassword: true
DBSubnetGroupName: !Ref DBSubnetGroupName
VpcSecurityGroupIds: !Ref VPCSecurityGroupIds
StorageEncrypted: true
DeletionProtection: true
BackupRetentionPeriod: 7
Tags:
- Key: Environment
Value: Production

Outputs:
ClusterEndpoint:
Description: Multi-AZ DB cluster endpoint
Value: !GetAtt MultiAZDBCluster.Endpoint.Address
ClusterArn:
Description: Multi-AZ DB cluster ARN
Value: !GetAtt MultiAZDBCluster.DBClusterArn

Key properties that enable Multi-AZ:

  • DBClusterInstanceClass: This property creates a Multi-AZ DB cluster
  • StorageType: io1: Required for Multi-AZ DB clusters
  • AllocatedStorage and Iops: Required with io1 storage

Deploy the stack:

aws cloudformation create-stack \
--stack-name multiaz-db-cluster \
--template-body file://template.yaml \
--parameters \
ParameterKey=DBClusterIdentifier,ParameterValue=my-multiaz-cluster \
ParameterKey=MasterUsername,ParameterValue=admin \
ParameterKey=DBSubnetGroupName,ParameterValue=<your-subnet-group> \
ParameterKey=VPCSecurityGroupIds,ParameterValue=<your-security-group-id> \
--region us-east-1
Terraform (optional)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "cluster_identifier" {
description = "Identifier for the Multi-AZ DB cluster"
type = string
default = "my-multiaz-cluster"
}

variable "master_username" {
description = "Master username for the database"
type = string
default = "admin"
}

variable "master_password" {
description = "Master password for the database"
type = string
sensitive = true
}

variable "db_subnet_group_name" {
description = "Name of the DB subnet group"
type = string
}

variable "vpc_security_group_ids" {
description = "List of VPC security group IDs"
type = list(string)
}

resource "aws_rds_cluster" "multiaz" {
cluster_identifier = var.cluster_identifier
engine = "mysql"
engine_version = "8.0.39"
db_cluster_instance_class = "db.r6gd.large"
allocated_storage = 100
storage_type = "io1"
iops = 1000
master_username = var.master_username
master_password = var.master_password
db_subnet_group_name = var.db_subnet_group_name
vpc_security_group_ids = var.vpc_security_group_ids
storage_encrypted = true
deletion_protection = true
backup_retention_period = 7
skip_final_snapshot = false
final_snapshot_identifier = "${var.cluster_identifier}-final-snapshot"

tags = {
Environment = "Production"
}
}

output "cluster_endpoint" {
description = "Multi-AZ DB cluster endpoint"
value = aws_rds_cluster.multiaz.endpoint
}

output "cluster_reader_endpoint" {
description = "Multi-AZ DB cluster reader endpoint"
value = aws_rds_cluster.multiaz.reader_endpoint
}

output "cluster_arn" {
description = "Multi-AZ DB cluster ARN"
value = aws_rds_cluster.multiaz.arn
}

Key arguments that enable Multi-AZ:

  • db_cluster_instance_class: This argument creates a Multi-AZ DB cluster
  • storage_type = "io1": Required for Multi-AZ DB clusters
  • allocated_storage and iops: Required with io1 storage

Apply the configuration:

terraform init
terraform plan -var="master_password=<your-secure-password>" \
-var="db_subnet_group_name=<your-subnet-group>" \
-var="vpc_security_group_ids=[\"sg-xxxxxxxxx\"]"
terraform apply

Verification

After creating your Multi-AZ DB cluster, verify it is properly configured:

  1. In the RDS console, go to Databases.
  2. Select your DB cluster.
  3. In the Configuration tab, check Multi-AZ - it should show 3 Zones.
  4. You should also see three DB instances listed under the cluster: one writer and two readers.
CLI verification
aws rds describe-db-clusters \
--db-cluster-identifier my-multiaz-cluster \
--query 'DBClusters[0].{MultiAZ:MultiAZ,AvailabilityZones:AvailabilityZones}' \
--region us-east-1

The output should show MultiAZ: true and three Availability Zones:

{
"MultiAZ": true,
"AvailabilityZones": [
"us-east-1a",
"us-east-1b",
"us-east-1c"
]
}

List clusters without Multi-AZ:

aws rds describe-db-clusters \
--query 'DBClusters[?MultiAZ==`false`].DBClusterIdentifier' \
--region us-east-1

Additional Resources

Notes

  • Aurora vs. Multi-AZ DB clusters: Amazon Aurora uses a different architecture with built-in replication across three AZs. Aurora clusters are inherently highly available. This check specifically applies to RDS Multi-AZ DB clusters (MySQL and PostgreSQL), not Aurora.
  • Engine support: Multi-AZ DB clusters support MySQL 8.0.28+ and PostgreSQL 13.4+. Check the AWS documentation for the latest supported versions.
  • Read scaling: Unlike Multi-AZ DB instances (which have a single standby that cannot serve read traffic), Multi-AZ DB clusters have two reader instances that can serve read queries.
  • Failover time: Multi-AZ DB clusters typically complete failover in under 35 seconds, compared to 1-2 minutes for traditional Multi-AZ DB instances.
  • Connection handling: Use the cluster endpoint for writes and the reader endpoint for read-only queries. Ensure your application handles failover gracefully with proper connection retry logic.
  • Subnet requirements: Your DB subnet group must include subnets in at least three Availability Zones for Multi-AZ DB cluster deployment.