There’s been a surge in the number of ways to author APIs using .NET in AWS over the last two years thanks to the arrival of .NET Core, Platforms as a Service, containers, and serverless. Mix in concepts like microservices and distributed architectures and it can be confusing to know when to use which technology.
The tech stack of choice depends a lot on the flavour of .NET that’s being used. For that reason I’ve broken my recommendations into two parts: .NET Framework and .NET Core. I’ve purposefully ignored broader architectural patterns in my thought process because the solution that delivers the most business value is always going to be the one that provides the most flexibility with the least effort to get to market.
.NET Framework: Elastic Beanstalk
By far the best option for hosting Web APIs built in .NET 4.6 and below is Beanstalk. It’s backed by EC2 Windows instances, which incidentally was the only way to host .NET in AWS for the longest time. Its biggest strength is its ability to abstract away the details of orchestrating and preparing Windows infrastructure, instead letting you focus on building and deploying code.
Beanstalk comes with a bunch of cool features including auto-scaling groups and Blue/Green deployments. Autoscaling makes it easy to size your application correctly based on a schedule or a resource utilization metric. Scaling horizontally is one of the best ways to keep your service responsive under heavy load, and Beanstalk takes most of the guesswork out of the equation by doing it for you.
Blue/Green deployments reduce the risk of deploying to production by hosting the current version of an application on one set of machines and the new version on a second set of machines. Flipping back and forth between the two versions is achieved via DNS, making it easy to go back to the previous version of the application if there’s a problem with the deployment.
Building a high quality service isn’t easy. Trying to manage your own EC2 instances is a headache unto its own. Let Beanstalk take infrastructure out of the equation by taking care of it for you.
.NET Core: A Handful of Options
Microsoft is working hard to increase .NET Core adoption for the development of new applications and migrations of old apps. The arguments are compelling. Lightweight, better performance, and the ability to run your application on Linux. This flexibility opens it up to a lot more options that don’t exist for the full .NET Framework within the AWS ecosystem.
My first recommendation is Beanstalk once again. It can host both .NET Framework and .NET Core apps simultaneously, making Beanstalk the ideal way to migrate existing applications to the newest version of .NET. You get all the same features and simplicity mentioned above for the .NET Framework, making it the clear favorite to run a .NET Core API.
.NET Core applications can run on Linux machines but as of the time of writing it doesn’t appear possible to host a .NET Core app on a Linux Beanstalk environment. Hopefully AWS will rectify this sooner rather than later. The gains are obvious: a Linux machine is about 30% cheaper than its Windows equivalent. Over the course of a year that adds up to decent cost savings.
There’s one big disadvantage to Beanstalk (or any other PaaS for that matter) and that’s vendor lock-in. It’s a lot more work to move a Beanstalk application to another platform because the technology is AWS-specific. Then again, it may not be a huge deal if you’re continuing to invest in other parts of AWS.
API Gateway and Lambda
I’m a huge fan of serverless and more specifically, Lambda. It now has two supported development paradigms for .NET Core.
The first, more traditional approach, is to reduce an API to a series of small functions that do a single operation. For example, having one function for a GET, and another for a POST. Use this approach when you have a very basic API that needs to expose only a few endpoints. But beware, this development model has a bit of a learning curve for developers used to writing Web API projects in Visual Studio.
A second approach has presented itself with the adoption of .NET Core 2 in Lambda. It’s almost too good to be true: Web API applications hosted in Lambda! The advantages to this approach are obvious. A Web API project in Visual Studio has a structure that is familiar to most developers and makes it easy to see at a glance how the API is structured. Supporting this development model is likely to increase the adoption of serverless with .NET Core and I can’t wait to read some case studies on it.
Elastic Container Service
This recommendation stems directly from the fact that .NET Core apps can run natively on Linux. Whilst Windows containers are supported on AWS, the Linux tooling on AWS is way ahead of its Windows counterparts.
The great thing about containers is they can easily be used in any orchestrator without needing to change a thing from the application’s point of view. That gives a team additional flexibility when compared to Beanstalk or Serverless, since both of those tend to lock you in to AWS’s ecosystem.
There are so many options on the containers side of the equation that you’ll want to have at least one person dedicated to the operationalization of your container strategy. Out of all the technologies to run a Web API on AWS, this is the one with the most knobs to turn and buttons to press.