How to Host a Static Website on Amazon S3 and Securely with CloudFront
S3+CloudFront
ByOlaniyi Oladimeji
How to Host a Static Website on Amazon S3 and Securely with CloudFront
Hosting a static website on Amazon S3 and securely with CloudFront is an efficient and cost-effective AWS architecture. This tutorial shows you how to set it up, including creating an S3 bucket, enabling secure Origin Access Control, configuring edge delivery, and cleaning up resources. This hands-on tutorial provides everything you need, whether you are preparing for AWS certification, building a portfolio, or deploying a production-ready static site.

Why Use Amazon S3 + CloudFront to Host a Static Website?

Leveraging the modern AWS services to achieve reliable, secure, and scalable serverless static website hosting that adjusts effortlessly as the audience grows.  Here are the valuable architectures:
  • Amazon S3: provides durable, highly available object storage to host your HTML, CSS, and image files without managing a web server.
  • Amazon CloudFront: AWS’s global Content Delivery Network (CDN) distributes your content across hundreds of edge locations worldwide, diminishing latency for end users regardless of their geographic location.
  • Origin Access Control (OAC): Ensures the S3 bucket is never directly accessible from the public internet; all traffic must flow through CloudFront, thereby improving the security posture.

Prerequisites

  • An active AWS account
  • Basic familiarity with the AWS Management Console
  • Prepare your static website files for upload to launch your project successfully (in this tutorial: index.html, style.css, kb.png, aws.png, icon.png).

Step 1 — Create an S3 Bucket

The first step is to create an S3 bucket to store your static website files. Remember, S3 bucket names must be globally unique across all AWS accounts and regions. If your chosen name is already taken, choose another.
  1. In AWS Management Console, go to S3.
  2. Click the Create bucket.
  3. Enter a globally unique bucket name. For this tutorial, we use: kb-aws-hsp
  4. Select the Region: us-east-1 (US East — N. Virginia).
  5. Leave Block all public access enabled; CloudFront will handle access via OAC, so direct public access is unnecessary and should remain blocked.
  6. Click Create bucket to finish.

Step 2 — Upload Your Website Files to the S3 Bucket

With the bucket ready, upload your website files. Once the upload completes, your website files are stored in S3, but they are not yet publicly accessible. That access will be handled exclusively through CloudFront.
  1. Open your newly created bucket.
  2. Click Upload → Add files.
  3. Select all five files: index.html, style.css, kb.png, aws.png, and icon.png.
  4. Click Upload.

Step 3 — Create a CloudFront Distribution

The core of the architecture is to create a CloudFront distribution. Set your S3 bucket as the origin. Configure secure access using Origin Access Control.
  1. Go to CloudFront in the AWS Console.
  2. Click Create distribution.
  3. Name it and click next

Configure the Origin

Origin type
Select your S3 bucket (e.g., kb-aws-hsp.s3.amazonaws.com)
Origin access
Origin access control settings (recommended)
  1. Under Origin browse and choose your S3 bucket.

Configure the Viewer Settings

Viewer protocol policy
Redirect HTTP to HTTPS
Allowed HTTP methods
GET, HEAD

Web Application Firewall (WAF)

For this tutorial, select Do not enable security protections. Be cautious. If you enable WAF during testing, delete the WAF Web ACL and associated rules after you finish. Otherwise, you will incur ongoing charges.

Additional Settings

Price class
Use all edge locations (best performance)
Alternate domain name (CNAME)
Leave blank (optional for custom domains)
Default root object
index.html
  1. Click Create distribution.
CloudFront takes a few minutes to deploy your distribution globally across all AWS edge locations.

Step 4 — Attach the CloudFront-Generated Policy to Your S3 Bucket

When you created the OAC in Step 3, CloudFront generated a bucket policy that you must now attach to your S3 bucket. This policy grants CloudFront permission to read objects from your bucket.

How to copy the policy from CloudFront

  1. Go to CloudFront → Distributions → open your distribution.
  2. Select the Origins tab.
  3. Select your S3 origin, then click Edit.
  4. Name it and click Create. This OAC will generate a bucket policy that allows CloudFront — and only CloudFront — to access your S3 bucket
  5. Click Copy policy under Origin access.

Attach the policy to your S3 bucket.

  1. Return to S3, open your bucket.
  2. Go to the Permissions tab.
  3. Click Edit under Bucket policy.
  4. Paste the copied policy.
  5. Click Save changes.
