"Effortlessly Deploy Your Static Website on AWS S3 with Terraform"
Table of contents
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
AWS Account with appropriate permissions to create S3 buckets.
Terraform installed on your local machine.
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
anderror.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
.
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>
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.
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!