AWS with Terraform (Day 14)
Hosting a Static Website on AWS S3 + CloudFront + Rout53 Using Terraform
Today in my “30 Days of AWS & Terraform” learning journey, I explored how to host a production-grade static website using AWS S3 and CloudFront, with the entire setup automated via Terraform. This combination provides high availability, global content delivery, strong security, and low cost — all while remaining fully repeatable through Infrastructure-as-Code.
Why CloudFront with S3?
A static site hosted directly on S3 works, but it isn’t ideal for real users worldwide. Problems include:
-
High latency for users far from the S3 region
-
Increased cost due to regional data transfer
-
Security risks when buckets are made public
CloudFront solves these by caching content in global edge locations, reducing load time and ensuring users never directly access the S3 bucket. Instead, CloudFront communicates with S3 using Origin Access Control (OAC), keeping the bucket private and secure.
High-Level Architecture
| Component | Purpose |
|---|---|
| S3 Bucket (private) | Stores static web files (HTML, CSS, JS, images) |
| CloudFront Distribution | Serves and caches content globally |
| Origin Access Control | Allows only CloudFront to pull from S3 |
| Bucket Policy | Restricts access to CloudFront ARN |
| (Optional) ACM + Route 53 | Custom domain + HTTPS |
Terraform Resources Used
The key Terraform components for this setup:
-
aws_s3_bucket -
aws_s3_bucket_public_access_block -
aws_cloudfront_origin_access_control -
aws_cloudfront_distribution -
aws_s3_bucket_policy -
aws_s3_bucket_object(for uploading files)
Useful Terraform functions & patterns:
These enable automated file uploads, intelligent cache busting, and clean policy handling.
Common Gotchas & Tips
Use Origin Access Control, not deprecated OAI
Ensure bucket policy uses correct object ARN (/*)
Don’t mix bucket-level and object-level permissions
CloudFront creation/update takes time — be patient
Use invalidation only for urgent refreshes
Production-Ready Checklist
| Feature | Status |
|---|---|
| Custom domain via Route 53 | Recommended |
| SSL via AWS Certificate Manager (us-east-1) | Required for HTTPS |
| CI/CD integration | Upload site + apply Terraform |
| Security headers / Error pages | Best practice |
| Remote backend for Terraform state | Strongly recommended |
Key Takeaway
Always keep your S3 bucket private. Serve content only through CloudFront for maximum security, speed, and cost efficiency.
Terraform makes static site hosting predictable, version-controlled, and reusable. With modular structure, replicating environments like dev / stage / prod becomes effortless.
Final Thoughts
This exercise strengthened my understanding of real-world DevOps practices: security, scalability, automation, and global performance optimization. Starting from a basic bucket and distribution helped build up step-by-step confidence before integrating Route 53 and ACM.
If you’re deploying static sites — portfolio, documentation, landing pages, or dashboards — this architecture is powerful and production-ready.
Comments
Post a Comment