"Effortlessly Deploy Your Static Website on AWS S3 with Terraform"

Irfan MestriIrfan Mestri
5 min read

Hosting a static website on Amazon S3 is an efficient and cost-effective way to make content available on the web. S3 (Simple Storage Service) is ideal for hosting static content such as HTML, CSS, and JavaScript files. When coupled with Terraform, an Infrastructure-as-Code (IaC) tool, you can automate the entire process, from creating an S3 bucket to uploading your website files.

In this blog, I'll guide you through the steps to host a static website on AWS S3 using Terraform. Everything, including creating the S3 bucket, configuring it for static hosting, and uploading the HTML files, will be handled by Terraform.

Prerequisites

  1. AWS Account with appropriate permissions to create S3 buckets.

  2. Terraform installed on your local machine.

  3. Basic knowledge of AWS, S3, and Terraform.

Step-by-Step Guide

Step 1: Install Terraform

If you haven't installed Terraform yet, you can download and install it by following the instructions on the Terraform website.

Step 2: Create a Directory for Your Project

Create a directory for your project files and navigate to it:

mkdir s3-static-website
cd s3-static-website

Step 3: Write Terraform Configuration

Create a file named main.tf and add the following Terraform configuration code. This will define the resources required to host the static website on S3.

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "5.72.1"
    }
  }
}

provider "aws" {
  # Configuration options
  region = "us-east-1"
}

resource "aws_s3_bucket" "mybucket" {
  bucket = my-project-bucket-for-static-web

}

resource "aws_s3_bucket_ownership_controls" "example" {
  bucket = aws_s3_bucket.mybucket.id
  rule {
    object_ownership = "BucketOwnerPreferred"
  }
}

resource "aws_s3_bucket_public_access_block" "example" {
  bucket = aws_s3_bucket.mybucket.id

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

resource "aws_s3_bucket_acl" "example" {
  depends_on = [
    aws_s3_bucket_ownership_controls.example,
    aws_s3_bucket_public_access_block.example,
  ]

  bucket = aws_s3_bucket.mybucket.id
  acl    = "public-read"
}

resource "aws_s3_object" "index" {
  bucket = aws_s3_bucket.mybucket.id
  key = "index.html"
  source = "index.html"
  acl = "public-read"
  content_type = "text/html"

}

resource "aws_s3_object" "error" {
  bucket = aws_s3_bucket.mybucket.id
  key = "error.html"
  source = "error.html"
  acl = "public-read"
  content_type = "text/html"

}

resource "aws_s3_bucket_website_configuration" "website" {
  bucket = aws_s3_bucket.mybucket.id

  index_document {
    suffix = "index.html"
  }

  error_document {
    key = "error.html"
  }

  depends_on = [ aws_s3_bucket_acl.example ]
}

This configuration does the following:

  • Creates an S3 bucket with the name my-project-bucket-for-static-web

  • Configures the bucket for static website hosting.

  • Sets the bucket’s ACL (Access Control List) to public-read so that the files are accessible to the public.

  • Uploads the index.html and error.html files to the bucket.

Step 4: Create HTML Files

Create a directory named html inside your project folder. This folder will contain the static files you want to upload to the S3 bucket.

Now, create two HTML files: index.html and error.html.

  1. index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Irfan Mestri | Aspiring DevOps Engineer</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
            color: #333;
            text-align: center;
        }
        header {
            background-color: #007acc;
            color: #fff;
            padding: 20px 0;
        }
        header h1 {
            margin: 0;
            font-size: 2.5rem;
        }

        .summary {
            max-width: 800px;
            margin: 30px auto;
            background-color: #fff;
            padding: 30px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            border-radius: 10px;
        }
        .summary h2 {
            font-size: 2rem;
            margin-bottom: 20px;
        }
        .summary p {
            font-size: 1.2rem;
            line-height: 1.6;
        }
        footer {
            margin-top: 40px;
            padding: 20px 0;
            background-color: #333;
            color: #fff;
        }
        footer p {
            margin: 0;
        }
    </style>
