Introduction
Let’s be honest: finding a decent way to host your portfolio or blog that doesn’t break the bank is trickier than it should be. I spent ages looking for an affordable and reliable setup. Since I already had a few things running on Amazon Web Services (AWS), I figured, “Why not keep everything under one roof?” In this article, I’ll show you how I host this blog (yes, what you’re reading right now, built with Astro.js) using AWS. Here’s the setup:
- S3 bucket: Stores your site files (super cheap and no server maintenance overhead or headaches with maintaining infrastructure)
- CloudFront: Acts as a CDN, so your site loads fast anywhere in the world
- Route 53: For registering a domain and providing DNS records
- ACM (AWS Certificate Manager): Free SSL so Google (and your visitors) don’t panic
The best part? This whole thing costs me less than a dollar a month, usually between $0.50 and $0.90 per site (the fixed cost is just $0.50 for Route 53). So basically, you can run a secure and stable site for about $12 a year - which is way cheaper than other services I’ve tried and has a lot less overhead than managing your own servers.
What you’ll need for this tutorial
- A domain you can use (not necessarily bought on AWS)
- A website you want to put online (I’m demoing with this blog, but this works for any static site)
- An AWS account (already set up - creating one is outside the scope here)
- About 30 - 60 minutes (and maybe your favorite beverage)
1. Create a New Route 53 Hosted Zone
Route 53 is AWS’s DNS service. Think of it as the address book that tells browsers where to find your site. First step: get yourself a domain; you don’t necessarily need to buy that on AWS. I prefer GoDaddy.com because it is the cheapest one in most cases. You can just update your name servers on your registrar’s website for your domain. You’ll find tutorials and guides by googling something like “GoDaddy domain change name servers”.
- Open Route 53 and create a “Hosted Zone” for your domain.
- AWS will give you nameservers. Copy these to your domain registrar so your domain points to AWS. If you didn’t buy your domain on AWS (I usually recommend GoDaddy.com as it is one of the cheapest options out there), update your nameservers there.
TODO: Add screenshot of Route 53 hosted zone creation
TODO: Add screenshot showing where to update nameservers if needed
2. Set Up AWS Certificate Manager (ACM)
Nobody likes “Not Secure” warnings in the browser!
- Go to AWS Certificate Manager and request a public certificate for your domain (make sure to add both
yourdomain.com
andwww.yourdomain.com
). - Choose DNS validation (it’s easiest if you’re using Route 53).
- ACM will prompt you to add a CNAME record. If you’re using Route 53, you can just click “Add record in Route 53” and you’re done.
Wait a few minutes for validation to complete (sometimes it’s instant, sometimes you’ll need to grab a snack. FYI: In IT, we like to call this a Cloud Minute).
TODO: Add screenshot of ACM request + DNS validation record
3. Create an S3 Bucket for Your Website
Jump into S3 and create a new bucket. Pick a name that matches your domain for convenience (like schufeli.blog). Please note that all bucket names must be unique throughout AWS’s entire infrastructure. So if, for example, yourdomain.com is already taken, you can use a different name, but keep in mind that you might need to find that bucket later on, so memorize the name and don’t set it to something random.
Important:
- Keep “Block all public access” enabled. (We’re going to keep things private; CloudFront will deliver your files.) Nobody needs direct access to your bucket files.
- No need to enable “Static website hosting” as we’ll use CloudFront for distribution.
TODO: Add screenshot of S3 bucket creation with block public access
Upload your built website files (for Astro, that’s the dist/ folder; for other static generators, it might be called build/ or something else). This is your project, so consult the documentation if you are unsure; ask Google or ChatGPT.
TODO: Add screenshot of uploading your site files
4. Create a CloudFront Distribution (CDN)
CloudFront is what keeps your site fast, global, and secure.
- Head to CloudFront and set up a new distribution.
- For the origin, choose your S3 bucket.
- To keep your S3 contents private, use “Origin Access Control” or “Origin Access Identity” (OAI). This means only CloudFront can fetch your files, and nobody else.
- In the “Default behavior,” set “Viewer protocol policy” to “Redirect HTTP to HTTPS” (so everyone gets SSL).
- Add your custom domain in the “Alternate domain name (CNAME)” field and link it to the SSL certificate you made earlier.
- Deploy the distribution. It may take 10 – 20 minutes, so go grab yourself a new cup of coffee.
TODO: Document how the DNS records can be created automatically
TODO: Add screenshot of creating a CloudFront distribution and configuring OAI
TODO: Add screenshot of SSL settings
Security Tips & Why This is Secure
- No public S3: Your bucket is private. Files can only be downloaded by CloudFront. This prevents random people (or bots) from accessing your files directly.
- Automatic SSL: ACM certificates are free, auto-renew, and work globally. No need to create a calendar entry on when to renew your certificates because you’d probably forget anyway.
- IAM Principle of Least Privilege: Only give your deployment tools enough permissions to push new site files, nothing more!
- CloudFront as a shield: CloudFront protects your S3 origin from DDoS and bad actors and gives you easy cache invalidation for quick updates.
Benefits of Doing It This Way
- Low cost: Route 53 hosted zone is $0.50/month. S3 storage and CDN traffic is pay-as-you-go (personally, most months it’s nearly nothing).
- No “Not Secure” messages: SSL is automatic and always up to date.
- Speed: CloudFront = CDN = fast site visitors, everywhere.
- No server management: Static file hosting, nothing to patch or update.
Summary
That’s it! By funneling all traffic through CloudFront and keeping S3 totally private, you get a blazing-fast, secure website for next to nothing, without any of the headaches of classic web hosting. AWS handles all the heavy lifting: SSL, DDoS protection, low latency, all the nerdy stuff that used to take hours.
If you want to see how I automate deployment with GitHub Actions, read my other article on how to do that.
TODO: Add link to other blog post
Happy shipping! 🚀