Skip to main content
This guide demonstrates how to use Amazon CloudFront to cache an object stored in an S3 bucket so it is served from CloudFront edge locations instead of being fetched from S3 on every request. You’ll learn how to configure the S3 origin, create a CloudFront distribution, replace the origin object, and control cache behavior with TTLs and invalidations. Quick overview:
  • Store an image in S3 (the origin).
  • Create a CloudFront distribution that points to the S3 bucket.
  • Request the image using the CloudFront domain to cache it at edge locations.
  • Replace the origin object and observe how cached content persists until TTL expiry or an invalidation.

Create the S3 origin

First, create an S3 bucket to host the object(s) that will act as the CloudFront origin.
A screenshot of the AWS S3 Management Console open to the "Create bucket" page showing general configuration fields (Bucket name, AWS Region) and object ownership/ACL options. The bucket name "myawsbucket" is entered and the region is set to US East (N. Virginia).
Example: I used a bucket name like codeclouddemo123 and the default region. For this demo we will temporarily allow public access so you can verify the object via a browser. In production, prefer Origin Access Control (OAC) so only CloudFront can retrieve objects from S3.
For demos you may set objects to public, but this is not recommended for production. Use OAC (Origin Access Control) or OAI and fine-grained bucket policies to restrict direct S3 access.

Upload an image to the bucket

Upload an image file to the bucket (for this demo the filename is car.jpg). After uploading, S3 will provide an object URL. If the object is not publicly accessible, opening the object URL returns an Access Denied XML error like:
Options to make the object reachable from a browser:
  • Temporarily make the object or bucket publicly readable (not recommended long-term).
  • Use CloudFront with Origin Access Control (recommended): CloudFront fetches objects from S3 using OAC and S3 blocks public access.
For a quick verification, you can upload with public ACL (demo only):

Create a folder (optional)

If you want CloudFront to cache a specific path within the bucket, create a folder and place objects there. You can then set an origin path when configuring CloudFront.
A screenshot of the AWS S3 console's "Create folder" page showing a folder named "images" being created, with server-side encryption options and S3 navigation/menu on the left.
If the origin path is left blank, CloudFront treats the entire bucket as the origin.

Create the CloudFront distribution

Create a CloudFront distribution and point its origin to the S3 bucket you created. When configuring the origin choose:
  • Origin domain: your S3 bucket endpoint (e.g., codeclouddemo123.s3.us-east-1.amazonaws.com)
  • Optional origin path: e.g., /images to limit CloudFront to a subfolder
  • Access type: Public or Restricted (use OAC for restricted)
  • Origin Shield and custom headers as required
A screenshot of the AWS CloudFront console showing the origin configuration for an S3 bucket (kodeklouddemo123.s3.us-east-1.amazonaws.com). Visible options include an origin path field, origin access set to "Public", add‑header button, and Origin Shield settings.
Key distribution settings to review:
  • Compression: enable Gzip/Brotli to reduce transfer sizes for compressible assets.
  • Viewer protocol policy: redirect HTTP to HTTPS or require HTTPS (recommended).
  • Allowed HTTP methods: GET/HEAD for static objects; add others only if needed.
  • Price class: limit edge locations for cost management.
  • TLS, HTTP protocol versions, and IPv6: enable per your needs.
  • Cache behaviors: map URL patterns to specific caching policies and behaviors.
Create the distribution and wait for deployment. When ready you’ll receive a domain name and distribution ID, for example:

Access the object through CloudFront

Request the image using the distribution domain plus the object path: https://d3o26icowwpbm9.cloudfront.net/car.jpg Note: Browsing to the distribution root (e.g., https://d3o26icowwpbm9.cloudfront.net/) will not show the image unless you configure an index document or set a default behavior that maps to an object. You must request the exact object path. How it works:
  • If the image is cached at the nearest edge, CloudFront serves the cached copy.
  • If not cached, CloudFront fetches the object from the S3 origin, caches it, and serves it to the client.

Replace the object at the origin

To demonstrate caching, replace the original object in S3 with a new file using the same key (car.jpg). For example, upload a new car.jpg containing different content (e.g., a red car vs. a blue car). S3 now returns the new object at the same key.
A screenshot of the AWS S3 "Upload" page showing one file, car.jpg (2.7 MB), queued for upload to the bucket s3://kodeklouddemo123. The interface shows file details and Upload/Add files/Add folder buttons.
If you open the S3 object URL directly you will see the updated (red) image. However, requests via CloudFront may continue to return the old (blue) cached image until the cached entry expires.

Cache TTL and cache policy

CloudFront cache behavior is controlled by the cache policy attached to a behavior. The policy defines TTL values and which headers, cookies, or query strings are included in the cache key. For example, the managed “CachingOptimized” policy often uses a default TTL of 86,400 seconds (one day):
A screenshot of the AWS CloudFront console displaying the "Managed-CachingOptimized" policy details, including TTL settings and cache key configuration. The page shows compression support (Gzip and Brotli enabled) and the CloudFront navigation sidebar.
Because of TTLs, CloudFront will serve the cached copy until the TTL expires and it revalidates with the origin (unless you force refresh the cache). Recommended cache settings (summary)

Force an update with invalidation

To immediately remove a cached object from CloudFront edge locations, create an invalidation. This instructs CloudFront to evict the specified object(s) from all edge caches so subsequent requests fetch the updated object from the origin. Console steps:
  1. Open your CloudFront distribution and go to the Invalidations tab.
  2. Create an invalidation and specify paths to remove.
Examples of invalidation paths:
CLI example to create an invalidation:
Notes about invalidations:
  • Wildcards like /* or /images/* are supported.
  • Invalidations take time to propagate to all edge locations.
  • Frequent or large invalidations can increase costs; consider cache-control headers or versioned filenames instead.
When the invalidation completes, requests to https://d3o26icowwpbm9.cloudfront.net/car.jpg will return the updated image from the origin.
Screenshot of the AWS CloudFront web console showing an invalidation details page. It indicates an invalidation (object path /*) was created on August 26, 2023 and its status is Completed.

Notes and best practices

  • For production, prefer Origin Access Control (OAC) so S3 objects are only retrievable by CloudFront.
  • Use Cache-Control headers and appropriate TTLs to balance freshness and performance.
  • Use versioned filenames (e.g., image-v1.jpg → image-v2.jpg) to avoid frequent invalidations and simplify cache management.
Additional links and references

Conclusion

This lesson covered:
  • Uploading an object to S3 and exposing it as a CloudFront origin.
  • Creating a CloudFront distribution to cache the object at edge locations.
  • Replacing the origin object and understanding CloudFront caching and TTL behavior.
  • Creating invalidations to force CloudFront to fetch updated objects before TTL expiration.
You can apply these steps to host static websites, serve images, and accelerate static assets for web apps using S3 + CloudFront.

Watch Video