Host a Static Website on AWS with S3 and CloudFront
Beginner guide to hosting a static site on a private S3 bucket with CloudFront, HTTPS, and Origin Access Control in about 15 minutes.
## Why this setup?
Hosting a static site (HTML, CSS, JS) on S3 is cheap and simple. Adding CloudFront gives you HTTPS, global caching, and lets you keep the bucket **private**. In this guide, you'll build it from scratch in the AWS Console.
**You'll need:** an AWS account and a simple `index.html` file.
## Step 1: Create an S3 bucket
1. Open **S3** → **Create bucket**.
2. Choose a globally unique name, e.g. `my-static-site-demo-123`.
3. Keep **Block all public access** turned **on**.
4. Click **Create bucket**.
2. Choose a globally unique name, e.g. `my-static-site-demo-123`.
3. Keep **Block all public access** turned **on**.
4. Click **Create bucket**.
## Step 2: Upload your website
1. Open the bucket → **Upload**.
2. Add `index.html` (and any CSS, JS, or images).
3. Click **Upload**.
2. Add `index.html` (and any CSS, JS, or images).
3. Click **Upload**.
## Step 3: Create a CloudFront distribution
1. Open **CloudFront** → **Create distribution**.
2. For **Origin domain**, select your S3 bucket.
3. Under **Origin access**, choose **Origin access control (OAC)** and create a new one.
4. Set **Default root object** to `index.html`.
5. Under viewer protocol policy, choose **Redirect HTTP to HTTPS**.
6. Click **Create distribution**.
2. For **Origin domain**, select your S3 bucket.
3. Under **Origin access**, choose **Origin access control (OAC)** and create a new one.
4. Set **Default root object** to `index.html`.
5. Under viewer protocol policy, choose **Redirect HTTP to HTTPS**.
6. Click **Create distribution**.
## Step 4: Allow CloudFront to read the bucket
After creating the distribution, CloudFront shows a banner with a **bucket policy**. Click **Copy policy**, then go to your bucket → **Permissions** → **Bucket policy**, paste it, and save.
This allows only your CloudFront distribution to read the files. The bucket stays private.
## Step 5: Test it
Wait a few minutes until the distribution status shows **Deployed**. Then open the **Distribution domain name** (like `d1234abcd.cloudfront.net`) in your browser. Your site should load over HTTPS.
## Updating your site
Upload the new files to S3. If you still see the old version, create a **cache invalidation** in CloudFront with the path `/*`.
## Cost
For small sites, costs are typically just a few cents per month, and both services have free tier allowances. Check the AWS pricing pages for current details.
## Troubleshooting
- **403 Access Denied:** check that the bucket policy is applied and the default root object is set.
- **Old content showing:** create an invalidation.
- **Blank page:** confirm the file is named `index.html` (case-sensitive).
- **Old content showing:** create an invalidation.
- **Blank page:** confirm the file is named `index.html` (case-sensitive).
## Conclusion
You now have a private S3 bucket served globally over HTTPS through CloudFront. Next, try adding a custom domain with Route 53 and a free certificate from AWS Certificate Manager.
Have questions or ran into issues? Drop a comment below!
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article