Skip to content

Elasticsearch domains should require TLS 1.2 for connections

TLS 1.0 and 1.1 have known vulnerabilities including BEAST, POODLE, and weak cipher suite support. Elasticsearch domains often hold sensitive application data, search indices, and log aggregations. Allowing legacy TLS versions exposes query traffic and ingested documents to interception or downgrade attacks.

Enforcing TLS 1.2 as the floor removes these weak protocols entirely. It's a one-line configuration change with zero performance penalty on modern clients. There's no good reason to leave a domain running the weaker default.

Retrofit consideration

Changing the TLS policy on a live domain may break clients that only support TLS 1.0 or 1.1. Verify all application clients, SDKs, and monitoring agents support TLS 1.2 before applying.

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_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"
  }

  node_to_node_encryption {
    enabled = true
  }

  vpc_options {
    security_group_ids = ["sg-12345678"]
    subnet_ids         = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
  }

  domain_endpoint_options {
    enforce_https       = true
    tls_security_policy = "Policy-Min-TLS-1-2-2019-07"
  }
}

What this control checks

In Terraform, the aws_elasticsearch_domain (or aws_opensearch_domain) resource must include a domain_endpoint_options block with tls_security_policy set to "Policy-Min-TLS-1-2-2019-07". If this argument is omitted, AWS defaults to Policy-Min-TLS-1-0-2019-07, which permits TLS 1.0 and 1.1 connections and fails this control. The enforce_https argument in the same block should also be true to require HTTPS, though this control specifically evaluates the TLS version policy. A passing configuration looks like:

domain_endpoint_options { enforce_https = true; tls_security_policy = "Policy-Min-TLS-1-2-2019-07" }

Any other value for tls_security_policy fails.

Common pitfalls

  • Default TLS policy allows 1.0

    Omit tls_security_policy from domain_endpoint_options and AWS quietly defaults to Policy-Min-TLS-1-0-2019-07. This silently passes terraform plan with no warnings but fails the compliance check. Always set the value explicitly.

  • Confusing aws_elasticsearch_domain with aws_opensearch_domain

    The aws_elasticsearch_domain resource is for legacy Elasticsearch engine types. If you've migrated to OpenSearch, use aws_opensearch_domain instead. Both support domain_endpoint_options.tls_security_policy, but referencing the wrong resource type means Terraform won't manage the actual domain and the TLS setting stays at its default.

  • enforce_https false negates TLS policy

    Setting tls_security_policy = "Policy-Min-TLS-1-2-2019-07" while leaving enforce_https = false means the domain still accepts plaintext HTTP. The TLS version policy is meaningless if HTTP isn't blocked. Set enforce_https = true explicitly alongside the TLS policy.

  • Custom endpoint TLS handled separately

    If you configure a custom endpoint via custom_endpoint and custom_endpoint_certificate_arn in domain_endpoint_options, TLS termination for that endpoint depends on both the ACM certificate and the domain's TLS policy. Make sure the custom endpoint configuration and tls_security_policy are both aligned to TLS 1.2, they don't inherit from each other automatically.

Audit evidence

An auditor expects AWS Config rule evaluation results for the managed rule elasticsearch-https-required, or equivalent custom Config rules checking DomainEndpointOptions.TLSSecurityPolicy. A compliance report showing all domains as COMPLIANT is the primary artifact. Per-domain verification: aws es describe-elasticsearch-domain --domain-name <name> should show "TLSSecurityPolicy": "Policy-Min-TLS-1-2-2019-07" under DomainEndpointOptions for each domain.

Security Hub findings for this control, or Prowler scan results, cover ongoing enforcement beyond a point-in-time check.

Framework-specific interpretation

NIST Cybersecurity Framework v2.0: PR.DS under NIST CSF v2 calls for protecting data in transit using current cryptographic standards. TLS 1.2 on Elasticsearch endpoints is how you meet that expectation for search traffic and ingested documents.

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: es_domain_encrypted_using_tls_1_2

  • Checkov Check: CKV_AWS_228

  • Powerpipe Control: aws_compliance.control.es_domain_encrypted_using_tls_1_2

  • AWS Security Hub Control: ES.8

  • Trivy Check: AWS-0126

Last reviewed: 2026-03-09