The Short Version
- My blog has been migrated off of Wordpress and onto AWS S3
- I'm using AWS CodePipeline and CodeBuild to automate the deployment process as I commit posts to a private Github repository
- AWS CloudFront is running as a CDN which is providing a crazy fast cache as well as redundancy across the US
- The cost is estimated at less than $1 a month for the entire solution. Not bad!
- Grant's Blog design skills > my blog design skills
The Detailed Version
Since I started this blog, It's lived on WordPress, hosted through NameCheap. I never had any complaints with the service; they were great. Although my hosting plan grew in cost as time went on. A few weeks ago, my buddy @grantorchard started talking to me about his adventures in redesigning his own site using the concept of static sites; which I had never heard of. Taking a look at his site, and being extremely impressed at both the load time as well as general look and feel of the site; I was intrigued. Take a peek here - GrantOrchard.com. He was using a static site generator named Jekyll for his - and being absolutely jealous of my Australian brethren - I had to know more about this concept.
Starting to research, I was finding a common theme of people having some interesting quirks with Jekyll along the way; especially when migrating over from WordPress. I had some concerns around “breaking” my sites links on Google which would damage my search results and obviously cause a negative impact to my ranking. I wasn't immediately able to find an easy solutions to this in Jekyll (I'm ABSOLUTELY sure there is one and that it was my own failing Google-fu that prevented me from figuring it out). Coincidently, I noticed one of the more popular Bloggers in the vSpace, Scott Lowe had just made the move over to Hugo from Jekyll. Both of us being on Slack, I dropped him a message and as always he was happy to chat with me a bit about his reasons for changing over. A lot of his reasons were driven by the sheer size of his page and the rendering time in Jekyll. Wanting to do it right the first time; I decided to throw my chips in with Hugo.
I had always figured I would need to leverage a hosting provider of some type, or at minimum a server with a public IP address to be able to host a blog site. When I started digging around, I discovered that the majority of static site users run their sites on Amazon Web Services - S3. S3 is Amazons incredibly low cost object store. A cool feature is the ability to give your S3 bucket (collection of files) a web address and natively provide a “static site hosting” service - Awesome!
During bucket creation you area able to enable features such as versioning and logging to track access to the site. Upon completion of the Bucket, you're able to enable static site hosting right there. Ultimately, I found an awesome tutorial that took me through the entire process using the AWS CLI tool. That tutorial is located here - How to Guide - AWS and Hugo.
There are a ton of tools available for pulling in a WordPress XML export into the flat files used to build the static site in Jekyll/Hugo. The tool I used to migrate my data over was tuned specifically for Jekyll so I had to make some minor adjustments to the structure of the files that were output. Additionally, there was post tagging that I wanted to add to each one of my posts to make a bit friendly category search. Since many of my posts had pictures on them; I needed to pull down all my pictures off of my hosting provider and drop them into the Hugo directory as well as correct the image code for everyone of my posts to reference the right location. It took a few hours; but was relatively painless. There are tools that are supposed to handle all of this for me; but since I didn't have root access to the server hosting my WordPress blog; I was up the creek.
The architecture I've decided to utilized is based on the tutorial outlined above, with some adjustments to accommodate automation. Effectively we use an S3 bucket for the static site, behind a Route 53 Hosted DNS zone.
We then leverage AWS CloudFront as a CDN in front of that. This makes the site load blisteringly fast, because it's leveraging cached versions of the site all around the country. It'll also help ensure a great uptime; as the cached content should always be available as a replica.
There's a little bit of a frustrating downside that when you modify your page, you have to wait for the cache to update - but fortunately AWS CLI has a trick for that leveraging invalidations to effectively clear the cache. I felt like the trade off was worth it in my case. The performance is NOTICIBLY better. For those of you who are concerned about the cost of Invalidations, I highly suggest giving a read to the Invalidating Objects documentation from AWS. You get 1,000 request a month; a wildcard invalidation (glob) only counts as a single invalidation. Our script runs against the /* glob meaning that everything invalidates in one fail swoop. We should be solid there!
With the actual structure of our page settled; we move on to the publishing process. Amazon, being of the developer first mentality, has a ton of tools around making this easier for us. We'll detail more about posting to our site in the next section; but we're going to be using a Github repository to commit our posts to. I built an automated process using CodeBuild that spins up a Ubuntu container, pulls down Hugo and the AWS CLI, and then clones our repository. The site is built with Hugo, and then sync'd to our S3 bucket. AWS Code pipeline is then monitoring our repository watching for changes and when a commit occurs - it triggers our build process and updates our page.
Using the above demonstration of the pipeline as a guide, you can roughly plot out the process my posts run through now. Commits to Github lead to CodePipeline firing off CodeDeploy jobs running. The last 2 boxes aren't relevant to us because we're simply building the site and letting it sync over. We don't have a separate staging and production area. Neato!
Posting to a Hugo Site
Something I found really interesting is the concept of using the markdown language as a blogging tool. With WordPress I essentially had to be connected (unless I decided to write my post in Word and “copy” it over) and logged into the site in order to build my post. Since Hugo is written in markdown, now I use Visual Studio Code to write my posts. Hugo has a really cool live page generator that you can access by running Hugo Serve, and you can even tell it to render your draft posts by throwing a -D on the end (Hugo serve -D). This lets you build the post, and watch it render as you save your changes. This is helpful for tuning html, playing with CSS, or monitoring how long your post is getting! Best part of all - all of this is done locally. I can do this while im on a plane heading down to SoCal for meetings; completely disconnected. Once I have network connectivity again - I push my commit up to my repo and the automation handles the rest.
My primary goals for migrating off of WordPress were specifically
- Reduce overall cost of my blog. My renewal was slated for $78.88; plus more money for a new SSL certificate. AWS provided this for free as part of my migration
- Gain more experience with AWS services (S3, Route 53, CloudWatch, CodePipeline, CodeBuild)
- Gain more control over the structure of my page from an HTML perspective. I'm no Grant Orchard; but I'm working on it!
- Migrations can be rough if you have to touch every page. You can script parts of it to change paths; but count on some time to get there
- Personally, I like Jekyll's (Ruby) template syntax a lot more. Reminds me a lot of Jinja in Python. I'm certain this is more of a user error issue however. Golang is unfamilar to me still; and as I grow my Golang skills I'm sure I'll start feeling more comfortable.
All and all, I met the goals I was going for. Are there still things I need to clean up or optimize? Yeah. I used a theme; and there’s components of the theme that I need to clean out. Formatting is painful sometimes. People who work with CSS on a daily basis totally deserve a BIG hug. I haven't even touched implementing SEO functionality which was largely handled by plugins on Wordpress. With all that being said; I'm happy with the new platform. Happy to get back to blogging!
Look forward to sharing more as I go. Now that the migration is done; I can actually get going again!