Using Amazon S3 to Host a Static Website

This tutorial will guide you through hosting a static website using Amazon S3. You'll learn how to create and configure an S3 bucket, upload website files, and make the site publicly accessible.

Published 2025-01-26

Low Cost Expectation, with Caution
Following this tutorial is expected to incur minimal costs, between $0.00 and $0.10 USD or equivalent in your local currency. This estimate assumes that the tutorial is fully completed and all resources are cleaned up on the same day.
Leaving resources running can become expensive, especially if larger resources are configured than are needed. Accuracy of this information is not guaranteed. You should verify the costs yourself before proceeding and if you have any doubts, do not follow this tutorial on the live system.

Prerequisites

  • An AWS account
  • Basic understanding of HTML/CSS

Step 1: Download the Sample Website

Step 2: Create an S3 Bucket

What is an S3 Bucket?

Amazon S3 (Simple Storage Service) buckets are cloud storage containers that can hold virtually any type of file. Think of a bucket like a root folder in a file system, one of the major differences though is that, if appropriately configured, they can be used to directly serve files to web browsers and they:

  • Provide high availability and durability for your files
  • Scale automatically with no maintenance required
  • Include built-in website hosting features
  • Are cost-effective for most static sites

Buckets must be given a name and that name must be unique across every AWS account owned by every user over every single AWS region, for this reason, everyone following this tutorial cannot use the same name. A suggested name is provided which you may whish to change, this will dynamically update the tutorial for your personal use.

Bucket Name

Must be 3-63 characters, lowercase letters, numbers, dots, and hyphens only. Cannot start or end with dots or hyphens.

Create the Bucket using the AWS Management Console

  1. Sign in to the AWS Management Console
  2. Navigate to S3
  3. (Optional) Change to a preferred region
  4. Click "Create bucket"
  5. Enter the bucket name: goldnode-tutorial-293148
  6. Uncheck "Block all public access"
  7. Acknowledge the warning by clicking "I acknowledge that the current settings might result in this bucket and the contents being public"

Security Warning
Whatever we are going to be placing in the bucket is going to be public, there will be no password protection, and no access control. For this tutorial this is absolutley fine, and even in a production environment it may be in some cases, but you need to be aware and be careful never to add anything to this bucket that you don't want to be public.

Although outside the scope of this tutorial, S3 can be combined with other AWS services to avoid giving full public access to the bucket. For example, you could use Amazon CloudFront to serve the files to the public from the bucket.

We can leave the rest of the settings as default, but while we are here lets take a look at what they are:

  • Object ownership: In nearly all cases when creating S3 buckets it is recommended to leave this as the default with ACLs Disabled. Access Control Lists (ACLs) are a way to manage permissions for objects in your bucket. When ACLs are enabled, the bucket owner can grant permissions to specific AWS accounts or groups. ACLs can lead to security risks if not managed properly so it is best avoided as there are now much better ways to manage permissions, by using IAM roles and policies.
  • Bucket Versioning: When objects of the same name are uploaded to the bucket, versioning allows you to keep track of the different versions. There are many reasons why you might want to enable versioning on a bucket, but for this tutorial we will leave it disabled.
  • Tags: The larger your AWS account gets the more useful tags become, you could use tags to group resources for billing and cost management, but for this tutorial we will not use them.
  • Default encryption: Encryption is now enabled by default, by leaving this as SSE-S3 it will not add any complexity to the management of the bucket as AWS will automatically encrypt all new objects using AES-256 and internally managing our keys.
  • Advanced / Object Lock: Object Lock is a feature that allows you to prevent objects from being deleted or overwritten for a specified amount of time, this can be useful in some environments, for Data Protection and legal reasons but is certainly not needed for this tutorial where we are going to be tidying up once we've done!
  1. Click "Create bucket"

Step 3: Upload Your Website Files

  1. Click on your newly created bucket (goldnode-tutorial-293148)
  2. With the Objects tab selected, click "Upload"
  3. Click "Add files"
  4. Navigate to the sample website directory you downloaded in step 1
  5. Select all of the files (this will include the index.html, error.html and a number of other files) and click "Open"
  6. Click the "Upload" button

You should now see the Upload: status screen and all of the files should be listed.

  1. Click "Close".

Step 4: Configure the Bucket for Static Website Hosting

