RDS DB clusters should be configured for multiple Availability Zones
A single-AZ database deployment creates an availability bottleneck. If that AZ experiences an outage, your database can become unreachable until failover or recovery actions complete.
Multi-AZ architectures maintain capacity in more than one AZ and support automatic failover. Failover timing varies by engine, topology, and workload, and is typically measured in tens of seconds to a few minutes. The cost difference is real, typically doubling compute spend for equivalent instance counts, but that's usually still less than the business impact of an unplanned outage on a production database.
Retrofit consideration
Enabling Multi-AZ on an existing single-AZ Aurora cluster means adding cluster instances in new AZs, which triggers provisioning time and increased cost. For non-Aurora Multi-AZ DB clusters, converting may require downtime or a blue-green deployment.
Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
module "rds_aurora" {
source = "nistcsf.compliance.tf/terraform-aws-modules/rds-aurora/aws"
version = ">=10.0.0,<11.0.0"
create_db_subnet_group = true
create_security_group = true
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
instances = {
one = {
instance_class = "db.t4g.medium"
}
}
manage_master_user_password = true
master_username = "root"
name = "abc123"
skip_final_snapshot = true
subnets = ["subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
}
module "rds_aurora" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/rds-aurora/aws"
version = ">=10.0.0,<11.0.0"
create_db_subnet_group = true
create_security_group = true
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
instances = {
one = {
instance_class = "db.t4g.medium"
}
}
manage_master_user_password = true
master_username = "root"
name = "abc123"
skip_final_snapshot = true
subnets = ["subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
}
If you use terraform-aws-modules/rds-aurora/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "rds_aurora" {
source = "terraform-aws-modules/rds-aurora/aws"
version = ">=10.0.0,<11.0.0"
create_db_subnet_group = true
create_security_group = true
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
instances = {
one = {
instance_class = "db.t4g.medium"
}
}
manage_master_user_password = true
master_username = "root"
name = "abc123"
skip_final_snapshot = true
subnets = ["subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
}
Use AWS provider resources directly. See docs for the resources involved: aws_rds_cluster.
resource "aws_rds_cluster" "this" {
backtrack_window = 72
cluster_identifier = "pofix-abc123"
db_subnet_group_name = "example-db-subnet-group"
enabled_cloudwatch_logs_exports = ["audit"]
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
manage_master_user_password = true
master_username = "dbadmin"
skip_final_snapshot = true
vpc_security_group_ids = ["sg-12345678"]
}
What this control checks
For Aurora clusters, the control validates that aws_rds_cluster has availability_zones set to at least two distinct AZs, and that corresponding aws_rds_cluster_instance resources exist in those AZs. Each instance can specify availability_zone to pin it to a particular AZ. A cluster with only one instance, or with all instances in the same AZ, fails. For non-Aurora Multi-AZ DB clusters (engine mysql or postgres), aws_rds_cluster should include at least two entries in availability_zones, and the DB cluster MultiAZ field should be true.
Common pitfalls
Aurora availability_zones is informational at creation
Setting
availability_zonesonaws_rds_clustertells AWS which AZs are eligible for instances, but it doesn't guarantee instances actually run there. Deploy at least twoaws_rds_cluster_instanceresources in separate AZs using theavailability_zoneargument on each instance to achieve true Multi-AZ.Serverless v1 clusters may not support Multi-AZ the same way
Aurora Serverless v1 (
engine_mode = "serverless") doesn't use discrete cluster instances. Its Multi-AZ behavior is managed internally by AWS and may not surface asMultiAZ: truein the API response. Serverless v2 uses cluster instances with classdb.serverless, but HA evidence and behavior should still be validated with Aurora-specific signals rather than assuming identical semantics to provisioned Multi-AZ DB clusters.Terraform plan shows no drift when AZ removed externally
Delete a cluster instance in a second AZ through the console or CLI, and Terraform will catch the missing
aws_rds_cluster_instanceon the next plan. But if that instance was never managed by Terraform in the first place, there's no drift to detect, and the cluster silently becomes single-AZ.Cost doubles with Multi-AZ
Each additional cluster instance in a new AZ incurs full compute charges. For Aurora, a db.r6g.xlarge writer plus one reader roughly doubles the hourly cost from approximately $0.58/hr to $1.16/hr in us-east-1. Budget for this before enabling Multi-AZ across all clusters.
Audit evidence
An auditor expects rds-cluster-multi-az-enabled Config rule results showing compliant status for all in-scope clusters. Supporting evidence includes aws rds describe-db-clusters output filtered to show AvailabilityZones with at least two entries, plus engine-appropriate HA indicators: MultiAZ: true for Multi-AZ DB clusters, and instance placement confirming failover-capable topology for Aurora. Console screenshots of the RDS cluster detail page work as supplementary proof when they show the relevant HA fields for that engine.
For continuous assurance, a compliance dashboard pulling from AWS Config or a CSPM tool should show historical evaluation results confirming Multi-AZ remained enabled throughout the audit period, with no gaps in compliance status.
Framework-specific interpretation
NIST Cybersecurity Framework v2.0: PR.IR (Infrastructure Resilience) and RC.RP (Recovery Planning) are both in scope. PR.IR expects components to remain available during failures, which multi-AZ deployment addresses directly. RC.RP is satisfied by automatic failover: recovery happens without a manual restore operation, which is what that planning requirement is really asking for.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
rds_db_cluster_multiple_az_enabledAWS Config Managed Rule:
RDS_CLUSTER_MULTI_AZ_ENABLEDCheckov Check:
CKV_AWS_157Powerpipe Control:
aws_compliance.control.rds_db_cluster_multiple_az_enabledProwler Check:
rds_cluster_multi_azAWS Security Hub Control:
RDS.15
Last reviewed: 2026-03-09