Brewing the Blog

Why I Chose ASP.NET Core and AWS For My Blog

by JamesQMurphy | May 25, 2019

DevOps can mean lots of things to different people. But it almost always involves Continuous Integration and Continuous Delivery (CI/CD) -- the processes necessary to refine a set of source code and take it from a developer workstation into a real production environment. I've been doing it for a while and I always wanted to showcase a complete CI/CD pipeline. I wanted to show everybody the entire process, and not just with pictures. I want to demonstrate a CI/CD pipeline with real tools that you (yes you) could actually go and look at.

So in this series of blog posts, I'll demonstrate how I set up the CI/CD pipeline for this blog site. Yes, this site -- the one you are reading right now. This site started as a summer project to get myself back up-to-speed with web technologies (while the rest of the world was learning JavaScript and Angular, I was learning PowerShell). You'll be able to see all of it: the source code, the build and deployment pipelines, and even the hosting environment as well. (Well, that's the goal at least.)

Selecting the Right Ingredients

Even before I settled on the idea of a blog, I knew that I wanted to develop an ASP.NET Core application. With cross-platform technologies all the rage, I knew I had to be proficient in at least one of them. Getting up-to-speed on my JavaScript for front-end work was going to be challenging enough. So I decided that for server-side code, I'd stick with what I'd know: Good old C#. Well... not really old C#... we're talking about C# 7.1 here. But still, I knew C# much better than any of the alternatives (Python, JavaScript, Go, etc.), so the decision was pretty easy. The app was going to be an ASP.NET Core application. As of this writing, the current version is 2.2, while ASP.NET Core 3.0 is in preview. Since I've never developed an ASP.NET Core app before, I decided to start out with version 2.2. This way, when ASP.NET 3.0 finally did get released, I could better appreciate the features and upgrades.

I also considered using Visual Studio Code to do the development work, but I ran into some odd behavior when toying with the ASP.NET 3.0 samples (for instance, the web browser wouldn't automatically start when I hit F5, even though it did for an ASP.NET 2.2 app). So I decided to stick with Visual Studio; specifically, I used Visual Studio 2019 Community Edition.

Clouds in my Cold-Brew

My inbox is littered with e-mails that scream, "Urgent need for DevOps Engineer with Cloud Experience!" 1 Pick up any DevOps job requirement and you'll see that cloud experience is almost always a prerequisite. Most job requirements want to see either Amazon Web Services (AWS) or Microsoft's Azure platform. I had played around with Azure in the past, so I knew I could go that route. In fact, Azure makes it really easy to host an ASP.NET Core application.

But honestly, I wanted to see how the other half lived. I really wanted to use AWS to host the site.

ASP.NET Core on the cheap

But what about cost? I knew that I wasn't going to get something completely free, yet I didn't want to spend more than $20/month. So right away, I knew that I wasn't going to have my own servers, even in a cloud environment. (Servers cost money no matter where you go). That leaves serverless platforms, and both Azure and AWS have solutions for that. With Azure, you can host an ASP.NET Core application using their App Service solution. However, even that gets pricey. The cheapest level that lets you have your own domain with SSL is their Basic level, and at the time of this writing, their cheapest Basic level tier (B1) runs over $50/month.

AWS, on the other hand, offers their AWS Free Tier, which is split into "free for a year" and "always free" lists. Putting aside the goodies on the "free for a year" list, the "always free" list was still intriguing. The two services that caught my eye were DynamoDB (an object database) and Lambda (their serverless compute engine). Both of these services are the "always-free" tier, which offers 25 GB of DynamoDB storage and a whopping 1 million requests per month for Lambda.

Now, Lambda is typically programmed using JavaScript or Python. Could Lambda be used for ASP.NET Core? The answer is a qualified yes. Out of the box, AWS Lambda supports versions of .NET Core that are in long-term support -- in other words, older versions (up to 2.1 as of this writing). But the support for ASP.NET Core is there; see Serverless ASP.NET Core 2.0 Application and Updates for serverless ASP.NET Core. What's more, just this past year, AWS announced the ability to run newer versions in Lambda, if you're willing to do a little bit of work and deploy your app self-contained.

What about the parts of AWS that you do have to pay for? With AWS, the nice part is that you pay for what you actually use. First, there's file storage, and that's the popular AWS S3 (Simple Storage Solution). They charge by the GB monthly, and it depends on the AWS region. For me, using the popular US-East-1 region would cost $2.30/month for 10GB of storage. Then there's data transfer. As we'll see later, I made use of AWS Gateway API to expose AWS Lambda and S3 to the outside world. $3.50/month per million hits in, and $0.09 per GB transferred out. Not only can you hook up your own domain, you can use SSL (in fact, with Gateway API, you have to, but I'm not complaining). And if you don't mind using Amazon's certificate for your custom domain, that's free too. Not to sound like an Amazon fan-boy, but this was a fantastic deal. A real ASP.NET Core site, with SSL, for a few dollars a month until I see actual real traffic. Winner: AWS.

In case you were wondering, did I ever look at other hosting sites, like GoDaddy? I didn't, but I didn't have to. Most of those sites offer straight hosting, with no application tier (PHP if you're lucky to get it). Scott Hanselman did manage to get an ASP.NET Core site running on one of these sites, but it was not a sustainable solution. Read about it here.

Source Control -- the obvious choice

The next choice was an easy one: version control. Since I am showing how this site is built, the source code needs to be publicly available. And that, of course, means GitHub. Besides being the obvious choice from a public availability standpoint, there was another factor to consider... continuous integration builds and deployments (CI/CD). Just about every CI build system on the planet can access and integrate with GitHub (they usually support their own repository and offer GitHub as the alternative). And speaking of continuous integration...

The CI/CD Pipeline

This is where the honeymoon ends with AWS. While AWS does offer build tools in their "always free" tier, it's not all that impressive. Sure, you get 100 hours per month of AWS CodeBuild, which isn't too bad, except that the features are somewhat paltry (for example, you can't even get the name of the branch that triggered your build). And you can only have one active AWS CodePipeline per month.

Microsoft's Azure DevOps Services, on the other hand, have superb continuous-integration tools, even if they keep renaming it every other year (it's really just Visual Studio Online, which used to be Visual Studio Team Services, which is really just an online version of Team Foundation Server). I've been working with the redesigned build engine for a few years now, and it keeps getting better. Plus, you get unlimited build minutes and up to ten parallel build pipelines for open-source projects. (Even the more traditional Microsoft-hosted pipeline, although limited to only one free pipeline, gives you 1,800 free hours per month. Yeah, 75 days' worth of build time in each month.) And yes, it can totally deploy to AWS.

Thus, the technology choices are:

  • Platform: ASP.NET Core 2.2
  • Source Control: GitHub
  • Continuous Integration: Microsoft Azure DevOps Pipelines
  • Hosting: Amazon Web Services (Lambda, S3, and Gateway API)

In the next post, I'll describe setting up the initial project.


  1. Well it used to be. Nowadays, I filter out messages with the words urgent need in the subject.