A Static Hugo Blog on AWS CloudFront and S3, Part 1

Introduction

I have a blog. It’s not much. You’re reading it right now. It used to run wordpress, but I got tired of worrying about the security of it, since there was so little value there. I got tired of updating FreeBSD, updating Apache, updating PHP, MySQL, and everything that comes with that, just for the sake of a small blog. I wanted to make it just plain HTML and I wanted to use some serverless technologies from AWS (I work there, so I’m keen on understanding how I can use it). This is the first in what will probably be a multi-part series on absolutely every single step you have to do. None of this stuff is hard, but frankly if you’re starting from nothing, it’s a lot of steps. Many aren’t particularly intuitive unless you know what you’re doing.

I’ve done this whole process a few times now, and I can get it down to about an hour of wall-clock time “from soup to nuts”, as they say. If you’ve never done much of this before, I don’t expect you’ll be able to do it in a single sitting, much less a single hour. But you can do it. You really can.

My Goals for My Blog

  1. Serverless.
    No more worrying about a web server that can crash, be hacked into, or that needs updating.
  2. Mine.
    Savvy readers might ask why I don’t use Blogger, WordPress.com, GitHub pages, or any number of other online hosting systems that can do this for me. I want to own the site. I don’t want you go to anyone but me to get my content. No analytics. No tracking. No ads. No monetization. It is my blog. You have it. That’s it.
  3. Scalable.
    This is a bit embarrassing to admit, but I do hope that one day I will write a popular web page and it will get hundreds of thousands of hits. I don’t want to worry about my server crashing or failing under the load. I might only get one crack at fame—one super popular post—and I don’t want it to melt my server if it happens.
  4. Modern.
    The last time I updated my WordPress theme was probably 4 or 5 years ago. I wanted something responsive and modern looking.
  5. HTTPS Everywhere.
    I wanted my blog to be HTTPS and I was looking to get out of the certificate renewal game.
  6. AWS.
    I work there. I wanted to do this with AWS so I learn it better. That’s another reason it’s not on one of the other blogging platforms.
  7. Cost.
    By all accounts, it sounds like blogs like this are cheap. I’ll post the costs from my AWS Cost Explorer after I have some data. But I think you can run a blog like this for pennies a day ($1-$2 per month) unless you are popular. That’s cheaper than what it costs to run a virtual server at most places, and it has basically zero maintenance. And there’s a famous case of a guy’s blog going viral and he paid $1.50 for all the traffic.

Getting Started

All the hard bits come at the end. I’m going to start at the very beginning, assuming you have a domain name (either you’ve thought one up, or you already own one). I’m also going to assume you’ve never used AWS before. You’ll find things you can safely skip if you know how to do some of these steps, or if you’ve already done them.

AWS

Side note: access controls:

  1. Create a user in your AWS ccount
  2. Create a policy for mucking with THIS bucket but no other buckets
  3. Issue access keys for that user
  4. Attach the policy to that user

Using credentials that will work… 1. Get a domain name 2. Create a Hosted Zone in Route 53 3. Request a certificate. Possibly add other names like www.example.com. 4. Do DNS based verification and let it create the route53 record 5. Create the S3 bucket - not public

  1. Create the CloudFront distribution
    1. Enter the S3 bucket for Origin Domain Name
    2. Leave the path blank
    3. Leave the Origin ID as is
    4. Choose “yes” for restrict bucket access
    5. Tell it to create a new identity
    6. Choose “Yes, Update Bucket Policy”
    7. Ignore custom headers
    8. Choose “redirect HTTP to HTTPS”
      • Choose GET, HEAD, OPTIONS
    9. Tick options to cache.
    10. Cache based on selected headers. Choose “Whitelist”. Add 3 headers:
      • Access-Control-Request-Headers
      • Access-Control-Request-Method
      • Origin
    11. Compress: Yes
    12. Price Class. I use EU and US only. You can pick what you like.
    13. Alternate names. Add your custom name, like example.com. Also add www.example.com if you were doing example.com.
    14. Custom SSL certificate. Pick the one that has the right name.
    15. Default Root Object: index.html
    16. Click “Create”. Wait 20 minutes.
  2. Create an A record in Route53. Set it to the cloudfront distribution.
    • Choose alias yes
    • choose the CF distribution as the target
    • Might complain that the distribution doesn’t have a state of “deployed”