Setting up my Blog, Part I

My reasons for past failure isn’t that blogging is a particularly Herculean task. No, the problem is that I am a mule.

This first post is, appropriately, about trying to get this blog up and running. This is probably the 4-5th time I’ve attempted to get a blog started. My reasons for past failure isn’t that blogging is technically challenging or a particularly Herculean task. No, the problem is that I am a mule.

Each time I’ve gone to setup a blog, I’ve treated it like I approach many of the side projects in my life, by considering the journey to be of greatest value, not the destination. In 2015, in a combined effort to practice writing Infrastructure-as-Code, get more experience in the web side of Azure and get a blog hosted, I decided to setup a WordPress site in Azure. By trying to maximize what I’d get out of the journey, I ended up losing sight of the destination.

First, it's worth noting that I nearly always take on my larger learning, homelab or self-improvement projects over some block of time that I can dedicate to it. Typically a long weekend, staycation or the winter holidays.

So back in 2015, I worked through some IaC templates, got my resources working in Azure and started doing the work of actually getting WordPress installed and working. And then promptly ran out of time. Life got busy again, I went back to work and my setup fell to the wayside 65% complete.

In a repeat of the same story, I gave it another go over the winter break in 2017. This time I had the combined goal of learning to work with a Ruby project(Jekyll) and hosting/securing the whole environment in my homelab. I have a network engineering and security background and my homelab included a FortiGate firewall with a WAF license the company had provided me. I also intended to use Cloudflare proxy services to protect my home IP to some degree.

Somewhat predictably, I ended up with  facing my biggest nemesis for many of these personal projects, Yak Shaving. In order to be satisfied that I'd successfully deployed my blog, I had a list of prerequisite tasks that I'd need to accomplish. These included tasks I identified at the outset like setting up the WAF, Host and Jekyll. As well as the dozens of supplementary tasks my brain simply insisted had to be completed in order to 'do it right'. Setting up a new VLAN for the isolated host turned into an effort to better structure my homelab IPAM. Configuring the WAF turned into a side-mission of understanding how I planned to license my Fortinet stack once the 3-year licenses they provided me expired and an attempt to revisit a previous effort to bring the firewall into my Ansible automation. It wasn't enough to just follow a guide to get Jekyll running, I thought it best to learn a little Ruby while I was at it. You can likely see where this is going.

Over the years there were several other attempts of middling conviction. I was going to run a blog from my home K8S cluster. The cluster itself did get built and still runs along with the GitOps automation that I set out to practice. I was going to learn dotnet/C# and build a blog template. I ended up completing the excellent C# 101 course with Scott Hanselman and Kendra Haven, but haven't followed up much given that I don't use C# day-to-day.

This most recent attempt started in a similar way. I set myself a series of requirements that I wanted to meet:

  • Hosted entirely in Azure
  • IaC/CaC with CICD Pipelines in Azure DevOps or GitHub Actions
  • Application and Infrastructure Logging & Analytics
  • Built in a public repo
  • Backup to Azure Storage Account in separate tenant(more on that in Part II)

The only difference, and the reason you can read this post now, is that I set myself an ultimatum. By the end of this vacation, I will have a Blog running even if that means paying for a hosted SaaS solution(gasp!).

I may touch a little on why getting this blog up and running was so important to me in a future post.

Well the first part of this went predictably. I spent a few hours looking into various self-hosted blogging technologies and ultimately settled on Ghost. I like writing in Markdown, which is supported and the default theme and publishing tools are suitable. It also seems popular enough among the crowd of people I like to think of as peers that it seemed a doable task. I also looked at the miniblog dotnet core template but ultimately decided it was too streamlined for my tastes.

Initially, I’d planned to host it on Azure Web Apps and I found some folks who’d successfully added the necessary files to make this deployable directly to a Windows App Service. This particular implementation is well executed. This seemed reasonable but I saw a few concerns that changes to the ghost source code  occasionally broke this approach. I also didn’t like the idea of hosting the whole thing as one macroservice with an embedded database.

I found that Ghost publishes a docker container and several enterprising bloggers have documented their approach to hosting this in Azure, including App Insights monitoring and other key supporting technologies. One particular setup, documented by Ukrainian Azure Architect Andrew Matveychuk, seemed a really good fit for me. It met many of my requirements, it used entirely Azure Resources(except a docker repo, which I later switched to an Azure Container Repo) and had the framework of IaC that I could rework to meet my needs.

In part II, I’ll go through the work I did to make that setup work and meet the remainder of my needs while integrating with the rest of my Azure infra. Reader, it won't surprise you to discover at this point that the Yak Shaving turned this simple activity into a much lengthier one. Within 30 minutes of finding Andrew’s blog post I had successfully deployed his templates and could have called it done.

Ultimately, after getting the Azure Container App solution mentioned above working reliably and to my satisfaction, I concluded that while it met my needs, it just cost too much to be reasonable as a small blog project, read Part II for more details. Instead I fell back to a solution that finds it’s middle-ground somewhere between SaaS hosting and full-selfhosting. A fully self-contained droplet on Digital Ocean, fronted by my free Cloudflare WAF and proxy. I go into the specifics in Part III.

Thanks for reading this inaugural post.

Mastodon