How to Securely Serve Static Content with AWS CloudFront and S3

A step-by-step guide to setting up a secure and efficient content delivery network.

Dataflow Map

This diagram illustrates the secure data flow from a user's browser to your private S3 bucket, facilitated by CloudFront.

User Browser -> CloudFront Edge Location
|
Cache Check
|
Cache Hit -> Content Served to User
OR
Cache Miss -> CloudFront Origin Request
|
Uses OAC to access private S3 bucket
|
S3 Bucket -> Content Returned to CloudFront
|
CloudFront Caches Content
|
Content Served from Cache to User

Step 1: Prepare Your S3 Bucket

The first step is to have an S3 bucket with the content you want to distribute.

  1. **Create an S3 Bucket:** Go to the AWS Management Console, navigate to the S3 service, and create a new bucket. Choose a globally unique name.
  2. **Upload Content:** Upload all the static content (HTML, CSS, JavaScript files, images, etc.) that you want to serve through CloudFront.
  3. **Configure Access:** Ensure that **"Block all public access"** is enabled for the bucket. This is a critical security measure. CloudFront will be granted access later, but the bucket itself will remain private.

Step 2: Create an Origin Access Control (OAC)

An OAC is a recommended feature that securely connects your CloudFront distribution to your S3 bucket.

  1. **Navigate to CloudFront:** In the AWS Management Console, go to the CloudFront service.
  2. **Create an OAC:** In the left-hand navigation pane, under **Security**, select **Origin access**. Click **Create control setting**.
  3. **Configure OAC:**
    • **Name:** Provide a descriptive name for your OAC (e.g., `my-s3-bucket-oac`).
    • **Origin type:** Select **S3**.
    • Click **Create**.
  4. **Copy the Policy:** After the OAC is created, CloudFront will display a bucket policy. **Copy this policy** to your clipboard. This policy grants CloudFront permission to read files from your private S3 bucket.

Step 3: Create the CloudFront Distribution

This is where you define how CloudFront will serve your content.

  1. **Start a New Distribution:** In the CloudFront console, select **Distributions** from the left-hand menu, then click **Create distribution**.
  2. **Configure Origin:**
    • **Origin domain:** Select your S3 bucket.
    • **Name:** The origin ID will be automatically populated.
    • **Origin access:** Choose **Origin access control settings (recommended)**.
    • **Origin access control:** Select the OAC you created in the previous step.
    • **Bucket policy:** CloudFront will prompt you to update the S3 bucket policy. Click **Copy policy** and then **Go to S3 bucket permissions**. Paste the policy into the Bucket policy editor and save.
  3. **Configure Default Cache Behavior:**
    • **Viewer protocol policy:** Select **Redirect HTTP to HTTPS**.
    • **Allowed HTTP methods:** Select **GET, HEAD**.
    • **Cache policy:** Choose **CachingOptimized**.
  4. **Configure Other Settings:**
    • **Distribution settings:** You can optionally add a **Default root object** (e.g., `index.html`).
    • **Price class:** Select the price class that best suits your needs.
    • **WAF:** You can optionally enable WAF for an extra layer of security.
  5. **Create Distribution:** Click **Create distribution**.

Step 4: Test Your CloudFront Distribution

The final step is to test your new distribution to ensure it's working correctly.

  1. **Wait for Deployment:** CloudFront distributions take some time to deploy. The status will show as `Deploying`.
  2. **Get the Domain Name:** Once the status changes to `Deployed`, go back to the list of distributions. Copy the **Distribution domain name**. It will look like `d1234abcd.cloudfront.net`.
  3. **Access Your Content:** Paste this domain name into your browser's address bar. If you configured a default root object, you'll see your website. Otherwise, append the path to one of your files (e.g., `d1234abcd.cloudfront.net/your-image.jpg`).