Elasticsearch domain node-to-node encryption should be enabled
Without node-to-node encryption, traffic between Elasticsearch nodes travels in plaintext within the VPC. An attacker with network-level access (through a compromised instance, misconfigured security group, or VPC peering) can passively sniff index data, search queries, and cluster state flowing between nodes. This includes the actual document content stored in your indices.
Enabling node-to-node encryption has no meaningful performance penalty on modern instance types and eliminates an entire class of eavesdropping risk. AWS requires it for certain Elasticsearch versions (6.0+) when using fine-grained access control, so skipping it also limits your future access control options.
Retrofit consideration
Enabling node-to-node encryption on a running domain triggers a blue/green deployment. AWS builds a new cluster, migrates data, then cuts over the endpoint. Depending on cluster size, this can run for hours and may cause brief endpoint unavailability or elevated latency. Plan a maintenance window before applying the change.
Implementation
Choose the approach that matches how you manage Terraform.
Use AWS provider resources directly. See docs for the resources involved: aws_elasticsearch_domain.
resource "aws_elasticsearch_domain" "this" {
advanced_security_options {
enabled = true
internal_user_database_enabled = true
master_user_options {
master_user_name = "admin"
master_user_password = "ChangeMe123!"
}
}
cluster_config {
dedicated_master_count = 3
dedicated_master_enabled = true
dedicated_master_type = "m5.large.elasticsearch"
instance_count = 3
instance_type = "m5.large.elasticsearch"
zone_awareness_config {
availability_zone_count = 3
}
zone_awareness_enabled = true
}
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"
}
elasticsearch_version = "7.10"
encrypt_at_rest {
enabled = true
}
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"
}
vpc_options {
security_group_ids = ["sg-12345678"]
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
}
node_to_node_encryption {
enabled = true
}
}
What this control checks
The control checks that the domain resource has node-to-node encryption enabled. For aws_opensearch_domain, the node_to_node_encryption block must be present with enabled = true. The legacy aws_elasticsearch_domain resource uses the same block and argument. A domain that omits the block entirely, or sets enabled = false, fails. No KMS key is required; node-to-node encryption uses AWS-managed TLS certificates.
Common pitfalls
Blue/green deployment on existing domains
What Terraform shows as an in-place update is actually a blue/green deployment in AWS. The cluster rebuild can run for hours, and brief endpoint unavailability is possible. Test the change in a staging environment before touching production.
Version and feature compatibility
Some older Elasticsearch engine versions don't support node-to-node encryption, and certain feature combinations (fine-grained access control, for instance) require it to be enabled. A Terraform
applyagainst an incompatible configuration fails with an API error, not a plan-time warning, so check version support before applying.Deprecated resource confusion
If you're migrating from
aws_elasticsearch_domaintoaws_opensearch_domain, carry thenode_to_node_encryptionblock across explicitly. The block name is the same, but the resource operates against the OpenSearch API and the setting won't be inferred from the old resource definition.Encryption at rest prerequisite
Node-to-node encryption and encryption at rest are independent settings, but certain engine versions and advanced security feature combinations require both to be enabled together. If they aren't, the AWS API rejects the configuration, sometimes with an error message that doesn't make the dependency obvious.
Audit evidence
An auditor expects AWS Config rule results for elasticsearch-node-to-node-encryption-check showing compliant evaluations across all in-scope domains. Console screenshots of the domain security configuration page with 'Node-to-node encryption' shown as Enabled work as supplementary evidence. For programmatic verification, aws es describe-elasticsearch-domain --domain-name <name> should return "NodeToNodeEncryptionOptions": {"Enabled": true}.
AWS Security Hub dashboards tracking this Config rule over time strengthen the audit trail by showing the control was not briefly disabled between reviews. Third-party CSPM platforms that ingest Config findings serve the same purpose.
Framework-specific interpretation
SOC 2: CC6.1 asks for encryption during transmission as part of logical access and data protection controls. Node-to-node encryption covers the intra-cluster leg, where search queries and index data move between nodes outside the reach of application-layer TLS. That gap is what this setting closes.
PCI DSS v4.0: Requirement 4 targets cardholder data on open, public networks, but most security programs extend equivalent protections to sensitive internal traffic. Node-to-node TLS helps protect indexed cardholder data moving between shards within the cluster, even though that traffic stays inside the VPC.
HIPAA Omnibus Rule 2013: 45 CFR 164.312(e)(1) requires transmission security for ePHI. Any ePHI indexed in Elasticsearch traverses inter-node channels during shard operations, replication, and search execution. Node-to-node encryption covers all of that traffic with TLS 1.2, directly satisfying the transmission security standard.
GDPR: Index data flowing between nodes during shard replication and query execution can include personal data. Article 32's requirement for appropriate technical safeguards applies to this layer, and encrypting it reduces exposure during processing operations where application-layer protections don't reach.
NIST SP 800-53 Rev 5: This addresses both SC-8 (Transmission Confidentiality and Integrity) and SC-23 (Session Authenticity). TLS 1.2 on inter-node channels handles both: authenticated sessions prevent man-in-the-middle attacks, and encryption prevents passive interception of index data and cluster state. Two controls, one setting.
FedRAMP Moderate Baseline Rev 4: SC-8 calls for confidentiality and integrity of transmitted information. At the Moderate baseline, TLS 1.2 between nodes is what gets you there for federal data processed through Elasticsearch, ensuring plaintext interception by network-level adversaries isn't possible within the cluster.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
es_domain_node_to_node_encryption_enabledAWS Config Managed Rule:
ELASTICSEARCH_NODE_TO_NODE_ENCRYPTION_CHECKCheckov Check:
CKV_AWS_6Powerpipe Controls:
aws_compliance.control.es_domain_node_to_node_encryption_enabled,aws_compliance.control.opensearch_domain_node_to_node_encryption_enabledProwler Check:
opensearch_service_domains_node_to_node_encryption_enabledAWS Security Hub Control:
ES.3KICS Query:
967eb3e6-26fc-497d-8895-6428beb6e8e2Trivy Check:
AWS-0043
Last reviewed: 2026-03-09