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
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.
This control is enforced automatically with Compliance.tf modules. Start free trial
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 BucketOwnerEnforced setting) and must grant the CloudFront log delivery canonical user permission to write objects and read bucket ACLs. If you use aws_s3_bucket_ownership_controls with object_ownership set to BucketOwnerEnforced, 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, via aws_cloudfront_realtime_log_config). This control checks for logging_config specifically. 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_config block entirely or gate it behind a variable that defaults to null. When importing existing distributions into Terraform state, don't assume the module handles logging by default. Confirm the logging_config block 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
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
- Compliance.tf Control:
cloudfront_distribution_logging_enabled - AWS Config Managed Rule:
CLOUDFRONT_ACCESSLOGS_ENABLED - Checkov Check:
CKV_AWS_86 - Powerpipe Control:
aws_compliance.control.cloudfront_distribution_logging_enabled - Prowler Check:
cloudfront_distributions_logging_enabled - AWS Security Hub Control:
CloudFront.5 - KICS Query:
94690d79-b3b0-43de-b656-84ebef5753e5 - Trivy Check:
AWS-0010
Last reviewed: 2026-03-08