Skip to content

CloudFront distributions should use SNI to serve HTTPS requests

SNI allows multiple domains to share the same IP address during the TLS handshake, which is how virtually all modern clients negotiate HTTPS connections. Choosing dedicated IP (vip) instead of SNI adds extra cost per distribution and provides no security benefit. The only reason to use a dedicated IP is to support legacy clients that predate SNI (pre-2010 era browsers), which are vanishingly rare in production traffic today.

Using SNI reduces your public IP footprint, which simplifies network inventory and minimizes the attack surface exposed through CloudFront edge locations.

Retrofit consideration

Switching from vip to sni-only on a live distribution propagates across CloudFront edge locations over a few minutes. Any client without SNI support will get connection errors after the change takes effect. These clients are extremely rare, but check your traffic logs before switching a high-traffic distribution.

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  = "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"

  viewer_certificate = {
    ssl_support_method = "sni-only"
  }
}

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

  wait_for_deployment = false
  web_acl_id          = "arn:aws:wafv2:us-east-1:123456789012:regional/webacl/example/12345678-1234-1234-1234-123456789012"

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

What this control checks

In the aws_cloudfront_distribution resource, the viewer_certificate block controls how HTTPS is terminated. When a custom certificate is attached via acm_certificate_arn or iam_certificate_id, ssl_support_method must be set to "sni-only". Setting it to "vip" fails the control. If the distribution uses the default CloudFront certificate (cloudfront_default_certificate = true), the control does not apply because no custom certificate is associated. A passing configuration: viewer_certificate with acm_certificate_arn pointing to a valid ACM ARN, ssl_support_method set to "sni-only", and minimum_protocol_version set to a policy such as "TLSv1.2_2021".

Common pitfalls

  • Omitting ssl_support_method defaults to error, not sni-only

    Terraform requires ssl_support_method when acm_certificate_arn or iam_certificate_id is specified. Omitting it causes a plan error, not a silent default to "sni-only". You cannot accidentally deploy without choosing, but copy-paste from older examples will often include "vip" explicitly, so review any inherited configuration before applying.

  • Default certificate distributions are not flagged

    Distributions using cloudfront_default_certificate = true serve HTTPS through CloudFront's default certificate. This control only applies when a custom certificate is associated, so default-cert distributions pass automatically but may have other issues like a missing branded domain.

  • Switching from vip to sni-only on an existing distribution

    The update is in-place with no downtime for SNI-capable clients, but propagation across edge locations takes several minutes. Any client without SNI support will get connection errors immediately after the change takes effect. Pre-2010 browsers are the main culprits; check your traffic logs before switching a high-traffic distribution.

Audit evidence

Auditors typically want either AWS Config rule evaluation results showing all distributions pass the SNI check, or a CloudFront console export of each distribution's SSL/TLS settings. The ViewerCertificate.SSLSupportMethod field from the GetDistribution API should return sni-only for every custom-certificate distribution. Output from Prowler or Turbot Pipes confirming no distributions use vip works as corroborating evidence.

Framework-specific interpretation

PCI DSS v4.0: Requirement 4.2.1 mandates strong cryptography for PAN in transit across open, public networks. CloudFront distributions serving cardholder data must use properly configured TLS, and ssl_support_method = "sni-only" is what QSA examiners expect to see. The dedicated-IP method is deprecated with no security benefit; using it invites unnecessary scrutiny during an assessment.

Tool mappings

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

  • Compliance.tf Control: cloudfront_distribution_sni_enabled

  • AWS Config Managed Rule: CLOUDFRONT_SNI_ENABLED

  • Powerpipe Control: aws_compliance.control.cloudfront_distribution_sni_enabled

  • Prowler Check: cloudfront_distributions_https_sni_enabled

  • AWS Security Hub Control: CloudFront.8

Last reviewed: 2026-03-09