Elasticsearch domains should have audit logging enabled
Audit logs capture authentication attempts, index-level access, and query activity within Elasticsearch domains. Without them, there is no record of who accessed or modified data, making breach investigation and insider-threat detection nearly impossible.
Elasticsearch domains often store aggregated application logs, business analytics, or sensitive search indices. Enabling audit logging creates a persistent audit trail in CloudWatch Logs that security teams can query with Logs Insights or forward to a SIEM for correlation.
Retrofit consideration
Enabling audit logging requires fine-grained access control (advanced_security_options). On existing domains, enabling fine-grained access control is typically done through a blue/green deployment and may cause temporary performance impact; recreation or migration is not always required.
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"
}
node_to_node_encryption {
enabled = true
}
vpc_options {
security_group_ids = ["sg-12345678"]
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
}
}
What this control checks
On aws_elasticsearch_domain (or aws_opensearch_domain), a log_publishing_options block must be present with log_type set to "AUDIT_LOGS" and cloudwatch_log_group_arn pointing to a CloudWatch Logs log group. advanced_security_options must have enabled = true, since audit logging is only available when fine-grained access control is active. It fails when the AUDIT_LOGS block is absent, when advanced_security_options is disabled, or when enabled inside log_publishing_options is explicitly set to false. A CloudWatch Logs log group and a resource policy granting es.amazonaws.com write access are also required.
Common pitfalls
Fine-grained access control prerequisite
Audit logging requires
advanced_security_options { enabled = true }. If this block is missing orenabledisfalse, the Elasticsearch API rejects the audit log configuration entirely. On existing domains where fine-grained access control was never enabled, turning it on may trigger a blue/green deployment with temporary performance impact.CloudWatch log resource policy missing
Even with
log_publishing_optionsconfigured, Elasticsearch cannot write to CloudWatch Logs without anaws_cloudwatch_log_resource_policygrantinges.amazonaws.comthelogs:PutLogEventsandlogs:CreateLogStreamactions. Without it, log delivery silently fails, and the gap won't be obvious duringterraform apply.Deprecated inline log_publishing_options in older modules
Older Terraform modules using
aws_elasticsearch_domainmay only includeES_APPLICATION_LOGSorINDEX_SLOW_LOGSinlog_publishing_options, omittingAUDIT_LOGSentirely. Eachlog_typeneeds its own block, so add a separatelog_publishing_optionsblock forAUDIT_LOGSalongside the existing ones rather than modifying them.Log group retention left at default
CloudWatch log groups created without an explicit
retention_in_daysonaws_cloudwatch_log_groupretain logs indefinitely. For audit logs, set a retention period that meets your compliance requirements (365 days for PCI DSS, for example) and avoid leaving it unbounded.
Audit evidence
An auditor expects the AWS Config rule evaluation to show compliant status across all in-scope Elasticsearch domains. Console evidence from the OpenSearch Service domain configuration page should show "Audit logs" enabled under the "Logs" tab, with a linked CloudWatch Logs log group containing recent entries for authentication events and index operations.
For deeper validation, CloudTrail logs showing UpdateElasticsearchDomainConfig or CreateElasticsearchDomain API calls confirm when audit logging was enabled and by whom. Security Hub finding status across accounts and regions provides a consolidated view of this control's coverage.
Framework-specific interpretation
NIST Cybersecurity Framework v2.0: DE.CM and DE.AE both call for continuous monitoring of data access and authentication events. Audit logs from Elasticsearch domains feed directly into that capability, covering search workloads that might otherwise be invisible to security tooling.
Related controls
Elasticsearch domain error logging to CloudWatch Logs should be enabled
OpenSearch domains node-to-node encryption should be enabled
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
es_domain_audit_logging_enabledAWS Config Managed Rules:
ELASTICSEARCH_LOGS_TO_CLOUDWATCH,OPENSEARCH_AUDIT_LOGGING_ENABLEDCheckov Check:
CKV_AWS_317Powerpipe Controls:
aws_compliance.control.es_domain_audit_logging_enabled,aws_compliance.control.opensearch_domain_audit_logging_enabledProwler Check:
opensearch_service_domains_audit_logging_enabledAWS Security Hub Controls:
ES.5,Opensearch.5Trivy Check:
AWS-0042
Last reviewed: 2026-03-09