Lab: Optimizing Content Delivery with Amazon CloudFront and S3
Optimize applications by using AWS services and features
Lab: Optimizing Content Delivery with Amazon CloudFront and S3
In this lab, you will learn how to optimize application performance by reducing latency and offloading traffic from your origin using Amazon CloudFront. You will set up an S3 bucket as an origin, distribute content via a global CDN, and verify caching behavior.
[!WARNING] Remember to run the teardown commands at the end of this lab to avoid ongoing charges for CloudFront distributions and S3 storage.
Prerequisites
- AWS Account: An active AWS account.
- AWS CLI: Installed and configured with
AdministratorAccesspermissions. - Region: We will use
us-east-1for this lab. - Tools:
curlinstalled on your local machine to test headers.
Learning Objectives
- Configure an S3 Bucket as a private origin for static content.
- Deploy an Amazon CloudFront Distribution with Origin Access Control (OAC).
- Optimize performance by configuring Cache Behaviors.
- Verify caching efficiency using CloudFront Response Headers.
Architecture Overview
Step-by-Step Instructions
Step 1: Create the Origin S3 Bucket
We need a bucket to host our static assets (the "Origin").
# Generate a unique suffix
RANDOM_ID=$RANDOM
BUCKET_NAME="brainybee-lab-origin-$RANDOM_ID"
# Create the bucket
aws s3 mb s3://$BUCKET_NAME --region us-east-1▶Console alternative
- Navigate to S3 > Buckets > Create bucket.
- Name:
brainybee-lab-origin-<your-id>. - Region:
us-east-1. - Keep default settings (Block all public access) and click Create bucket.
Step 2: Upload Content and Set Metadata
To see caching in action, we will upload an HTML file and set a Cache-Control header.
echo "<h1>Hello from Optimized AWS!</h1>" > index.html
aws s3 cp index.html s3://$BUCKET_NAME/index.html \
--cache-control "max-age=3600"Step 3: Create CloudFront Origin Access Control (OAC)
OAC ensures that users cannot bypass CloudFront to access your S3 bucket directly.
aws cloudfront create-origin-access-control \
--origin-access-control-config '{"Name": "LabOAC", "Description": "Access for Lab", "SigningProtocol": "sigv4", "SigningBehavior": "always", "OriginAccessControlOriginType": "s3"}'[!IMPORTANT] Note the
Idfrom the output; you will need it for the next step.
Step 4: Create the CloudFront Distribution
This command creates a global distribution. For the purpose of this lab, we will use a simplified configuration.
# Replace <BUCKET_NAME> and <OAC_ID> with your values
aws cloudfront create-distribution \
--origin-domain-name $BUCKET_NAME.s3.us-east-1.amazonaws.com \
--default-root-object index.html▶Console alternative (Recommended for Step 4)
- Go to CloudFront > Distributions > Create distribution.
- Origin domain: Select your S3 bucket.
- Origin access: Select Origin access control settings (recommended).
- Click Create control setting > Create.
- Web Application Firewall (WAF): Select "Do not enable security protections" (to save costs for this lab).
- Default root object:
index.html. - Click Create distribution.
Step 5: Update S3 Bucket Policy
CloudFront needs permission to read from your S3 bucket. After creating the distribution, copy the generated policy from the CloudFront console or use the following template.
# Replace placeholders with your Distribution ARN and Bucket Name
POLICY='{"Version":"2012-10-17","Statement":[{"Sid":"AllowCloudFrontServicePrincipalReadOnly","Effect":"Allow","Principal":{"Service":"cloudfront.amazonaws.com"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::'$BUCKET_NAME'/*","Condition":{"StringEquals":{"AWS:SourceArn":"<YOUR_DISTRIBUTION_ARN>"}}}]}'
aws s3api put-bucket-policy --bucket $BUCKET_NAME --policy "$POLICY"Checkpoints
Checkpoint 1: Verification of Distribution
- Wait for the CloudFront Distribution status to change from
InProgresstoEnabled(approx. 3-5 mins). - Copy the Distribution Domain Name (e.g.,
d111111abcdef8.cloudfront.net).
Checkpoint 2: Testing Cache Efficiency
Run the following command twice in your terminal:
curl -I https://<YOUR_DISTRIBUTION_DOMAIN>/index.htmlExpected Result:
- 1st Attempt:
X-Cache: Miss from cloudfront(Content fetched from S3). - 2nd Attempt:
X-Cache: Hit from cloudfront(Content fetched from Edge cache).
Troubleshooting
| Error | Cause | Solution |
|---|---|---|
| 403 Forbidden | S3 Bucket Policy is missing or incorrect. | Ensure the Bucket Policy allows s3:GetObject for the CloudFront OAC. |
| 404 Not Found | Default Root Object not set. | Update Distribution settings to include index.html as the root object. |
| X-Cache: Miss | TTL is set to 0 or headers prevent caching. | Check Cache-Control metadata on the S3 object. |
Clean-Up / Teardown
To avoid charges, follow these steps in order:
- Disable CloudFront Distribution: You must disable it before you can delete it.
bash
# Get ETag first ETAG=$(aws cloudfront get-distribution --id <DIST_ID> --query 'ETag' --output text) # Update to disabled (requires full config, console is easier here) - Delete S3 Bucket:
bash
aws s3 rb s3://$BUCKET_NAME --force - Delete Distribution: Once status is
Disabled, delete via console or CLI.
Stretch Challenge
Optimize for Dynamic Headers:
Modify the Cache Behavior to cache based on a specific custom header (e.g., X-User-Type). Observe how CloudFront creates separate cache keys for different header values.
Cost Estimate
- S3 Storage: $0.023 per GB (Negligible for this lab).
- CloudFront Data Transfer: First 1TB/month is free.
- CloudFront Requests: First 10 million/month are free.
- Total Estimated Cost: $0.00 (within Free Tier).
Concept Review
Optimization Strategy Table
| Feature | Mechanism | Optimization Goal |
|---|---|---|
| TTL (Time to Live) | Specifies how long objects stay in cache. | Balance between freshness and origin load. |
| Edge Locations | Globally distributed data centers. | Minimize latency (Round Trip Time). |
| Cache Policy | Controls cache key settings (headers, cookies). | Increase cache hit ratio. |
| Origin Shield | Additional caching layer between Edge and Origin. | Further reduce load on the origin server. |