This project demonstrates how to deploy a production-ready static website on AWS using Terraform.
The following diagram illustrates the request flow from user to the S3 origin:
User → Internet → Domain → CloudFront Distribution → S3 Bucket (Static Website)
- Private S3 Bucket: Hosts static website files (HTML, CSS, JS) and is not directly accessible to the public
- CloudFront Distribution: Global CDN for fast and secure content delivery
- Origin Access Control (OAC): Secures authentication between CloudFront and S3
Website_Infra/
├── provider.tf # Provider Configuration
├── main.tf # Main Terraform configuration
├── variables.tf # Input variables
├── terraform.tfvars # Default variable values (separates configuration from infrastructure code)
├── outputs.tf # Output values
├── README.md # This file
└── www/ # Website source files
├── index.html # Main HTML page
├── style.css # Stylesheet
└── script.js # JavaScript functionality
- Modern Responsive Design: Works on desktop and mobile
- Dark/Light Theme Toggle: Switch between themes (saves preference)
- Interactive Elements: Click counter, status updates
- AWS Branding: Professional layout showcasing AWS services
- Animations: Smooth transitions and loading effects
- S3 Static Website Hosting: Reliable file storage and serving
- CloudFront CDN: Global content delivery with HTTPS
- Proper MIME Types: Correct content-type headers for all files
- Private Origin Architecture: S3 accessible only through CloudFront
- AWS CLI configured with appropriate credentials
- Terraform installed (version 1.0+)
- AWS Account with sufficient permissions for:
- S3 bucket creation and management
- CloudFront distribution creation
- IAM permissions to manage S3, CloudFront, Route53, and ACM resources
Step 1: Create a folder named Website_Infra, and inside it create another folder named www:
Add the following three files:
-
index.html: The code forindex.htmlis available in this repository insidewwwdirectory. -
style.css: The code forstyle.cssis present in this repository insidewwwdirectory. -
script.js: The code forscript.jsis present in this repository insidewwwdirectory.
Step 2: Inside “Website_Infra” folder add the code for provider configuration:
provider.tf
Then run aws configure in your terminal and provide your Access Key ID, Secret Access Key, region, and default output format.
Step 3: In the same Root Folder that is “Website_Infra”, create a file named main.tf and:
-
Add HCL Configuration for Creating an S3 Bucket.
-
Make this bucket as private:
- Refer to the Terraform AWS Provider documentation for:
aws_s3_bucket_public_access_block
- Origin Access Control for CloudFront:
- Refer to the Terraform AWS Provider documentation for:
aws_cloudfront_origin_access_control
- Bucket Policy for S3:
- Refer to the Terraform AWS Provider documentation for:
aws_s3_bucket_policy
https://awspolicygen.s3.amazonaws.com/policygen.html
- Copy the Policy and Paste It.
-
Uploading Static Files to S3:
Search for “aws_s3_object”. Copy / Paste and then make the changes.
-
Create Route53 Hosted Zone for domain management.
-
Create ACM Certificate for CloudFront (must be in us-east-1 region).
-
Create CloudFront Distribution for S3 Origin with HTTPS.
-
Initialize Terraform: “terraform init”:
cd Website_infra
terraform init
- Validate the Configuration:
terraform validate
- Review the execution plan output carefully before applying:
terraform plan -out tfplan
- Apply the changes:
Deploy Infrastructure
terraform apply tfplan
Type yes when prompted to confirm deployment.
- Access Your Website
- After deployment completes, Terraform will output the Website URL.
- Note: Remember to update your Route53 nameservers in your domain provider.
| Resource Type | Purpose | Count |
|---|---|---|
| S3 Bucket | Website hosting | 1 |
| S3 Bucket Policy | Restricts access to CloudFront only | 1 |
| S3 Objects | Website files (HTML, CSS, JS) | 3 |
| CloudFront Distribution | Global CDN | 1 |
- Bucket naming: Auto-generated with prefix
my-static-website- - Website hosting: Enabled with
index.htmlas default - Public access: Fully blocked; access allowed only via CloudFront (OAC)
- Content types: Proper MIME types for web files
- Origin: S3 bucket regional domain
- Caching: Standard web caching (1 hour default TTL)
- HTTPS: Automatic redirect from HTTP to HTTPS
- Global: Available worldwide (PriceClass_100)
AWS Console Resource Overview:
1. S3 Bucket:
2. Route53 Hosted Zone:
3. ACM Certificate: (us-east-1):
4. CloudFront Distribution for S3 Origin with HTTPS:
5. Live Static Website:
To destroy all resources and avoid charges:
terraform destroyType yes when prompted to confirm destruction.
After completing this project, you should understand:
- ✅ How to configure S3 for static website hosting
- ✅ Setting up CloudFront distributions
- ✅ Managing S3 bucket policies and public access
- ✅ Dynamic S3 object provisioning using
for_each - ✅ Proper MIME type configuration for web assets
- ✅ AWS CDN concepts and caching strategies
Note:
- For a deeper architectural explanation, read the accompanying blog post:








