In this multi-part series, I'll run through my process for architecting and deploying a self-hosted blog. When starting this journey I asked myself whether I wanted to do Ops or write posts. The thought being if I get caught up with maintaining the systems to run the blog, how much time will be left over to write? I went back and forth a few times. On one hand, rolling my own meant having to secure and maintain the infrastructure while a hosted solution would allow me to start writing immediately without any prior groundwork. Pricing for the platform I chose isn't exactly cheap for a passion project with no revenue but the creators did open source it to allow self-hosting. Then there's the elephant in the room, content. What will I write about? After weighing this all up I decided on what will hopefully be a silver bullet. I'll self-host an off the shelf blogging platform in a public cloud with additional layers of security where possible and automate the entire process so someone else in my position doesn't have to bother! To top it all off, this can be my first few posts. So here we are and the best bit, if I or anyone else attempting this later decide to move to the hosted version it's a simple export and reimport.
Architecture
As a starting point for this project let's outline some high-level objectives that we want to meet. This will help us stay consistent and on track throughout the implementation process.
Requirements:
- Blogging platform (no statically generated sites or cumbersome upload process)
- Minimal ongoing maintenance
- Cost-effective
- Reasonably secure
- Best effort availability
- Fully automated deployment
Blogging Platform
TL;DR: Ghost
When it came to the blogging platform, I wanted something pleasant to use and opinionated. The idea being, if it's opinionated someone has already thought through a workflow. Highly flexible products are great for complex use cases but for this, I just want to jump in and write without distractions. WordPress and Ghost were the first two options that came to mind. For me, the writing experience in Ghost seemed more polished and less distracting, plus, seeing various complaints online about plugin conflicts and upgrade compatibility with WordPress gave me the type of Ops headache I knew I didn't want to support. Don't get me wrong, WordPress is a great product. It runs 39% of the top 10 million websites according to Wikipedia but for my narrow use case I just like Ghost better. No hard feelings WordPress!
Automation - Infrastructure as Code (IaC)
TL;DR: Terraform
Infrastructure as Code (IaC) lets you define servers, networks and other supporting infrastructure and services in a config file. This file tells a provider (usually a cloud provider like AWS or Azure) what you want to be built and how it should be configured. This is super powerful because when written properly it allows you to deploy your application/solution very quickly and in a repeatable fashion.
For example, say you’ve got an application and a customer who wants an isolated deployment. Easy done, just run the template to deploy your application again!
I’ve also found IaC great for helping create new projects faster since you can pre-write base configurations. If every stack you build has a network, server and firewall why should you write that every time? Just take a copy of an old template and update it to fit your new use case. This avoids you having to start from scratch each time.
IaC tools are available from several providers, some tools are vendor-specific such as AWS’s CloudFormation while others are open source and vendor agnostic such as HashiCorp’s Terraform. The benefit of vendor created tools like CloudFormation is that they’re natively supported by the company (in this case AWS) and therefore generally support new features quickly. On the other hand, vendor-agnostic tools support a wide array of vendors giving you the flexibility to choose tools and services from different companies or projects.
Terraform will be the IaC solution to champion the automation and repeatability requirements of our project. The choice of Terraform was a pretty simple one. It's open-source, free and supports a wide range of providers so we can pick and choose the products that deliver the best 'bang for buck' without impacting our ability to offer a fully automated solution.
Cloud Provider
TL;DR: AWS
You've probably noticed there's no shortage of cloud providers on the market. There's AWS, Azure, GCP, Linode, Digital Ocean just to name a few. I've decided to go with Amazon Web Services. I could list several reasons why I chose AWS but in reality, it was the platform I was most comfortable with when building the solution.
CDN, WAF, DNS
TL;DR: CloudFlare
This probably comes as no surprise to tech enthusiasts. Cloudflare is the provider of choice for our Content Delivery Network (CDN), Web Application Firewall (WAF) and Domain Name System (DNS) services. I have no idea how they manage to offer this many services for free but Kudo's to the team at Cloudflare. You guys truly are exceptional!
Content Delivery Network (CDN)
A CDN service is a bunch of servers located all over the world that keep a copy of your website as close as possible to your users so they can load your website quicker. When someone accesses your website for the first time the CDN will keep a copy of your website so anyone else in the area asking for the site doesn't need to go back to your server to get it. This not only increases performance but can also save you money by minimising the network traffic to your server because the CDN is sending it for you instead!
https://www.cloudflare.com/en-gb/learning/cdn/what-is-a-cdn/
Web Application Firewall (WAF)
A WAF is a firewall built specifically for handling web requests. This will allow us to set up specific rules around how web traffic to our server is handled. We will use this predominately for securing the administrative pages of our blog by IP address.
WAF's can also protect against DDoS attacks. This is when a large number of computers send a large number of requests in an attempt to bring a server offline. Luckily for us, CloudFlare will act as the entry point for requests to our web server. Since they have such a huge capacity they can send the traffic off somewhere else and prevent our server from being overwhelmed.
https://www.cloudflare.com/en-au/learning/ddos/glossary/web-application-firewall-waf/
Domain Name System (DNS)
DNS resolves web names like "www.lukefaccin.com" to addresses that computers understand like "1.1.1.1". This lets your computer know where it needs to go to get the website you're asking to load.
https://www.cloudflare.com/en-au/learning/dns/what-is-dns/
Putting it all together
So now that we've picked our tech stack let's put it together.

We'll start out by creating an EC2 Instance, wrapping it in a network (Security Group, Subnet, VPC, etc) and then building out supporting services (Cloudflare) and automations.
Up Next
So that's our project! In the next post, we'll get our hands dirty with the technical build.