DEV Community

Revathi Joshi for AWS Community Builders

Posted on

How to Create a simple static website using Amazon S3

What is a Static Website?

  • On a static website, individual personal or marketing webpages include static content
  • Static websites deliver HTML, JavaScript, images, video and other files to your website visitors
  • Static websites are very low cost
  • They provide high-levels of reliability
  • They require no server administration
  • They can scale to handle enterprise-level traffic with no additional work.
  • They are very fast, because there is no true backend to fetch information from.
  • Use Amazon Simple Storage Service (Amazon S3)
  • Where as a dynamic website relies on server-side processing including server-side scripts, such as PHP, JSP, or ASP.NET.

Amazon S3 is object storage with a simple web service interface to store and retrieve any amount of data from anywhere on the web. It is designed to deliver 99.999999999% durability and scale past trillions of objects worldwide.

To use S3 for a static website, you simply upload files to an S3 bucket and configure your S3 bucket for web hosting.

Please visit my GitHub Repository for S3 articles on various topics being updated on constant basis.

Let’s get started!

Objectives:

1. Sign into the AWS Management Console.

2. Create the error.html and index.html files

3. Create a S3 bucket and upload error.html and index.html files

4. Enable Static Website hosting settings

5. Test the website - see a 403 Forbidden error message

6. Apply Bucket Policy

7. Test the website

Pre-requisites:

  • AWS user account with admin access, not a root account.

Resources Used:

Tutorial: Configuring a static website on Amazon S3

Steps for implementation to this project:

1. Sign into the AWS Management Console.

  • Make sure you're in the N. Virginia (us-east-1) region

2. Create the error.html and index.html files

  • index.html
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Creating a Static Website Using Amazon S3</title>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <style>
    body {
      padding-top: 5rem;
    }

    .starter-template {
      padding: 3rem 1.5rem;
      text-align: center;
    }

    .bd-placeholder-img {
      font-size: 1.125rem;
      text-anchor: middle;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }

    @media (min-width: 768px) {
      .bd-placeholder-img-lg {
        font-size: 3.5rem;
      }
    }
  </style>
</head>

<body>
  <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
    <a class="navbar-brand" href="#">My Static Website</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
      aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarsExampleDefault">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true"
            aria-expanded="false">Dropdown</a>
          <div class="dropdown-menu" aria-labelledby="dropdown01">
            <a class="dropdown-item" href="#">Action</a>
            <a class="dropdown-item" href="#">Another action</a>
            <a class="dropdown-item" href="#">Something else here</a>
          </div>
        </li>
      </ul>
      <form class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
        <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>
      </form>
    </div>
  </nav>

  <main role="main" class="container">

    <div class="starter-template">
      <h1>Creating a Static Website Using Amazon S3</h1>
      <p class="lead">Welcome to a simple static website, a cost-efficient website hosting for sites that consist of files like HTML, CSS, JavaScript, fonts, and images with a custom error page. 
      </p>
    </div>

    <div class="starter-template alert alert-light" role="alert">
      Navigation and search functions are intentionally not implemented.
    </div>

  </main><!-- /.container -->

  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
    integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
    integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous">
  </script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
    integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous">
  </script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode
  • error.html
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Creating a Static Website Using Amazon S3</title>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <style>
    body {
      padding-top: 5rem;
    }

    .starter-template {
      padding: 3rem 1.5rem;
      text-align: center;
    }

    .bd-placeholder-img {
      font-size: 1.125rem;
      text-anchor: middle;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }

    @media (min-width: 768px) {
      .bd-placeholder-img-lg {
        font-size: 3.5rem;
      }
    }

  </style>
</head>

<body>
  <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
    <a class="navbar-brand" href="#">My Static Website</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
      aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarsExampleDefault">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true"
            aria-expanded="false">Dropdown</a>
          <div class="dropdown-menu" aria-labelledby="dropdown01">
            <a class="dropdown-item" href="#">Action</a>
            <a class="dropdown-item" href="#">Another action</a>
            <a class="dropdown-item" href="#">Something else here</a>
          </div>
        </li>
      </ul>
      <form class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
        <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>
      </form>
    </div>
  </nav>

  <main role="main" class="container">

    <div class="starter-template">
      <h1>Custom Error Page</h1>
      <p class="lead">Go to <a href="index.html">index.html page again</a>?</p>
      </p>
    </div>

    <div class="starter-template alert alert-light" role="alert">
      Navigation and search functions are intentionally not implemented.
    </div>

  </main><!-- /.container -->

  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

3. Create a S3 bucket and upload error.html and index.html files

  • Create S3 bucket with a series of numbers at the end to make it globally unique, in US East (N. Virginia) us-east-1, un-check Block all public access, upload the error.html and index.html files

Image description

  • un-check Block all public access.
  • Ensure all four permissions restrictions beneath it are also un-checked.

Image description

  • Check the box to acknowledge that turning off all public access might result in the bucket and its objects becoming public.

Image description

  • Take all defaults

  • Create bucket

  • Copy ARN and paste it into notepad

arn:aws:s3:::mys3bucket-1234567
Enter fullscreen mode Exit fullscreen mode
  • upload error.html and index.html files

Image description

4. Enable Static Website hosting settings

  • Click the Properties tab.
  • find the Static website hosting section.
  • On the right in the Static website hosting section, click Edit.

  • 1.

Image description

  • 2.

Image description

  • Click Save Changes

5. Test the website

  • In the Static website hosting section, open the listed endpoint URL in a new browser tab.

Image description

http://mys3bucket-1234567.s3-website-us-east-1.amazonaws.com
Enter fullscreen mode Exit fullscreen mode
  • see a 403 Forbidden error message

Image description

6. Apply Bucket Policy

  • in S3, click the Permissions tab

Image description

{
    "Version": "2012-10-17",
    "Id": "Policy1234567890123",
    "Statement": [
        {
            "Sid": "Stmt1234567890123",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<BUCKET_ARN>/*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode
  • replace with your S3 bucket ARN

Image description

{
    "Version": "2012-10-17",
    "Id": "Policy1234567890123",
    "Statement": [
        {
            "Sid": "Stmt1234567890123",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mys3bucket-1234567/*"
        }
    ]
}

Enter fullscreen mode Exit fullscreen mode
  • Note: Ensure the trailing /* is present so the policy applies to all objects within the bucket.

  • Click Save changes

7. Test the website

  • Refresh the browser tab with the static website (the endpoint URL you opened earlier). This time, the site should load correctly.

Image description

  • Add a / at the end of the URL and some random letters (anything that's knowingly an error). This will display your error.html page.

Image description

Cleanup

  • Delete error.html and index.html files
  • Delete S3 bucket

What we have done so far

  • We created a static site using an AWS S3 bucket with the pre-created HTML files for your static web site.

Top comments (0)