Your bucket now accepts requests only from CloudFront.
How to Host a Static Website on Amazon S3 and Securely with CloudFront

Step 5 — Access Your Site via CloudFront

Your distribution has been deployed, and your bucket policy is in place. Time to access your site.
  1. Go to CloudFront → Distributions.
  2. Copy the Domain name of your distribution (e.g., d1bpxeei7j3k9a.cloudfront.net).
  3. Paste it into your browser.
Good job! Your static website is now live, served securely through Amazon CloudFront, distributed across AWS edge locations worldwide, and with zero direct exposure of your S3 bucket.

Bonus: Two Useful CloudFront Features to Explore

Can you restrict access to specific countries?

Yes. CloudFront supports geographic restrictions at the distribution level:
  1. Open your distribution → Security tab.
  2. Under CloudFront geographic restrictions, click Edit.
  3. Choose between an Allow list (only listed countries can access) or a Block list (listed countries are denied access).
This is useful for compliance requirements or to block regions you do not serve.

How do you retrieve the bucket policy generated by CloudFront?

If you need to retrieve it again at any time:
  1. Open your distribution → Origins tab.
  2. Select your S3 origin and click Edit.
  3. Under Origin access, click Copy policy.

Step 6 (Optional) — Verify Direct S3 Access Is Blocked

This optional step confirms that your architecture is working as intended and that your site files are accessible only through CloudFront, not via the direct S3 URL. You should receive an AccessDenied error. This is the expected and correct behavior, which confirms that your bucket policy is properly enforced and that all access is routed exclusively through CloudFront.
Try accessing your index.html file directly using the S3 URL format: https://kb-aws-hsp.s3.amazonaws.com/index.html

Step 7 — Clean Up Your Resources

Delete all resources you created in this tutorial to avoid AWS charges. Follow the correct order.

1. Disable and Delete the CloudFront Distribution

  1. Go to CloudFront → Distributions.
  2. Select your distribution. Click Disable.
  3. Wait about 5 minutes for disabling. Monitor the Status column.
  4. Once the status shows Disabled, select the distribution again and click Delete.

2. Delete the Origin Access Control

  1. Go to CloudFront, then select Origin access.
  2. Under Origin access control settings, select the OAC you created and click Delete.

3. Empty and Delete the S3 Bucket

If you enabled WAF, delete the WAF WebACL and associated ACL rules from the WAF & Shield console.

  1. Go to S3 and open your bucket.
  2. Click Empty and confirm the action. ( Bucket must be empty before deletion.)
  3. After emptying, click Delete and confirm the bucket name.

Conclusion

Hosting a static website on Amazon S3 with CloudFront is a production-grade, serverless, and cost-efficient AWS deployment pattern. The pattern follows AWS best practices for secure, high-performance static website delivery: S3 stores your assets privately; CloudFront acts as the public CDN and secure proxy. With Origin Access Control, only CloudFront fetches content from S3. Enforcing HTTPS encrypts user traffic, while Edge locations cache content near users to reduce latency. For extra production security, enable WAF and logging, and use Origin Access Control (OAC)—the recommended replacement for Origin Access Identity (OAI)—to secure your S3 origin. Never allow direct public access to the S3 bucket; always confirm that direct S3 URLs return an AccessDenied error. After testing, clean up your CloudFront distributions, OAC settings, and S3 buckets to avoid unexpected charges.
{{ reviewsTotal }}{{ options.labels.singularReviewCountLabel }}
{{ reviewsTotal }}{{ options.labels.pluralReviewCountLabel }}
{{ options.labels.newReviewButton }}
{{ userData.canReview.message }}

Related Posts

Platform Engineering Monitoring Solution
Platform Engineering: Build Automated Monitoring Solution with Sumo Logic, AWS Lambda, and Terraform
Manually monitoring dashboards and restarting instances is not scalable. As a Platform Engineer, one of...
AutoscalingWithElasticLoadBalancer
How to Create an Auto Scaling Group with Elastic Load Balancing on AWS (Step-by-Step)
Building highly available, fault-tolerant applications is a core competency for any AWS architect or engineer....
On-Prem Migration
Step-by-Step AWS Migration: Moving On-Prem Workloads to EC2 and Amazon RDS
Successfully migrating workloads from an on-prem corporate data center to the cloud marks a significant...