50 shades of .NET on AWS

One question I hear often from .NET developers is: “how can I host my .NET application on AWS?”. I systematically answer: “It depends”. In this article, I will walk you through the decision tree to use for deciding the best option to host your .NET application on AWS.

Author: Francois Bouteruche

At a first glance, my answer may be frustrating but it is the best and shortest answer I can provide. After all, which .NET are we talking about? Is it a .NET Framework application, a .NET Core or .NET 5+ application? It makes a huge difference. For example, if it is a .NET Core or a .NET 5+ application, you may be able to run your application on Linux and even target our ARM chip, Graviton 2. If it is a .NET Framework application, you will have to stick to Windows Server.

There are many other questions that drive the decision to relocate your application to Amazon EC2 instances (short for Elastic Compute Cloud, basically virtual machines) or, if you want to go in a different direction, to refactor your application to run as serverless functions on AWS Lambda, our serverless, event-driven compute engine. Let’s walk through the decision tree together.

Relocate/rehost your .NET application

The first thing you need to assess is if you want to continue to target virtual machines for hosting your applications. There are many reasons for this. Here are a few:

  • Your operations team is highly skilled at managing your infrastructure and you want to build on that.
  • Your operations and/or development teams have no container or serverless architecture skills.
  • Your application has specific requirements that will be easier to meet by using Amazon EC2 instances, e.g. many CPU cores, many gigabytes of memory, spot instance usage.

In this case, your .NET application should be hosted on Amazon EC2 instances. It will be on Windows if it is a .NET Framework application. It can be on Windows or Linux if it is a .NET Core or .NET 5+ application.

But even there, you still have a choice. Do you want to run self-managed Amazon EC2 instances or do you want AWS to manage your EC2 instances for you? If the second option is appealing to you then AWS Elastic Beanstalk is the right service to host your .NET application. It will manage your Amazon EC2 instances for you as well as your load balancer and your auto scaling group (which are optional). The auto scaling group will automatically increase or decrease instances based on a set of rules you define.

It you have a complex application that require DevOps expertise, you may prefer to self-manage your own Amazon EC2 instance fleet, your load balancer and your auto scaling group to have full control and optimize your workload.


Replatform your .NET application

If your .NET application is containerized or you are open to containerizing it, then a wide range of options are available to you.

Replatform your .NET Framework application

Let’s reduce the scope by first addressing the options for a .NET Framework application. In this case, you need to run Windows containers.

If you don’t want to manage the Amazon EC2 instances that will host your Windows containers, then your option is to use AWS Fargate with Amazon Elastic Container Service (Amazon ECS) managed Windows containers. AWS Fargate is a serverless compute engine for containers that runs your containers without you having to manage underlying compute hosts for your container instances. Amazon ECS Is our built-in container orchestrator. It can orchestrate your container instances on your own Amazon EC2 instance cluster or leverage AWS Fargate to save you much form the heavy lifting of managing compute hosts.

AWS Fargate may not fit your need because you may have specific hardware requirements that AWS Fargate is not able to cover. In this case, you will run your .NET containerized application on Amazon EC2 instances.

You still need to decide which container orchestrator you want to use: Kubernetes or Amazon Elastic Container Service. Kubernetes is an open-source container orchestration system managed by the Cloud Native Computing Foundation and widely supported. If you decide to invest in Kubernetes, you can host your .NET application on Amazon Elastic Kubernetes Service (Amazon EKS) with Amazon EC2 Windows instances. Amazon EKS offers you a managed Kubernetes-based container orchestration.

You may have no appetite for learning Kubernetes and prefer to use an orchestrator deeply integrated with the AWS platform. If so, you can host your .NET application on Amazon Elastic Container Service with Amazon EC2 Windows instances.

Replatform your .NET Core, .NET 5+ application

