RDS Instance Multi-AZ Deployment
Overview
This check verifies whether your Amazon RDS database instances have Multi-AZ (Multi-Availability Zone) deployment enabled. Multi-AZ automatically maintains a synchronized standby replica of your database in a different Availability Zone, providing automatic failover if something goes wrong with the primary instance.
Risk
Without Multi-AZ protection, your database 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.
- Data loss: You may lose transactions that occurred since your last backup.
- SLA violations: Unplanned downtime can breach service-level agreements with your customers.
- Manual recovery burden: You would need to restore from backups, which is time-consuming and error-prone.
Remediation Steps
Prerequisites
You need permission to modify RDS instances (typically via the rds:ModifyDBInstance IAM permission).
Important considerations before enabling Multi-AZ
- Cost impact: Multi-AZ roughly doubles your RDS instance cost since AWS maintains a standby replica.
- Brief I/O pause: Enabling Multi-AZ on an existing instance may cause a brief I/O freeze (typically a few seconds) during the transition.
- Storage requirement: Ensure you have adequate storage provisioned, as both instances use the same storage allocation.
- Not supported for all instance types: Some older or smaller instance types may not support Multi-AZ.
AWS Console Method
- Open the Amazon RDS console.
- In the left navigation, click Databases.
- Select the database instance you want to modify.
- Click the Modify button.
- Scroll down to the Availability & durability section.
- Select Create a standby instance (recommended for production usage).
- Scroll to the bottom and click Continue.
- Under Schedule modifications, choose:
- Apply immediately if you want the change now (may cause brief I/O pause)
- Apply during the next scheduled maintenance window for less disruption
- Click Modify DB instance.
- Wait for the instance status to return to Available (this may take several minutes).
AWS CLI (optional)
Enable Multi-AZ on an existing RDS instance:
aws rds modify-db-instance \
--db-instance-identifier <your-db-instance-id> \
--multi-az \
--apply-immediately \
--region us-east-1
Replace <your-db-instance-id> with your actual database instance identifier.
To apply during the next maintenance window instead:
aws rds modify-db-instance \
--db-instance-identifier <your-db-instance-id> \
--multi-az \
--no-apply-immediately \
--region us-east-1
Check the modification status:
aws rds describe-db-instances \
--db-instance-identifier <your-db-instance-id> \
--query 'DBInstances[0].{Status:DBInstanceStatus,MultiAZ:MultiAZ,PendingModifiedValues:PendingModifiedValues}' \
--region us-east-1
CloudFormation (optional)
Set MultiAZ: true in your AWS::RDS::DBInstance resource:
AWSTemplateFormatVersion: '2010-09-09'
Description: RDS instance with Multi-AZ enabled
Parameters:
DBInstanceIdentifier:
Type: String
Description: Unique identifier for the RDS instance
DBInstanceClass:
Type: String
Default: db.t3.medium
Description: Instance class for the RDS instance
Engine:
Type: String
Default: mysql
AllowedValues:
- mysql
- postgres
- mariadb
- oracle-ee
- sqlserver-ee
Description: Database engine
MasterUsername:
Type: String
Description: Master username for the database
AllocatedStorage:
Type: Number
Default: 20
Description: Allocated storage in GB
VPCSecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
Description: Security groups for the RDS instance
DBSubnetGroupName:
Type: String
Description: DB subnet group name
Resources:
RDSInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: !Ref DBInstanceIdentifier
DBInstanceClass: !Ref DBInstanceClass
Engine: !Ref Engine
MasterUsername: !Ref MasterUsername
ManageMasterUserPassword: true
AllocatedStorage: !Ref AllocatedStorage
MultiAZ: true
VPCSecurityGroups: !Ref VPCSecurityGroupIds
DBSubnetGroupName: !Ref DBSubnetGroupName
StorageEncrypted: true
PubliclyAccessible: false
Outputs:
DBInstanceEndpoint:
Description: RDS instance endpoint
Value: !GetAtt RDSInstance.Endpoint.Address
Note: This template uses ManageMasterUserPassword: true to let AWS Secrets Manager handle the password securely.
Terraform (optional)
Set multi_az = true in your aws_db_instance resource:
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
variable "db_instance_identifier" {
description = "Unique identifier for the RDS instance"
type = string
}
variable "db_instance_class" {
description = "Instance class for the RDS instance"
type = string
default = "db.t3.medium"
}
variable "engine" {
description = "Database engine"
type = string
default = "mysql"
}
variable "engine_version" {
description = "Database engine version"
type = string
default = "8.0"
}
variable "allocated_storage" {
description = "Allocated storage in GB"
type = number
default = 20
}
variable "db_name" {
description = "Name of the database"
type = string
}
variable "username" {
description = "Master username"
type = string
}
variable "password" {
description = "Master password"
type = string
sensitive = true
}
variable "vpc_security_group_ids" {
description = "List of VPC security group IDs"
type = list(string)
}
variable "db_subnet_group_name" {
description = "DB subnet group name"
type = string
}
resource "aws_db_instance" "main" {
identifier = var.db_instance_identifier
instance_class = var.db_instance_class
engine = var.engine
engine_version = var.engine_version
allocated_storage = var.allocated_storage
db_name = var.db_name
username = var.username
password = var.password
# Enable Multi-AZ for high availability
multi_az = true
vpc_security_group_ids = var.vpc_security_group_ids
db_subnet_group_name = var.db_subnet_group_name
storage_encrypted = true
publicly_accessible = false
skip_final_snapshot = false
final_snapshot_identifier = "${var.db_instance_identifier}-final-snapshot"
tags = {
Name = var.db_instance_identifier
}
}
output "db_instance_endpoint" {
description = "RDS instance endpoint"
value = aws_db_instance.main.endpoint
}
output "db_instance_arn" {
description = "RDS instance ARN"
value = aws_db_instance.main.arn
}
To enable Multi-AZ on an existing instance, simply add or change:
multi_az = true
Then run:
terraform plan
terraform apply
Verification
After enabling Multi-AZ, verify it is active:
- In the RDS console, go to Databases.
- Select your database instance.
- In the Configuration tab, look for Multi-AZ - it should show Yes.
CLI verification
aws rds describe-db-instances \
--db-instance-identifier <your-db-instance-id> \
--query 'DBInstances[0].MultiAZ' \
--region us-east-1
This should return true.
To list all instances without Multi-AZ:
aws rds describe-db-instances \
--query 'DBInstances[?MultiAZ==`false`].DBInstanceIdentifier' \
--region us-east-1
Additional Resources
- Amazon RDS Multi-AZ deployments
- High availability (Multi-AZ) for Amazon RDS
- Multi-AZ DB cluster deployments
- RDS pricing - Multi-AZ pricing information
Notes
- Aurora clusters: Amazon Aurora uses a different architecture with built-in replication. Aurora DB clusters inherently provide high availability, but individual Aurora instances still benefit from Multi-AZ placement.
- Read replicas vs. Multi-AZ: Read replicas are for scaling read traffic; Multi-AZ is for high availability. They serve different purposes and can be used together.
- Failover testing: Consider periodically testing failover using the
aws rds reboot-db-instance --force-failovercommand to ensure your application handles failover gracefully. - Connection handling: Ensure your application uses the RDS endpoint (not IP addresses) and implements proper connection retry logic to handle transparent failover.