Skip to main content
Skip to main content
Still in beta — questions, comments or suggestions? aramb@aramb.dev

Build a Simple Static Website with S3

Hands-on lab: create an S3 bucket, upload an index.html, enable static website hosting, and make it publicly readable.

25 min
Introductory
AWS Free TierFREE TIER

All services used in this lesson are covered by the AWS Free Tier.

AWS Services Used

S35 GB storage free for 12 monthsS3 Static HostingNo extra charge

What you are building

Amazon S3 can host a static website from a general purpose bucket. When you enable static website hosting, S3 gives you a Region-specific website endpoint, and you must specify at least an index document.

For a public S3 website, you must make the bucket publicly readable by disabling the relevant Block Public Access setting for the bucket and adding a bucket policy that grants public read access. By default, new buckets and objects do not allow public access.


Before you start

Warning

This lesson is a learning lab. S3 website endpoints support only publicly readable content and do not support HTTPS. AWS recommends CloudFront or Amplify for secure HTTPS hosting in production.

S3 now defaults to Bucket owner enforced object ownership, which disables ACLs. For a basic static website, the simpler path is to keep ACLs disabled and use a bucket policy for public reads.


What you will build

What this lab builds: a public S3 static website
  • One S3 bucket
  • One index.html file
  • Optionally one error.html file
  • A public-read bucket policy
  • One S3 website endpoint you can open in your browser

Part 1: Create the bucket

Create a general purpose bucket in the Region you want. The Region matters because it determines the S3 website endpoint for the bucket.

A good naming pattern for a learning bucket is something unique like: yourname-aws-learning-site-12345

Bucket names must be globally unique, so if your first name is taken, add a random suffix.


Part 2: Upload your files

Create a file named index.html with something simple like this:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>My First AWS Site</title>
</head>
<body>
  <h1>Hello from S3</h1>
  <p>This is my first static website on AWS.</p>
</body>
</html>

Optionally create an error.html file too:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Error</title>
</head>
<body>
  <h1>Page not found</h1>
  <p>Please go back to the home page.</p>
</body>
</html>

Upload these files to the bucket. In S3, uploaded files become objects.


Part 3: Enable static website hosting

Open the bucket's Properties tab, find Static website hosting, choose Edit, and enable Use this bucket to host a website. Then set:

  • Index document: index.html
  • Error document: error.html (optional)

The index document name is case-sensitive and required for website hosting. After saving, S3 shows you the website endpoint at the bottom of the static website hosting section.


Part 4: Make the site publicly readable

This is the step most often missed.

Two steps to make an S3 website publicly readable

4A) Change bucket public access setting

Go to the Permissions tab and edit Block public access (bucket settings) so the bucket can accept a public-read bucket policy. Block Public Access settings override public policies and permissions, so you must edit this before your bucket policy will work.

4B) Add the bucket policy

Add a bucket policy like this, replacing YOUR_BUCKET_NAME:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadForWebsite",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
    }
  ]
}

This grants everyone s3:GetObject permission on all objects in the bucket.


Part 5: Open the website endpoint

Return to Properties and open the website endpoint. If everything is correct, your browser should load index.html.

Tip

If you get 403 Forbidden, the most likely causes are: Block Public Access is still preventing the policy, or the bucket policy does not correctly grant public s3:GetObject.


Important warning

Warning

This lab is good for learning, but it is not the secure production pattern. S3 website endpoints do not support HTTPS. Use CloudFront or Amplify for real public sites.

  • S3 website endpoint alone = fine for learning
  • CloudFront or Amplify in front = better for real public sites

Verify your work

StepSuccess condition
Create bucketBucket exists in your chosen Region
Upload filesindex.html is in the bucket
Enable website hostingStatic website hosting is on
Set index documentindex.html is configured
Adjust public accessBucket can accept public-read policy
Add bucket policyPublic s3:GetObject access is granted
Test endpointWebsite loads in browser

Micro-activity 1: Reflection

Think about it

After the lab, reflect: Which Region did you choose? What is your bucket name? What is your website endpoint? Which setting blocked public access before you changed it? Which permission made the site readable in the browser?


Micro-activity 2: Explain the tradeoff

Think about it

Why does this S3 website setup need public read access? Why is CloudFront or Amplify better for a real public site? Consider that S3 website endpoints serve only publicly readable content without HTTPS.


Summary

In this lab, you created a general purpose S3 bucket, uploaded a small website, enabled static website hosting, and made it publicly readable through a bucket policy.

The most important limitation: the S3 website endpoint is public-content-only and does not support HTTPS. That is why AWS recommends CloudFront or Amplify for secure production hosting.


Quiz

Knowledge Check
1 / 8

What must you specify when enabling S3 static website hosting?