CloudFront distributions access logs should be enabled
CloudFront access logs record every request to your distributions: viewer IP, request URI, edge location, HTTP status, and bytes served. Without them, investigating unauthorized access patterns, detecting content scraping, or tracing the source of anomalous traffic spikes all become significantly harder.
Log data also feeds into cost attribution and performance analysis. If a distribution suddenly drives unexpected data transfer charges, access logs are the fastest way to identify the responsible paths and referrers.
Retrofit consideration
Enabling logging on an existing distribution triggers a configuration update but does not cause downtime. The part that trips people up: the destination S3 bucket must grant the CloudFront log delivery account write access via ACL, and that bucket-side change is easy to miss when retrofitting.
Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
module "cloudfront" {
source = "pcidss.compliance.tf/terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
module "cloudfront" {
source = "hipaa.compliance.tf/terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
module "cloudfront" {
source = "nistcsf.compliance.tf/terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
module "cloudfront" {
source = "cisv80ig1.compliance.tf/terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
module "cloudfront" {
source = "acscessentialeight.compliance.tf/terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
module "cloudfront" {
source = "hipaasecurity2003.compliance.tf/terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
module "cloudfront" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
If you use terraform-aws-modules/cloudfront/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 "cloudfront" {
source = "terraform-aws-modules/cloudfront/aws"
version = ">=6.0.0,<7.0.0"
}
Use AWS provider resources directly. See docs for the resources involved: aws_cloudfront_distribution.
resource "aws_cloudfront_distribution" "this" {
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
field_level_encryption_id = "abc123"
forwarded_values {
cookies {
forward = "none"
}
query_string = false
}
target_origin_id = "S3Origin"
viewer_protocol_policy = "redirect-to-https"
}
default_root_object = "index.html"
enabled = true
logging_config {
bucket = "example-bucket-abc123_domain_name"
}
origin {
domain_name = "example.s3.amazonaws.com"
origin_id = "S3Origin"
}
restrictions {
geo_restriction {
locations = ["US", "CA", "GB"]
restriction_type = "whitelist"
}
}
viewer_certificate {
acm_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
minimum_protocol_version = "TLSv1.2_2021"
ssl_support_method = "sni-only"
}
wait_for_deployment = false
web_acl_id = "arn:aws:wafv2:us-east-1:123456789012:regional/webacl/example/12345678-1234-1234-1234-123456789012"
}
What this control checks
The aws_cloudfront_distribution resource must include a logging_config block. Within that block, bucket is required and must reference the domain name of an S3 bucket (e.g., my-logs-bucket.s3.amazonaws.com). The optional include_cookies argument controls whether cookie data appears in logs; prefix sets a key prefix for log objects. A distribution that omits the logging_config block entirely, or sets bucket to an empty string, fails. Any non-empty bucket value pointing to a valid S3 bucket passes.
Common pitfalls
S3 bucket ACL requirements for log delivery
CloudFront standard logging uses the legacy S3 ACL mechanism. The destination bucket must have ACLs enabled (not the default
BucketOwnerEnforcedsetting) and must grant the CloudFront log delivery canonical user permission to write objects and read bucket ACLs. If you useaws_s3_bucket_ownership_controlswithobject_ownershipset toBucketOwnerEnforced, log delivery silently fails and the control may appear compliant even though no logs arrive.Logging bucket configuration mismatches
Log delivery can silently fail if the destination bucket has restrictive policies or mismatched ACL settings, even when the Terraform config looks correct. The bucket can be in any region, but that doesn't exempt it from the ACL and policy requirements. After enabling logging, verify actual log files are appearing in the bucket before treating the control as satisfied.
Confusing standard logging with real-time logging
CloudFront supports both standard logging (to S3, via
logging_config) and real-time logging (to Kinesis Data Streams, viaaws_cloudfront_realtime_log_config). This control checks forlogging_configspecifically. A distribution with only a real-time log config attached does not pass, regardless of how comprehensive that config is.Deprecated inline syntax in older modules
Some legacy Terraform modules omit the
logging_configblock entirely or gate it behind a variable that defaults tonull. When importing existing distributions into Terraform state, don't assume the module handles logging by default. Confirm thelogging_configblock is explicit in both state and config.
Audit evidence
Config rule evaluation results showing each distribution as COMPLIANT are the standard starting point, or an equivalent report from a CSPM tool. Supporting evidence should include an S3 bucket listing with actual log files and recent timestamps matching the distribution ID prefix, confirming delivery is working, not just configured. Console screenshots of the distribution's General settings tab with "Standard logging" set to "On" and a valid S3 destination are also accepted. For environments with many distributions, a bulk export from aws cloudfront list-distributions cross-referenced against each distribution's Logging configuration covers the full inventory efficiently.
Framework-specific interpretation
PCI DSS v4.0: CloudFront distributions serving payment pages or APIs are system components under Requirement 10. Every request to those distributions must be logged to support forensic investigation and the daily log review process PCI DSS mandates.
HIPAA Omnibus Rule 2013: 45 CFR 164.312(b) requires audit controls that record and examine activity in systems containing ePHI. For content delivered through CloudFront, access logs are the request-level record of what was served, to whom, and when, which is the evidence that audit control requires.
NIST Cybersecurity Framework v2.0: DE.CM calls for continuous monitoring of your environment for anomalies. CloudFront access logs feed that monitoring directly, giving you traffic patterns and edge behavior for anything served through the distribution.
Related controls
Neptune DB clusters should publish audit logs to CloudWatch Logs
CloudFront distributions should use SNI to serve HTTPS requests
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
cloudfront_distribution_logging_enabledAWS Config Managed Rule:
CLOUDFRONT_ACCESSLOGS_ENABLEDCheckov Check:
CKV_AWS_86Powerpipe Control:
aws_compliance.control.cloudfront_distribution_logging_enabledProwler Check:
cloudfront_distributions_logging_enabledAWS Security Hub Control:
CloudFront.5KICS Query:
94690d79-b3b0-43de-b656-84ebef5753e5Trivy Check:
AWS-0010
Last reviewed: 2026-03-08