DevOps.Academy
CoursesCurriculumPricing

    Loading…

    ↑ ↓ move · ↵ open · Ctrl K anywhere

    ◔My learningSign in
    DevOps.Academy

    Free, hands-on DevOps lessons. Made with care in India.

    Learn

    All coursesLinux roadmapCurriculumMy learning

    Academy

    PricingCertificates

    Legal

    PrivacyTermsContact

    devops.rajeev.pro

    AWS for DevOpsLesson 9 of 17
    Your progress · 0%
    On this page
    1. Why a CDN
    2. Create a distribution
    3. The origin
    4. Caching and invalidations
    5. Your own domain and HTTPS
    6. Code at the edge
    7. Signed URLs, geo restriction and origin failover
    ↖ Course roadmap
    Lesson 9 · CloudFront

    CloudFront: a fast edge in front of your app

    Put a CDN in front of a private S3 bucket: walk the create-distribution wizard, keep the bucket private with Origin Access Control, add HTTPS with ACM and clear the cache after a deploy.

    30 min read · intermediate · hands-on

    By the end of this lesson you'll be able to

    0 of 6 complete

    Why a CDN

    Your S3 bucket from lesson 6 lives in Mumbai. A visitor in Mumbai gets files quickly; one in São Paulo waits for every byte to cross the planet. CloudFront is AWS's CDN (content delivery network): hundreds of edge locations worldwide keep cached copies of your files, so each visitor is served from one nearby. It also gives you HTTPS on your own domain, a web application firewall, and a way to keep the bucket private.

    visitor → nearest edge location ──(cache hit)──→ file
                        └──(cache miss)──→ origin (private S3 bucket or ALB) → cached for next time
    

    The screenshots below are the real create-distribution wizard in a practice account, walked to the final Review step. That account hadn't yet been verified for CloudFront, which AWS requires before a new account's first distribution, so this lesson stops at Review. If your new account gets the same error, open an Account and billing support case asking AWS to verify it.

    Create a distribution

    CloudFront → Distributions → Create distribution. The first choice is how to pay:

    (1) Flat-rate plans or pay as you go. (2) The Free plan covers a small site: CDN, WAF and up to 100 GB a month.© Screenshot: DevOps Academy

    (1) Flat-rate plans or pay as you go. (2) The Free plan covers a small site: CDN, WAF and up to 100 GB a month.© Screenshot: DevOps Academy

    Flat-rate plans bundle the CDN, WAF, DNS and logging at a fixed monthly price with no overage charges. Pay as you go bills each request and GB separately: cheapest at very low volume, but with no spending cap. For a learning project or a small site, Free is the safe choice.

    (1) A name, stored as a tag. (2) One configuration for one site.© Screenshot: DevOps Academy

    (1) A name, stored as a tag. (2) One configuration for one site.© Screenshot: DevOps Academy

    The origin

    The origin is where CloudFront fetches files it hasn't cached yet: an S3 bucket, a load balancer, API Gateway, a Lambda function, or any public URL.

    (1) An S3 origin. (2) The bucket's domain name; Browse S3 picks it from a list.© Screenshot: DevOps Academy

    (1) An S3 origin. (2) The bucket's domain name; Browse S3 picks it from a list.© Screenshot: DevOps Academy

    (1) Origin Access Control: the bucket stays private, readable only by this distribution. (2) Recommended origin and cache settings for S3.© Screenshot: DevOps Academy

    (1) Origin Access Control: the bucket stays private, readable only by this distribution. (2) Recommended origin and cache settings for S3.© Screenshot: DevOps Academy

    Origin Access Control (OAC) is the important part. CloudFront signs its requests to S3, and the wizard adds a bucket policy that allows s3:GetObject only for this distribution:

    {
      "Effect": "Allow",
      "Principal": { "Service": "cloudfront.amazonaws.com" },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-site-bucket/*",
      "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/E1ABCDEF" } }
    }
    

    Block Public Access stays on (lesson 6), and nobody can skip the CDN and read the bucket directly.

    (1) WAF protections included in the plan. (2) Monitor mode counts would-be blocks first, so you can check nothing legitimate gets caught.© Screenshot: DevOps Academy

    (1) WAF protections included in the plan. (2) Monitor mode counts would-be blocks first, so you can check nothing legitimate gets caught.© Screenshot: DevOps Academy

    (1) Billing: Free, $0. (2) Create distribution. A new distribution takes a few minutes to deploy to every edge.© Screenshot: DevOps Academy

    (1) Billing: Free, $0. (2) Create distribution. A new distribution takes a few minutes to deploy to every edge.© Screenshot: DevOps Academy

    When it's created you get a domain like d1234abcd.cloudfront.net; open it and you get index.html from the nearest edge. Set the distribution's default root object to index.html so / works.

    Caching and invalidations

    A behavior maps a path pattern (/api/*, *.js, default *) to an origin and a cache policy: how long to keep files (TTL) and what makes two requests "the same" (the cache key: path, plus any headers, cookies or query strings you include). Keep the cache key small; every extra header splits the cache.

    ContentTypical policy
    app.3f9c2e1.js, images with versioned namescache for a year: the name changes when the file does
    index.htmlshort TTL, or invalidate on every deploy
    /api/* to an ALBCachingDisabled, forward the headers and cookies the app needs

    After a deploy, clear old copies with an invalidation:

    $ aws s3 sync ./build s3://my-site-bucket/ --delete
    $ aws cloudfront create-invalidation --distribution-id E1ABCDEF --paths "/index.html"
    
    aws s3 sync ./build s3://my-site-bucket/ --delete
    • awsthe AWS command line

    Response headers tell you what happened: X-Cache: Hit from cloudfront means an edge served it, Miss from cloudfront means it went to the origin.

    Your own domain and HTTPS

    To use www.example.com instead of the cloudfront.net name:

    1. Request a public certificate in ACM in us-east-1 (N. Virginia) for the domain. CloudFront only reads certificates from that Region, wherever your origin is.
    2. Prove you own the domain with the DNS record ACM gives you (one click if the domain is in Route 53).
    3. Add the domain as an alternate domain name on the distribution and pick the certificate.
    4. Point the domain at the distribution with a Route 53 alias record (lesson 8).

    ACM in N. Virginia: Request a public certificate. Public ACM certificates are free and renew themselves.© Screenshot: DevOps Academy

    ACM in N. Virginia: Request a public certificate. Public ACM certificates are free and renew themselves.© Screenshot: DevOps Academy

    Code at the edge

    CloudFront Functions: small JavaScript functions that run at every edge location.© Screenshot: DevOps Academy

    CloudFront Functions: small JavaScript functions that run at every edge location.© Screenshot: DevOps Academy
    CloudFront FunctionsLambda@Edge
    Runsat every edge location, under 1 msat regional edge caches, up to seconds
    LanguageJavaScript onlyNode.js or Python
    Canrewrite URLs, add headers, redirect, simple auth checkscall other services, read the body, generate responses
    Costvery low, per million invocationshigher, like Lambda

    A typical function adds security headers or rewrites /about to /about/index.html for a static site.

    In production

    Keep the bucket private behind OAC, serve only HTTPS (redirect HTTP), use versioned file names so you rarely need invalidations, turn on standard logging or real-time logs, attach WAF rules, and define the distribution in Terraform or CloudFormation. For an API behind an ALB, use a caching-disabled behavior and allow only CloudFront to reach the ALB.

    Signed URLs, geo restriction and origin failover

    CloudFront signed URLs grant one path for a short time; signed cookies grant a set of paths to a browser. Geo restriction is a coarse country allow or deny list, not application authorisation. Origin failover switches to a secondary origin for configured errors, so the fallback must contain compatible content.

    $ aws cloudfront get-distribution-config --id "$DISTRIBUTION_ID" \
      --query 'DistributionConfig.{Origins:Origins.Items[].DomainName,Restrictions:Restrictions}'
    
    aws cloudfront get-distribution-config --id "$DISTRIBUTION_ID" \
    • awsthe AWS command line
    ⌘
    Mini mission

    A private bucket behind a CDN

    Create a private S3 bucket with an index.html, walk CloudFront's create-distribution wizard with that bucket as the origin and private access allowed, and stop at Review to check every setting. If your account is verified for CloudFront, create it, load the page through the cloudfront.net domain, then disable and delete the distribution and the bucket.

    Input: An AWS account with the console and AWS CLIOutput: A Review page showing the Free plan, your S3 origin and private bucket access; if created, your page served from a cloudfront.net URL
    Reveal one safe solution
    $ BUCKET=academy-cf-$(aws sts get-caller-identity --query Account --output text)-$RANDOM
    $ aws s3api create-bucket --bucket $BUCKET --region ap-south-1 --create-bucket-configuration LocationConstraint=ap-south-1
    $ printf '<h1>Served by CloudFront</h1>\n' > index.html
    $ aws s3 cp index.html s3://$BUCKET/index.html --content-type text/html
    $ echo "Origin: $BUCKET.s3.ap-south-1.amazonaws.com"
    $ # Console: CloudFront → Create distribution → Free → name → S3 origin above,
    $ #          Allow private S3 bucket access → Next → Next → Review (→ Create distribution)
    $ # If created: curl -sI https://<distribution>.cloudfront.net/index.html | grep -i x-cache
    $ # Clean up: disable the distribution, wait for Deployed, delete it; then:
    $ aws s3 rb s3://$BUCKET --force
    
    aws s3api create-bucket --bucket $BUCKET --region ap-south-1 --create-bucket-configuration LocationConstraint=ap-south-1
    • awsthe AWS command line
    • --regionwhich Region
    printf '<h1>Served by CloudFront</h1>\n' > index.html
    • >write output to a file, replacing it
    echo "Origin: $BUCKET.s3.ap-south-1.amazonaws.com"
    • echoprint text
    # If created: curl -sI https://<distribution>.cloudfront.net/index.html | grep -i x-cache
    • |pipe: send output to the next command
    • grepfind lines that match a pattern
    • -iignore upper/lower case

    The first curl after creating says Miss from cloudfront, the second Hit from cloudfront: the second request never reached your bucket.

    Try it yourself

    0 of 6 steps done

    Run each task in your own account or terminal, then tick it off.

    Knowledge check

    Quick check

    Question 1 of 5

    Why put CloudFront in front of an S3 website instead of serving the bucket directly?

    Go deeper

    Official reading for this lesson

    • DocsWhat is Amazon CloudFront?AWS Docs ↗
    • DocsRestrict access to an Amazon S3 origin (OAC)AWS Docs ↗
    • DocsCache policiesAWS Docs ↗
    • DocsInvalidate filesAWS Docs ↗
    • DocsChoosing between CloudFront Functions and Lambda@EdgeAWS Docs ↗

    Or get every quiz answer right and it completes itself.

    ← PreviousRoute 53: DNS for your appsNext lesson →Managed databases: RDS, DynamoDB, ElastiCache