Amazon Web Services has previewed an "opinionated deployment tool for .NET" as part of its pitch to attract .NET developers to its cloud services.
According to AWS software engineers Norm Johanson (who represents AWS on the .NET Foundation) and Philip Pittle, .NET developers struggle with questions like "what's the right service for my application?" and "how do I reduce the learning curve?"
Considering the number of different options for deploying applications to AWS, that is not a surprise, though arguably the best way to answer them is via research and experimentation rather than trusting a tool.
AWS thinks otherwise, and Johanson and Pittle said that "using this feedback, we decided to reverse the way we think about .NET developers deploying to AWS. Instead of providing a plethora of tooling for each of our compute services, we want to have a single tool that starts with the .NET application; a tool that provides an opinion and guides you to the right service for your application."
The AWS Deployment Tool recommended EC2 and Elastic Beanstalk but we chose the more interesting ECS option
.NET is a Microsoft technology, and Visual Studio has built-in deployment tools that will get a project up and running on the Azure cloud, using either Azure App Service for Windows or Linux, an Azure Virtual Machine, or packaging as a container in the Azure Container Registry. Although the publish wizard may not always come up with the best options, they work to get a deployment started and can be tweaked later. Possibly AWS has some Visual Studio envy, as the developer's initial choices may often evolve into significant deployments at a later date.
AWS is focused on Linux, even for .NET applications, so its new .NET deployment tool only targets what used to be called .NET Core (now just .NET) applications to Linux, not Windows. There is an intention to support .NET Lambda (serverless) functions but currently this still has separate tooling; the plan is to merge the two in future. The code for the deployment tool is on GitHub and depends on Node.js, with Docker also required for containerized deployments.
We took a sample .NET 5.0 project and gave the new AWS tool a quick try. Setup was a matter of configuring AWS credentials and then installing the tool via the dotnet command line. Our project was developed in C# using Visual Studio Code and uses a SQL Server database – a common combination for a .NET project. We opened up a terminal in VS Code and typed: dotnet aws deploy.
Is this what AWS wants to match? Microsoft's publish wizard in Visual Studio walks developers through several options for Azure deployment, and is smart about application dependencies such as database services
Our first effort failed because we ran the command at the top level of the project, where there is a solution file which ties together several projects that together form the application. The tool was unhappy about that: it did not understand solution files, only .csproj project files. We had to go into the project folder for the main project and run the tool there. It still had some chance of working, since the dependencies on the other projects were referenced from here. AWS did say that "we intend to integrate with IDEs like Visual Studio in the future," at which point we presume it would need to parse whole solutions.
The tool offered us two choices: Elastic Beanstalk on Linux (recommended), or ASP.NET Core app to Amazon ECS (Elastic Container Service) using Fargate, an AWS service for running containers. Why was Beanstalk recommended? It seems that the tool simply looks to see if there is a Dockerfile, defining a Docker container. If there is one it recommends ECS, otherwise it recommends a traditional EC2 VM managed by Elastic Beanstalk. This seemed to fall short as an intelligent recommendation, particularly as despite the absence of a Dockerfile we would normally package this app in a container.
These two high-level choices raised further questions. What EC2 instance type should Elastic Beanstalk use? Or if using ECS, what should be the task specification, which defines how much CPU and memory is allocated to each container? How many tasks should be allocated? We recommend a careful study of how ECS manages CPU and memory.
The deployment tool came up with what seemed to us rather arbitrary choices. Not all the details were shown by default, but clicking More showed additional information. The EC2 instance type for Elastic Beanstalk was blank, and the environment was set to SingleInstance. In the case of ECS, the tool proposed three Tasks with 256 CPU units and 512MB of RAM. The tool did not exercise the application to identify how much RAM it might need so we presume this is just a default.
The tool makes some decisions about ECS specification but does not bother with any metrics on how the application runs
Although the specification offered by the deployment tool seemed pretty much a stab in the dark, it did handle jobs like creating an ECS cluster and an IAM role to run it.
If the question is: how do I get something that works up and running on AWS, it looks like the tool will do that, subject to some caveats.
What caveats? Well, Microsoft's Visual Studio publish wizard is quite smart, and will do things like looking to see if a database is required, connecting to it, and running Entity Framework migrations which update the database schema to the latest version, if the .NET object-relational modelling tool is in use. The AWS deployment tool did nothing like this – though it is in its first preview. Johanson and Pittle said: "It's still early days for our new .NET deployment experience. This is a great time to try out the tool and give us feedback."
Our deployment using the tool would not have worked without further effort setting up a SQL Server on AWS.
Another question is how this initiative would fit with a typical DevOps pipeline. In the case of Microsoft's Visual Studio publish wizard, it can be handy for small projects but in many cases would be abandoned in favour of a scripted solution that would include tests and other precautions and enhancements. Production applications are also generally deployed to a staging environment.
The deployment tool does use AWS CloudFormation under the covers, a way of defining infrastructure as code, which means in principle that the output of the tool could be incorporated into a GitHub Action or AWS CodePipeline. The tool also includes the ability to list and delete deployments in one command, so clean-up of a developer experiment is straightforward. The tool is also able to redeploy updated applications so it would be possible to include it in a script that also performed tests or other actions.
According to the docs, the supported application types are not only ASP.NET Core web applications, but also Blazor WebAssembly, long-running service applications, and scheduled tasks. Both these latter types would be containerised, and the tool would do this automatically if needed.
The two big questions raised by this tool were first, whether AWS can catch up with Microsoft in offering a quick path from code editor to cloud deployment, and second, the extent to which wizard-type tools could make sensible decisions concerning the complex matter of how to choose appropriate and cost-effective cloud infrastructure for an application.
In its current state the AWS .NET Deployment tool is some distance from either goal; but no doubt will improve. There is brief documentation here.®