</head>
<body>

<header>
    <h1>Irfan Mestri</h1>
    <p>Aspiring DevOps Engineer | Cloud Enthusiast | Linux Expert</p>
</header>



<section class="summary">
    <h2>About Me</h2>
    <p>
        Hi, I'm Irfan Mestri, an aspiring DevOps Engineer with a passion for building scalable, secure, and automated cloud infrastructures. I have hands-on experience in AWS, Linux, and various DevOps tools, and I'm continuously learning and experimenting with new technologies to enhance my skills.
    </p>
    <p>
        My goal is to bridge the gap between development and operations, creating seamless workflows, automating deployments, and ensuring high availability in production environments. Whether it's working on AWS, setting up CI/CD pipelines, or managing Linux servers, I'm driven by a love for problem-solving and efficiency.
    </p>
    <p>
        Follow my journey as I work on exciting projects, share my knowledge, and grow into a well-rounded DevOps professional. Let's connect and explore the endless possibilities of cloud technology and automation together!
    </p>
</section>

<footer>
    <p>© 2024 Irfan Mestri | DevOps Journey</p>
</footer>

</body>
</html>
  1. error.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Page Not Found | Irfan Mestri</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
            color: #333;
            text-align: center;
        }
        .error-container {
            margin-top: 100px;
            padding: 30px;
            background-color: #fff;
            max-width: 600px;
            margin-left: auto;
            margin-right: auto;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            border-radius: 10px;
        }
        .error-container h1 {
            font-size: 6rem;
            margin: 0;
            color: #ff6b6b;
        }
        .error-container h2 {
            font-size: 2rem;
            margin: 20px 0;
        }
        .error-container p {
            font-size: 1.2rem;
            color: #666;
        }
        .error-container a {
            display: inline-block;
            margin-top: 20px;
            padding: 10px 20px;
            font-size: 1.1rem;
            color: #fff;
            background-color: #007acc;
            text-decoration: none;
            border-radius: 5px;
        }
        .error-container a:hover {
            background-color: #005f99;
        }
    </style>
</head>
<body>

<div class="error-container">
    <h1>404</h1>
    <h2>Oops! Page Not Found</h2>
    <p>Sorry, but the page you're looking for doesn't exist.</p>
    <p>Maybe you took a wrong turn or the page has been moved.</p>
    <a href="index.html">Back to Home</a>
</div>

</body>
</html>

Step 5: Initialize Terraform

Initialize Terraform to download the necessary provider plugins (in this case, the AWS provider):

terraform init

Step 6: Apply the Terraform Configuration

Now, apply the Terraform configuration. This will create the S3 bucket, configure it for static hosting, and upload the HTML files to the bucket:

terraform apply

Terraform will ask for confirmation before proceeding. Type yes to continue.

Once the apply is complete, Terraform will output the website URL in your bucket properties. You can use this URL to access your static website.

Step 7: Verify the Website

Once Terraform has successfully applied the configuration, you can visit your static website using the URL provided in your bucket.

Step 8: Clean Up (Optional)

If you want to delete the resources you created, simply run:

terraform destroy

This will remove the S3 bucket and all the files you uploaded.

Conclusion

In this blog, you learned how to host a static website on AWS S3 using Terraform. With Terraform, the entire process of creating the S3 bucket, configuring it for static hosting, and uploading the HTML files can be automated, saving you time and effort.

By leveraging Infrastructure as Code with Terraform, you can easily manage, version, and scale your infrastructure, making your static website hosting more robust and easier to maintain.

0
Subscribe to my newsletter

Read articles from Irfan Mestri directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Irfan Mestri
Irfan Mestri

Aspiring DevOps Engineer | Passionate about Cloud & Automation 🌩️ | Learning AWS, Linux, and DevOps Tools ⚙️ I'm diving into the world of DevOps, starting with the basics of AWS, Linux, and essential DevOps tools. With a growing passion for cloud technologies and automation, I’m excited to build scalable, secure, and efficient solutions. Follow along as I document my learning journey, share insights, and tackle real-world projects!