If your application is a .NET Core or .NET 5+ application, the question you need to answer is: do you want to run your application on Windows or Linux? There are many reasons for continuing to run your .NET Core/.NET 5+ application on Windows servers. Here are the two most common:

  • Your operations and/or development team is highly skilled on Windows operations and has less knowledge on Linux operations.
  • Your application has a dependency on a module that can run only on Windows.

In this case, the decision tree you have to walkthrough is basically the same as for .NET Framework applications.

To reduce your need for Windows Server licenses or standardize your operations on one operating system, you may also decide to run your .NET application on Linux. This offers you even more options. If a container is your favorite application packaging format you can continue there. If you are interested by serverless functions, jump directly to the next section.

If container is your choice, the next node in the decision tree is about the nature of your application. If you are building a publicly accessible Web application or API and want to sit in the passenger seat for operating your infrastructure, I would recommend to use AWS App Runner. It is a fully managed service for running your web or API application with no prior infrastructure experience required. Under the hood, it automatically deploys your application, load balances traffic with encryption and scales up and down the number of container instances to meet your traffic needs. But you don’t need to worry about all this.

However, not every .NET application is about public Web application or API. You may want to deploy a private Web application or API. You may want to deploy a background worker process. You may want to deploy batch jobs. Even in these cases you can let AWS manages the infrastructure, health check, scaling, etc. for you.

In this case, you will use AWS Fargate to run your containerized .NET applications and the last question you have to answer is whether you want to use Kubernetes as an orchestrator and thus Amazon EKS or our built-in orchestrator Amazon ECS.

If you have specific hardware or configuration requirements, you may want to consider deploying your .NET containerized application on self-managed compute hosts. It will offer you maximum flexibility on the configuration of your hosts. Here again, you end up by choosing between Amazon EKS or Amazon ECS.

Refactor to serverless functions

Finally, if you want to avoid using containers or want to leverage a fully managed infrastructure or you are developing event-oriented .NET applications, you are a candidate for using serverless functions and AWS Lambda, our serverless, event-driven compute engine.

If you want to leverage the event-driven nature of AWS Lambda compute and still use containers to package your application, you can. AWS Lambda offers you this flexibility.

The .NET Lambda function programming model is pretty straightforward. The code blow shows the default function handler method you get when you create a C# Lambda function for processing Amazon Simple Queue Service (Amazon SQS) events. Amazon SQS is a fully queue service. It can trigger your Lambda function each time a message or a batch of messages reach the queue. Your function handler receives an SQS event that contains the messages and all you have to do is to write the logic for processing the messages.

/// <summary>
/// This method is called for every Lambda invocation. This method takes in
/// an SQS event object and can be used to respond to SQS messages.
/// </summary>
/// <param name="evt"></param>
/// <param name="context"></param>
/// <returns></returns>
public async Task FunctionHandler(SQSEvent evt, ILambdaContext context)
foreach(var message in evt.Records)
await ProcessMessageAsync(message, context);


You really have 50 shades of .NET on AWS. Knowing which way to host is the right for you may seem overwhelming at first. If you use the decision tree we have gone through in this article, you will end up with the right option in the vast majority of the use cases.

You may have some use cases that sill don’t fit in this decision tree because of hardware, security, compliance, or business requirements. If so, don’t hesitate to reach out to the AWS community or AWS Developer Advocates like myself on social networks or on repost.aws.

If you want to learn more, I encourage you to visit our AWS .NET homepage (https://aws.amazon.com/dotnet) and to read our “Developing and Deploying .NET Applications on AWS” Whitepaper (https://go.aws/39NClk2). If you prefer videos, you can visit our .NET on AWS playlist on the AWS YouTube channel (https://bit.ly/dotnetonaws-youtube)

Author details:

Francois Bouteruche is currently a Senior Developer Advocate at Amazon Web Services, advocating for .NET and Java developers. He has a PhD in Computer Science and started his career working on handwriting recognition. He has more than 15 years of experience in .NET development and more than 8 years in the Cloud area. He joined AWS in 2019 to help .NET developers using AWS Cloud to build, test and deploy efficiently and securely on AWS Cloud.