OpenSearch domains should have at least three data nodes
An OpenSearch cluster with fewer than three data nodes or without zone awareness has a single point of failure at the AZ level. If the sole AZ, or one of two AZs hosting data nodes, goes down, the cluster loses quorum or becomes read-only, taking down search and analytics workloads with it.
Three data nodes across multiple AZs let the cluster redistribute shards automatically during an AZ failure. This is the minimum configuration AWS recommends for production OpenSearch clusters, and it's the threshold where fault tolerance becomes meaningful.
Retrofit consideration
Increasing instance_count on a running domain triggers a blue/green deployment. Enabling zone_awareness_enabled on an existing single-AZ cluster requires shard rebalancing across new AZs, which can temporarily increase cluster load and latency. Plan changes during a maintenance window.
Implementation
Choose the approach that matches how you manage Terraform.
If you use terraform-aws-modules/opensearch/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 "opensearch" {
source = "terraform-aws-modules/opensearch/aws"
version = ">=2.0.0,<3.0.0"
advanced_security_options = {
enabled = true
internal_user_database_enabled = true
master_user_options = {
master_user_name = "admin"
master_user_password = "P0fix-Test-2026!"
}
}
auto_tune_options = {
desired_state = "DISABLED"
}
domain_endpoint_options = {
enforce_https = true
tls_security_policy = "Policy-Min-TLS-1-2-2019-07"
}
domain_name = "abc123"
ebs_options = {
ebs_enabled = true
volume_size = 20
volume_type = "gp3"
}
engine_version = "OpenSearch_2.11"
cluster_config = {
zone_awareness_enabled = true
}
}
Use AWS provider resources directly. See docs for the resources involved: aws_opensearch_domain.
resource "aws_opensearch_domain" "this" {
advanced_security_options {
enabled = true
internal_user_database_enabled = true
master_user_options {
master_user_name = "admin"
master_user_password = "ChangeMe123!"
}
}
auto_tune_options {
desired_state = "DISABLED"
}
cognito_options {
enabled = true
identity_pool_id = "us-east-1:12345678-1234-1234-1234-123456789012"
role_arn = "arn:aws:iam::123456789012:role/example-role"
user_pool_id = "us-east-1_AbCdEfGhI"
}
domain_endpoint_options {
enforce_https = true
tls_security_policy = "Policy-Min-TLS-1-2-2019-07"
}
domain_name = "pofix-abc123"
ebs_options {
ebs_enabled = true
volume_size = 10
volume_type = "gp3"
}
encrypt_at_rest {
enabled = true
}
engine_version = "OpenSearch_2.11"
log_publishing_options {
cloudwatch_log_group_arn = local.es_log_group_arn
log_type = "AUDIT_LOGS"
}
log_publishing_options {
cloudwatch_log_group_arn = local.es_log_group_arn
log_type = "ES_APPLICATION_LOGS"
}
log_publishing_options {
cloudwatch_log_group_arn = local.es_log_group_arn
log_type = "SEARCH_SLOW_LOGS"
}
log_publishing_options {
cloudwatch_log_group_arn = local.es_log_group_arn
log_type = "INDEX_SLOW_LOGS"
}
node_to_node_encryption {
enabled = true
}
vpc_options {
security_group_ids = ["sg-12345678"]
subnet_ids = ["subnet-12345678", "subnet-12345678"]
}
cluster_config {
dedicated_master_enabled = false
instance_count = 4
instance_type = "t3.small.search"
zone_awareness_enabled = true
}
}
What this control checks
In the aws_opensearch_domain resource, the cluster_config block must set instance_count to 3 or greater and zone_awareness_enabled to true. With zone_awareness_enabled = true, also configure the nested zone_awareness_config block with availability_zone_count set to 2 or 3 to control how many AZs the nodes span. A domain fails this control if instance_count is less than 3 or zone_awareness_enabled is false (or omitted, since it defaults to false). For three-AZ deployments, set availability_zone_count to 3 and instance_count to a multiple of 3 for even shard distribution.
Common pitfalls
Default instance_count is 1
instance_countdefaults to 1 when omitted fromcluster_config. Any domain created without an explicit value fails this control immediately, including test clusters that later get promoted to production without a Terraform review.zone_awareness_enabled without zone_awareness_config
Setting
zone_awareness_enabled = truewithout azone_awareness_configblock defaults to 2 AZs. This passes the control but may not match your resilience target. If you later increaseinstance_countto 6 expecting 3-AZ distribution, you get 3 nodes per AZ across only 2 AZs instead of 2 per AZ across 3.Uneven instance_count across AZs
If
instance_countis not evenly divisible byavailability_zone_count, OpenSearch distributes nodes unevenly. Five nodes across 3 AZs places them 2-2-1, which means losing the AZ with 1 node is less impactful than losing one with 2. The control passes, but shard allocation becomes unbalanced.Dedicated master nodes do not count as data nodes
Setting
dedicated_master_enabled = trueanddedicated_master_count = 3does not satisfy this control. The check evaluatesinstance_count, which covers data nodes only. You need both dedicated masters and at least 3 data nodes.
Audit evidence
AWS Config rule evaluation results showing each OpenSearch domain as compliant, or a Security Hub findings export filtered to this control, are the most portable form of audit evidence. Console screenshots of the cluster configuration page showing data node count (3+) and the Zone Awareness or Multi-AZ with Standby setting are also acceptable for point-in-time checks. For continuous compliance, a CloudWatch dashboard or Config conformance pack report showing sustained compliance over the audit period is stronger than point-in-time screenshots.
Framework-specific interpretation
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
opensearch_domain_data_node_fault_toleranceAWS Config Managed Rule:
OPENSEARCH_DATA_NODE_FAULT_TOLERANCEPowerpipe Controls:
aws_compliance.control.es_domain_data_nodes_min_3,aws_compliance.control.opensearch_domain_data_node_fault_toleranceProwler Check:
opensearch_service_domains_fault_tolerant_data_nodesAWS Security Hub Controls:
ES.6,Opensearch.6
Last reviewed: 2026-03-09