This site runs on AWS. S3 for storage, CloudFront for distribution. Fast, secure, costs about $2-3 per month.
Why Static Sites?
I’ve run WordPress sites, custom CMSs, application servers. For content sites, static hosting is better.
No server-side code means no vulnerabilities to patch. No database means no SQL injection. Pre-built HTML from a CDN is fast - no queries, no rendering, just files from the nearest edge location.
S3 storage is pennies. CloudFront bandwidth is minimal. Compare that to $20-50/month for managed WordPress or running EC2 24/7.
The Setup
S3 stores the files. CloudFront serves them globally with caching and SSL. Route 53 handles DNS. ACM provides free SSL certificates.
S3: Website Hosting
Enable S3 static website hosting. Bucket is public with read-only access. CloudFront uses the S3 website endpoint.
This is the correct setup for static websites. S3 website hosting was designed for this exact use case.
Why this approach:
- Directory index support -
/tags/msp→/tags/msp/index.htmlautomatically - Custom error pages - 404 handling works natively
- RFC 3986 compliant - Proper URI handling for web content
- Simple configuration - No Lambda@Edge or complex routing needed
- HTTPS via CloudFront - Secure delivery even with public S3 bucket
The bucket is public (read-only), but that’s fine. You’re hosting a public website. The files are meant to be public. CloudFront adds HTTPS, caching, and security headers on top.
CloudFront: Global Distribution
CloudFront sits in front of S3. Visitors hit an edge location near them. Content gets cached at edge locations. Most requests never touch S3.
CloudFront handles HTTPS, custom domains, compression, security headers. Redirect HTTP to HTTPS. Compress automatically. Custom error pages.
Use Response Headers Policy for security - CSP, HSTS, X-Frame-Options. Protects against vulnerabilities without application code.
Route 53 and ACM
Point your domain to CloudFront with alias records. Free query charges. Works for apex domains and subdomains.
ACM provides free SSL with auto-renewal. Request certificate, validate via DNS, attach to CloudFront. Certificate must be in us-east-1.
Security
Static sites are more secure. Configuration still matters.
Content Security Policy (CSP) restricts what loads. Configure it in CloudFront Response Headers Policy. Default-deny everything, then explicitly allow trusted sources. Scripts from self and CDNs only. No inline scripts, no eval().
Example CSP configuration:
default-src 'none';
script-src 'self' https://cdnjs.cloudflare.com;
style-src 'self' https://cdnjs.cloudflare.com;
img-src 'self' data:;
font-src 'self' data:;
connect-src 'self';
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
Add HSTS to force HTTPS. X-Content-Type-Options to prevent MIME sniffing. X-Frame-Options to block framing. CloudFront Response Headers Policy handles all of this.
Enable S3 versioning for rollback capability. For public S3 website hosting, bucket policy allows public read access (files are public anyway - it’s a website). Access logging for audit trails.
Deploy Process
I use Hugo. Works with Jekyll, Gatsby, Next.js, 11ty, whatever.
- Build (
hugo --cleanDestinationDir) - Sync to S3 (
aws s3 sync) - Invalidate CloudFront (
aws cloudfront create-invalidation)
Takes 30 seconds. Live globally in minutes. First 1,000 invalidations free monthly.
What It Costs
Real numbers:
- S3 Storage: $0.20/month for 10GB
- S3 Requests: $0.10/month
- CloudFront: $1.00/month for moderate traffic
- Route 53: $0.50/month
- ACM: Free
Total: ~$2/month
WAF adds $5-10/month for bot protection. Overkill for most blogs.
Cost Scaling Warning
These costs are based on a low-traffic content site (~100k requests/month). CloudFront costs scale with bandwidth and request volume. High-traffic sites can cost significantly more. Calculate your expected costs before deploying. See Terms of Service for important disclaimers.
When This Doesn’t Work
Need dynamic infrastructure for:
- User-generated content
- Real-time features
- Complex forms
- Personalized content per user
You’ll need application servers and databases. But for blogs, documentation, portfolios? Static wins.
Cloud Reliability Reality
AWS markets 99.999999999% durability. No infrastructure is perfect.
The November 2025 AWS outage reminded everyone. Services down across regions. When your cloud provider has an outage, you’re down. You wait.
That’s the trade-off. You get AWS’s engineering and redundancy. When AWS has a bad day, you have a bad day.
For a content site, makes sense. Outage lasted hours, not days. AWS track record is solid. Multi-cloud redundancy costs exponentially more.
If you have SLA commitments or revenue tied to uptime, multi-region failover makes sense. For a blog? Accept occasional outages.
The cloud is someone else’s computers. They break sometimes.
Why I Use This
I’ve built complex infrastructures. Load balancers, auto-scaling, RDS, microservices. Necessary for the right workloads.
For this site? No maintenance. No patches, no updates, no server management. Security by design. Fast delivery. Pay for usage, not idle compute.
Fast, secure, cheap. Zero time on infrastructure. I write content, not manage servers.
Getting Started
Setup takes an hour or two.
Choose a static site generator. Create S3 bucket with website hosting enabled. Setup CloudFront pointing to S3 website endpoint. Configure Route 53. Add ACM certificate. Security headers. Deployment script.
Then just write and deploy. No patching, no updates, no backups. Infrastructure runs itself.