We have already configured our bucket to allow public access back in step 2, but further configuration is required for the bucket to serve our files to web browsers.

  1. Click the "Properties" tab.
  2. Scroll down to "Static website hosting" section
  3. Click "Edit"
  4. Select to "Enable" static website hosting

This will open up a few more fields for completion...

  1. Under "Hosting type", ensure "Host a static website" is selected
  2. Configure.
    • Set "Index document" to index.html (this is the page that loads when visitors access your site's root URL)
    • Set "Error document" to error.html (this page displays when errors occur, like when a file isn't found)
  3. Click "Save changes"

If you now scroll back down to the bottom of the page (still on the "Properties" tab) you should see under "Static website hosting" you have a "Bucket website endpoint", open that is a new browser tab.

You should see a 403 Forbidden error. We have a little more configuration to do, we need to configure a bucket policy.

Step 5: Configure Bucket Permissions

  1. Go to the "Permissions" tab
  2. Click "Edit" under "Bucket policy"
  3. Enter the following policy:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "PublicReadGetObject",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::[BUCKET_NAME]/*"
            }
        ]
    }
  4. Click "Save changes"

💡 If you receive a 'Policy has invalid resource' message, check that the bucket name in the Resource field matches exactly with your bucket name. The policy is case-sensitive and must match your bucket name precisely.

What this policy does:

  • "Version": "2012-10-17" although a considerable number of years old, this is the current version of the policy language and what you would use in nearly all policies at the time of writing
  • Allows anyone ("Principal": "*") to read files ("Action": "s3:GetObject") from your bucket
  • Applies to all files in the bucket ("Resource": "[BUCKET]/*")

Security Warning
This policy is the final step in making your bucket public, it makes all files in the bucket publicly readable. Make sure you don't upload sensitive information.

Step 6: Test Your Website

Head back over to the tab where you have the web site open and refresh the page. If you no longer have the tab open, you can find the URL in the "Properties" tab under "Static website hosting" at the bottom.

You will hopefully see our new weather site!

Click the "Check Weather" button to check the weather in London, and search for your own city check you are getting a correct result.

How This Works

This is a common pattern in modern web development, "static site + API" architecture, where:

  1. The static files (HTML, CSS, JavaScript) are served directly from S3
  2. The JavaScript code in your browser makes API calls to fetch dynamic data
  3. The results are displayed without needing to reload the page

In this example, we're using a free public weather API Open-Meteo to keep things simple, but in a production environment you have several options:

  • AWS Services: Create your own API using services like:
    • AWS API Gateway + Lambda
    • AWS AppSync for GraphQL APIs
    • Amazon DynamoDB for database storage
  • Other Cloud Providers: Use APIs from Google Cloud, Azure, or other providers
  • External API Services: Integrate with thousands of available third-party APIs for:
    • Payment processing (Stripe, PayPal)
    • Authentication (Auth0, Okta)
    • Content delivery (Contentful, Sanity)
    • And many more

This approach gives you the benefits of both worlds:

  • Static content is fast and cheap to serve
  • Dynamic data keeps your site interactive and up-to-date
  • You can scale each part independently

So, some important things to note here:

  • We are using a static website, which means that the content is served as-is and is not dynamically generated.
  • We are viewing up to date content.

Cost Considerations

  • S3 costs are based on:
    • Storage used (the sample website is very small)
    • Bandwidth out
    • Number of requests
  • Static websites typically have very low costs
  • Monitor usage to avoid surprises

💡 Tip: Enable AWS Cost Explorer to track expenses.

Step 7: Clean Up

To avoid incurring any future charges and keep your AWS account clean, we will now delete the bucket and all of the files it contains.

  1. Delete the bucket contents:

    • Go to the S3 console and click on your bucket (goldnode-tutorial-293148)
    • Select all objects in the bucket
    • Click "Delete"
    • Type "permanently delete" in the confirmation field
    • Click "Delete objects"
  2. Delete the bucket:

    • Return to the S3 console main page
    • Select your bucket (goldnode-tutorial-293148)
    • Click "Delete"
    • Type your bucket name in the confirmation field
    • Click "Delete bucket"
  3. Local cleanup:

    • Delete the downloaded zip file
    • Delete the extracted website files

⚠️ Note: Always remember to clean up AWS resources you no longer need to avoid unexpected charges.

© 2025 Goldnode. All rights reserved.