DEV Community

Stephanie Makori
Stephanie Makori

Posted on

Deploying a Static Website on AWS S3 with Terraform: A Beginner’s Guide

Introduction

In this project, I deployed a fully functional static website using AWS S3 and CloudFront with Terraform. The goal was to apply everything learned throughout the Terraform challenge, including modular design, environment separation, remote state, and Infrastructure as Code best practices.

This project represents a complete real-world workflow where infrastructure is defined, reviewed, deployed, and destroyed in a controlled and repeatable manner.


Project Overview

The architecture of the solution follows a simple but powerful flow:

User requests website → CloudFront distributes content globally → S3 bucket serves static files

Key Components

  • S3 bucket for static website hosting
  • CloudFront distribution for global content delivery and HTTPS support
  • Terraform module for reusable infrastructure design
  • Environment-based configuration for dev deployment
  • Remote backend for state management and locking

Project Structure

The project was organized using a modular approach:

  • A modules directory containing reusable infrastructure logic for the static website
  • An envs directory containing environment-specific configurations
  • A backend configuration for remote state storage
  • A provider configuration for AWS setup

This structure ensures a clear separation between reusable infrastructure components and environment-specific deployment settings.


Module Design Decisions

The module was designed to encapsulate all infrastructure complexity related to the static website.

Key design choices:

  • The bucket name is required with no default because it must be globally unique in AWS
  • The environment variable is restricted to predefined values to prevent misconfiguration
  • Tags are optional to allow flexibility while still supporting cost tracking and resource organization
  • Default values are used for index and error documents because most static websites follow standard conventions

The module also centralizes tagging, security configuration, and CloudFront setup to ensure consistency across deployments.


Why Modules Were Used

Modules were introduced to:

  • Avoid duplication of infrastructure code
  • Promote reusability across environments
  • Improve maintainability of the codebase
  • Enforce consistent architecture patterns
  • Support scaling to multiple environments such as staging and production

Without modules, each environment would require repeated configuration, increasing the risk of inconsistency and errors.


Calling Configuration (Dev Environment)

The dev environment configuration acts as a lightweight wrapper around the module.

It only defines:

  • The bucket name
  • The environment type
  • Any overrides for defaults
  • Basic tagging information

All infrastructure logic remains inside the module, keeping the environment configuration clean and easy to manage.


Deployment Workflow

The deployment followed a structured Terraform workflow:

  1. Initialization of the working directory and backend configuration
  2. Validation of configuration correctness
  3. Planning of infrastructure changes to preview modifications
  4. Application of the planned changes to create real AWS resources

Each step ensured that infrastructure changes were predictable and reviewable before being applied.


Deployment Output

After successful execution, Terraform output provided a CloudFront distribution domain.

This domain represents the live endpoint of the deployed static website, served globally through AWS edge locations.

The deployment confirmed that:

  • S3 bucket was created and configured correctly
  • CloudFront distribution was provisioned successfully
  • Static website content was accessible via HTTPS

Live Website Confirmation

The deployed website was successfully accessed using the CloudFront URL.

The site displayed:

  • A simple static HTML page
  • A confirmation message indicating deployment via Terraform
  • Dynamic values such as environment and bucket information

This confirmed that both S3 and CloudFront were correctly integrated.


Cleanup Process

After verification, all infrastructure was destroyed using Terraform destroy.

This ensured:

  • No unnecessary AWS costs were incurred
  • All resources were properly removed
  • State was updated to reflect the destroyed infrastructure

This step reinforces the importance of infrastructure lifecycle management in real-world environments.


DRY Principle in Practice

The DRY (Don’t Repeat Yourself) principle was applied through module usage.

Instead of repeating S3 and CloudFront configurations across environments:

  • All logic was centralized in a single module
  • Environments only supplied configuration values
  • Infrastructure changes could be made in one place and applied everywhere

This significantly reduces complexity and improves long-term maintainability.


Key Learnings

  • CloudFront requires propagation time before the site becomes fully available globally
  • S3 static websites require careful configuration of public access policies
  • Modules are essential for scalable infrastructure design
  • Remote state improves collaboration and prevents configuration drift
  • Terraform outputs are critical for validating successful deployments

Conclusion

This project demonstrates how Terraform transforms simple infrastructure into a scalable and maintainable system. A static website deployment becomes more than just hosting files; it becomes a fully automated, version-controlled, and reproducible cloud architecture.

By combining S3, CloudFront, modules, and remote state, infrastructure is treated like software — predictable, reusable, and safe to evolve over time.

Top comments (0)