Skip to content
AWS aws dns-cdn 5 min read

Setting Up a CloudFront Distribution

Amazon CloudFront is a CDN (Content Delivery Network — a worldwide network of servers that cache your content close to users). A “distribution” is the CloudFront object you create to put that network in front of your application. Once it exists, visitors hit a nearby edge location instead of travelling all the way to your origin server, which makes pages load faster and shields your origin from traffic spikes. This page walks through creating a distribution end-to-end, with HTTPS and a custom domain, in both the AWS Management Console and the AWS CLI.

Key concepts before you start

A distribution ties together a handful of settings. You need to understand four of them.

SettingWhat it meansTypical value
OriginThe source CloudFront pulls content fromAn S3 bucket, an Application Load Balancer, or any public domain
Default cache behaviorRules for how requests are matched and cachedPath pattern *, caching enabled
Viewer protocol policyHow CloudFront handles HTTP vs HTTPS from browsersredirect-to-https
Alternate domain name (CNAME)The custom domain you want, e.g. cdn.example.comPlus an ACM certificate

The single most common CloudFront mistake: the ACM (AWS Certificate Manager) certificate for a CloudFront custom domain MUST be created in the us-east-1 (N. Virginia) Region — no matter where your origin or your users are. A certificate in any other Region simply will not appear in the CloudFront dropdown. If your cert is missing, this is almost always why.

When to use a CloudFront distribution

Reach for CloudFront when you serve a global audience, want to offload traffic from your origin, need free HTTPS at the edge, or want to absorb traffic bursts. It is the standard front door for static websites on S3, single-page apps, image and video assets, and APIs that benefit from edge caching.

Do not bother when your audience is entirely in one region and latency is fine, or when every response is unique per user and cannot be cached at all (a pure dynamic API to local users). In those cases the extra hop and configuration add complexity for little gain.

Step 1 - prepare the certificate (us-east-1)

Before creating the distribution, request a certificate so it is ready to attach. Request it in us-east-1.

aws acm request-certificate \
  --domain-name cdn.example.com \
  --validation-method DNS \
  --region us-east-1

Output:

{
    "CertificateArn": "arn:aws:acm:us-east-1:111122223333:certificate/0a1b2c3d-4e5f-6789-abcd-ef0123456789"
}

Then add the DNS validation record ACM gives you (a CNAME) to your domain. Once the certificate status becomes ISSUED, you can attach it. See ACM certificates for the full validation walkthrough.

Step 2 - create the distribution (Console)

  1. Open the CloudFront console and choose Create distribution.
  2. Under Origin, set Origin domain to your source — for example your S3 bucket (my-site.s3.amazonaws.com) or load balancer DNS name. The dropdown lists your AWS resources, or you can type any public domain.
  3. For an S3 origin, choose Origin access control settings (recommended) and create an OAC so the bucket stays private. For a custom origin, set the Protocol (HTTPS only is best).
  4. Under Default cache behavior, set Viewer protocol policy to Redirect HTTP to HTTPS.
  5. Under Cache key and origin requests, pick a cache policy — CachingOptimized is a good default for static content.
  6. Under Settings, add your Alternate domain name (CNAME): cdn.example.com.
  7. For Custom SSL certificate, choose the ACM certificate you created in us-east-1. (If it is not listed, the cert is in the wrong Region or not yet ISSUED.)
  8. Optionally set a Default root object of index.html.
  9. Choose Create distribution.

The distribution starts with status Deploying. It takes several minutes to propagate to every edge location worldwide. You can use it as soon as the status changes to Enabled.

Step 3 - create the distribution (CLI)

The CLI takes a JSON config. Save the following as dist-config.json, adjusting the origin domain, CNAME, and certificate ARN.

{
  "CallerReference": "my-site-2026-06-15",
  "Aliases": { "Quantity": 1, "Items": ["cdn.example.com"] },
  "DefaultRootObject": "index.html",
  "Origins": {
    "Quantity": 1,
    "Items": [
      {
        "Id": "s3-origin",
        "DomainName": "my-site.s3.amazonaws.com",
        "S3OriginConfig": { "OriginAccessIdentity": "" }
      }
    ]
  },
  "DefaultCacheBehavior": {
    "TargetOriginId": "s3-origin",
    "ViewerProtocolPolicy": "redirect-to-https",
    "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
    "Compress": true
  },
  "ViewerCertificate": {
    "ACMCertificateArn": "arn:aws:acm:us-east-1:111122223333:certificate/0a1b2c3d-4e5f-6789-abcd-ef0123456789",
    "SSLSupportMethod": "sni-only",
    "MinimumProtocolVersion": "TLSv1.2_2021"
  },
  "Comment": "Static site CDN",
  "Enabled": true
}

The CachePolicyId above is the managed CachingOptimized policy ID, which is the same in every account. The CallerReference just has to be a unique string. Now create it.

aws cloudfront create-distribution \
  --distribution-config file://dist-config.json

Output:

{
    "Distribution": {
        "Id": "E2QWRUHEXAMPLE",
        "ARN": "arn:aws:cloudfront::111122223333:distribution/E2QWRUHEXAMPLE",
        "Status": "InProgress",
        "DomainName": "d111111abcdef8.cloudfront.net",
        ...
    }
}

Note the DomainName (d111111abcdef8.cloudfront.net) — that is the CloudFront endpoint you point your custom domain at.

Step 4 - point your domain at CloudFront

Create a DNS record so cdn.example.com resolves to the distribution. In Route 53, create an A record with Alias = Yes targeting the CloudFront distribution. Using an alias (instead of a plain CNAME) is free and lets you alias the apex domain too.

aws route53 change-resource-record-sets \
  --hosted-zone-id Z0123456789ABC \
  --change-batch '{
    "Changes": [{
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "cdn.example.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "DNSName": "d111111abcdef8.cloudfront.net",
          "EvaluateTargetHealth": false
        }
      }
    }]
  }'

The HostedZoneId of Z2FDTNDATAQYW2 is a fixed, special value that always means “CloudFront” — use it verbatim for any CloudFront alias.

Updating and deploying changes

Any change you make — a new cache policy, an added origin, a swapped certificate — must be applied with update-distribution, and it again enters InProgress while it rolls out to all edges. Expect a few minutes before the change is live everywhere; this is normal and not a failure.

Cost note: There is no charge for the distribution itself or for ACM certificates used with CloudFront. You pay only for data transfer out to the internet (roughly $0.085/GB in North America/Europe, tiered down with volume) and per 10,000 HTTPS requests (about $0.01). A low-traffic site usually costs cents per month, and the first 1 TB/month of transfer is on the AWS Free Tier.

Best practices

  • Always create the ACM certificate in us-east-1 for CloudFront, no matter where the origin lives.
  • Set Viewer protocol policy to redirect-to-HTTPS so no visitor is served plaintext.
  • For S3 origins, use Origin Access Control (OAC) and keep the bucket private — never make the bucket public.
  • Enable Compress objects automatically to shrink text assets and lower transfer cost.
  • Use Route 53 alias records, not CNAMEs, to point your domain (free and works at the apex).
  • Pin MinimumProtocolVersion to TLSv1.2_2021 or higher to drop weak, outdated TLS.
  • Wait for status Enabled / Deployed before testing — a fresh distribution needs several minutes to propagate.
Last updated June 15, 2026
Was this helpful?