Hosting a Secure Static Website on AWS with S3, CloudFront, Route 53, ACM and Proper Logging
A while ago, I decided to do what sounded like a simple task: host a static website on AWS with my own domain and HTTPS.
Hosting a Secure Static Website on AWS with S3, CloudFront, Route 53, ACM and Proper Logging
A while ago, I decided to do what sounded like a simple task: host a static website on AWS with my own domain and HTTPS.
“How hard could it be?” I thought.
I uploaded my site to S3 in minutes and felt pretty confident until I tried adding a custom domain. That’s when the real journey began.
One tutorial told me to use CloudFront. Another said I needed ACM for SSL. Then Route 53 entered the picture. Suddenly I had multiple AWS tabs open, half a dozen docs bookmarked, and a growing list of questions:
- Why does the certificate have to be in us-east-1?
- Why am I getting 403 errors?
- Why does it work on the S3 endpoint but not my domain?
- And how do I even see who’s accessing my site?
Each service made sense on its own, but no one explained how they all connect together in a real setup.
After a lot of trial, error, and waiting for DNS propagation (more than I’d like to admit), the puzzle finally came together. And when it did, I realized something:
Most beginners don’t struggle with AWS because it’s too complex they struggle because the knowledge is scattered.
This post is the guide I wish I had when I started a single place that shows how S3, CloudFront, ACM, Route 53, and logging all work together to host a secure, production-ready static website.
If you’re doing this for the first time, you’re in the right place. Let’s put all the moving parts together, step by step.
This guide walks through setting up:
✅ S3 static hosting ✅ HTTPS using ACM ✅ CloudFront CDN ✅ Custom domain via Route 53 ✅ Logging to CloudWatch & S3
By the end, you’ll have a secure, production-style setup.
Architecture Overview

What each service does
S3 -Stores your website files (HTML/CSS/JS/images) -Acts as the origin
CloudFront -CDN for performance -Adds HTTPS -Protects S3 from direct access
ACM -Provides free SSL certificates
Route 53 -Connects your domain to CloudFront
Logging -CloudFront → S3 logs -Monitoring → CloudWatch
Step 1 — Create the S3 Bucket
1. Create a bucket Name = your domain (e.g., mydomain.com) Region = choose near your audience
2. Upload website files Upload: index.html error.html (optional)
3. Disable public access (Important!)
We’ll let CloudFront access it instead.
Step 2 — Enable Static Website Hosting
Inside S3: Properties → Static website hosting → Enable
Set: Index document: index.html Error document: error.html This gives a website endpoint — but don’t use it publicly.
We want CloudFront in front.
Step 3 — Request SSL Certificate (ACM)
Go to ACM: Important Rule Certificate MUST be in us-east-1 for CloudFront.
Request certificate: Add domain: example.com Add www.example.com (recommended) Choose: DNS validation ACM gives CNAME records.
Step 4 Validate via Route 53
If your domain is in Route 53: Click: Create records in Route 53 Wait a few minutes → status becomes Issued.
Step 5 Create CloudFront Distribution Origin: Select S3 bucket Use S3 REST endpoint (not website endpoint) Enable Origin Access Control (OAC) This keeps bucket private.
Default Behavior Settings Viewer protocol policy: Redirect HTTP to HTTPS
Cache policy: Managed-CachingOptimized
Attach SSL Certificate Under: Custom SSL certificate Choose your ACM certificate. Add domain names: example.com www.example.com
Step 6 Enable Logging Many skip this — but it’s crucial for debugging and analytics.
📁 CloudFront → S3 Logging Create a new bucket for logs: mydomain-logs
In CloudFront: Enable standard logging Select log bucket. Now you capture: Viewer IP Request paths Response codes User agents Great for analytics and security audits.
📊 CloudWatch Logging CloudFront integrates with CloudWatch for: -Metrics -Alarms -Monitoring traffic spikes Useful metrics: 4xx error rate 5xx error rate Total requests
Example alarm: Alert if 5xx errors > 5% for 5 minutes.
This helps detect outages early.
Step 7 — Configure Route 53 Create: A Record (Alias) Point to: CloudFront distribution Now: example.com → CloudFront → S3
Step 8 — Lock Down S3 Update bucket policy to allow only CloudFront: Example concept: Allow access from CloudFront OAC Deny public access This prevents direct downloads from S3.
Final Result
You now have: ✅ Secure HTTPS site ✅ Fast global delivery ✅ Custom domain ✅ Private S3 bucket ✅ Traffic logs ✅ Monitoring & alerts
This is production-grade hosting.
Beginner Tips
-
Propagation takes time DNS + CloudFront changes can take 10–30 minutes. Be patient.
-
403 Errors? Usually: OAC not configured Wrong bucket policy Wrong origin type
-
Start simple Don’t enable every feature at once. Build → Test → Improve.
Conclusion
Your first AWS website setup may feel overwhelming, but once you understand the role of each service, it clicks. Think of it like this:
S3 = storage CloudFront = delivery ACM = security Route 53 = navigation Logging = visibility
Master these and you’re already thinking like a cloud architect.
메타데이터
- post_id
- 5b8e05cfdbd9
- slug
- hosting-a-secure-static-website-on-aws-with-s3-cloudfront-route-53-acm-and-proper-logging-5b8e05cfdbd9
- url
- https://medium.com/@naved-shaikh/hosting-a-secure-static-website-on-aws-with-s3-cloudfront-route-53-acm-and-proper-logging-5b8e05cfdbd9
- canonical_url
- https://medium.com/@naved-shaikh/hosting-a-secure-static-website-on-aws-with-s3-cloudfront-route-53-acm-and-proper-logging-5b8e05cfdbd9
- author_url
- https://medium.com/@naved-shaikh
- status
- ok
- fetched_at
- 2026-09-05 06:16:23