Back to Checks
aws

OpenSearch domain has at least 3 data nodes and Zone Awareness enabled

opensearch_service_domains_fault_tolerant_data_nodes
Service: opensearchSeverity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:AwsOpenSearchServiceDomain

Amazon OpenSearch domains are assessed for fault tolerance: >= 3 data nodes (instance_count >= 3) and Zone Awareness (zone_awareness_enabled = true) to distribute data across Availability Zones.

Risk

Insufficient data nodes or disabled Zone Awareness reduces availability and durability. A node or AZ failure can trigger shard unavailability, write failures, or cluster outage, increasing risk of data inconsistency during rebalancing and blocking reads/writes until recovery.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks opensearch_service_domains_fault_tolerant_data_nodes

Recommendation

Configure OpenSearch with >= 3 data nodes and enable Zone Awareness to spread nodes across AZs.

  • Prefer Multi-AZ with Standby for resilient failover
  • Use node counts in multiples of three and set index replicas (>= 1)
  • Practice capacity planning and failure testing as defense in depth

Remediation

CLI

aws opensearch update-domain-config --domain-name <example_resource_name> --cluster-config InstanceCount=3,ZoneAwarenessEnabled=true

Terraform

# Terraform: Ensure at least 3 data nodes and enable Zone Awareness
resource "aws_opensearch_domain" "<example_resource_name>" {
  domain_name = "<example_resource_name>"

  cluster_config {
    instance_type          = "m5.large.search"
    instance_count         = 3     # Critical: sets at least 3 data nodes for fault tolerance
    zone_awareness_enabled = true  # Critical: enables cross-AZ (Zone Awareness)
  }
}

NativeIaC

# CloudFormation: Ensure at least 3 data nodes and enable Zone Awareness
Resources:
  <example_resource_name>:
    Type: AWS::OpenSearchService::Domain
    Properties:
      DomainName: <example_resource_name>
      ClusterConfig:
        InstanceType: m5.large.search
        InstanceCount: 3            # Critical: sets at least 3 data nodes for fault tolerance
        ZoneAwarenessEnabled: true  # Critical: enables cross-AZ (Zone Awareness)

Other

1Open the AWS Console and go to Amazon OpenSearch Service
2Select your domain and click Edit domain
3Under Cluster configuration:
4- Set Number of data nodes to 3 (or more)
5- Enable Zone awareness
6Click Submit to apply the changes

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.opensearch.opensearch_client import (
    opensearch_client,
)


class opensearch_service_domains_fault_tolerant_data_nodes(Check):
    def execute(self):
        findings = []

        for domain in opensearch_client.opensearch_domains.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=domain)

            report.status = "FAIL"
            report.status_extended = f"Opensearch domain {domain.name} is not fault tolerant as it has less than 3 data nodes and cross-zone replication (Zone Awareness) is not enabled."

            if domain.instance_count >= 3 and domain.zone_awareness_enabled:
                report.status = "PASS"
                report.status_extended = f"Opensearch domain {domain.name} is fault tolerant with {domain.instance_count} data nodes and cross-zone replication (Zone Awareness) enabled."
            elif domain.instance_count >= 3 and not domain.zone_awareness_enabled:
                report.status = "FAIL"
                report.status_extended = f"Opensearch domain {domain.name} is not fault tolerant as it has {domain.instance_count} data nodes, but cross-zone replication (Zone Awareness) is not enabled."
            elif domain.instance_count < 3 and domain.zone_awareness_enabled:
                report.status = "FAIL"
                report.status_extended = f"Opensearch domain {domain.name} is not fault tolerant as it has cross-zone replication (Zone Awareness) enabled, but only {domain.instance_count} data nodes."

            findings.append(report)

        return findings