Migrating our trusty ol’ .NET Framework applications to AWS, I couldn’t believe it!
AWS 🧡 .NET?
When Inès, our CTO, announced that the company has decided to migrate all-in on AWS, as a .NET developer, I was a bit concerned. My team and I are used to Visual Studio and we are just one click away from a much “bluer” cloud provider since several versions of Visual Studio now. Even in the .NET documentation, you find lots of code examples adapted to this bluer cloud provider. I was even wondering if it was even possible to run .NET applications on AWS.
I Love My Local Farmer is a fictional company inspired by customer interactions with AWS Solutions Architects. Any stories told in this blog are not related to a specific customer. Similarities with any real companies, people, or situations are purely coincidental. Stories in this blog represent the views of the authors and are not endorsed by AWS.
To be honest, I think my team and I went through all the steps of the Cycle of Acceptance. We first denied this announcement. Why would we need to migrate our trusty ol’ .NET Framework applications to the Cloud? They work perfectly well for years. Our platform is very stable and we release new features twice a year (sic).
Then we went angry. Why did nobody asked us? We would have told you that if a Cloud migration was really needed, a bluer Cloud would have been easier for us as it is fully integrated in our IDE. I escalated and had a discussion with Inès and our Head of Development. They took time to explain to me all the good reasons that the company, as a whole, has decided to migrate to AWS. If you’re interested in this, Inès has written a series of 4 posts explaining how the company came to the decision of migrating all-in onto AWS (post 1, post 2, post 3, post 4). When I got out of this meeting, I was clearly at the depression step of the cycle. How would we handle this?
The light came from, Melina, one of our team members. She attended an online event of the DevTalks .NET meetup in Paris. An AWS Developer Advocate delivered a talk called “50 shades of .NET on AWS”. The video recording is there but be warned: it is in French since we are :) The key takeaways she shared with us are that AWS supports Windows Server, SQL Server and .NET since 2008. AWS also provides a bunch of tools to support .NET developers and numerous hosting options for .NET applications. It was time for us to bargain. We didn’t want to be left behind nor become obsolete. So we started to look into this thing called AWS and what it has to offer us .NET developers.
Don’t take me out of my preferred IDE!
First things first, we love our IDE. And we are not alone. Visual Studio was ranked #2 in 2021 Stackoverflow survey with 33.03% of respondents using it. So we don’t want to get out of it. For development and testing purposes, we love the Right-Click and Publish feature. Of course, we don’t use it to deploy into production. We were curious to see if we would be able to deploy our .NET Web Applications from our IDE directly to AWS.
The answer is “Yes, we can!”. But of course, you can’t out of the box. AWS provides a pretty cool Visual Studio extension called AWS Toolkit for Visual Studio. Once you’ve installed it, you first need to configure your AWS Credentials to access your AWS Account. Then, you get the AWS Explorer view that allows you to explore and interact with the AWS services deployed into your account. Beware, not all AWS Services are supported here, but you will find the services you will most likely use to host your .NET applications. For our .NET Framework applications, we could Right-Click-Publish to AWS Elastic Beanstalk by default. The first time I saw this name in my Visual Studio IDE, I had no idea what it is but I will come back to this later.
Do you speak my language?
The second thing we explored was how to interact with AWS services from our C# code. We didn’t intend to strongly couple our code to AWS services, but during our exploration we discovered a few services that seemed to offer very low hanging fruits. The most appealing one was Amazon S3. You probably already heard about this cloud object storage service. It looked like an obvious solution to offload serving static content from our IIS servers. But what would have been the point if we had to develop our own .NET Framework client for Amazon S3 API?
Once again, we were surprised to discover that the AWS SDK for .NET was the first official SDK released by AWS and is more than 10 years old. It offers client implementations for AWS services with common patterns for authentication and authorization. In addition, AWS provides additional libraries that extend the integration of AWS services with .NET or popular 3rd party .NET libraries. For example, you can use AWS Logging .NET to integrate popular .NET logging libraries like NLog, Apache log4net, ASP.NET Core Logging or Serilog with Amazon CloudWatch Logs service. As its name suggests, it is a managed logs service provided by AWS.
Power(my)Shell or I bash you
As long time Windows Server users, we learned PowerShell. I know there are lovers and haters of PowerShell, I won’t go into this debate here. All I know is that when you’ve started to administer your Windows Servers with PowerShell, you don’t fall back to the default Windows command prompt. And obviously, you won’t administer Windows with Bash. So, we learnt PowerShell. Our ops team learned to administer and operate our Windows servers environments. Our dev team learned a bit of PowerShell to interact with our dev and test Windows Server environments.
We were glad to discover that the AWS Tools for PowerShell provide PowerShell modules. They enable us to script operations on our AWS resources from our usual scripting language. We could use it to create, start and stop our servers for example. Another box checked by AWS that I wouldn’t have bet on.
Do you have sweets for us?
It was our very own surprise that AWS fulfills these three basic yet mandatory requirements. At that point, I was a bit ashamed by my own unconscious bias and became hungry for more. Does AWS have sweets for us? Yes, and here are those we love the most.
The curse of choice — our hosting options
When I looked at the hosting options, I realized that they offered a full range of hosting options for our .NET Framework applications. It goes from hosting our .NET Framework applications on raw EC2 instances (that’s how they call virtual machines) that we have to fully configure and operate by ourselves to deploying Windows containers workload on managed orchestrators. In between, you find managed services like Amazon Lightsail well-suited for small projects or individual developers and AWS Elastic Beanstalk that basically manages your load balancer and your Windows servers for you for larger projects where you need more fine grained configuration options. The same goes for SQL Server. You can run it to EC2 instances and operate it by yourself or opt in for the fully managed database service Amazon RDS and its SQL Server flavor.
Make me feel at home — support Team Foundation Server
We arrived at a point where hosting our .NET Framework applications on AWS became a viable option in our mind. But before hosting, you need to deploy. For our integration and deployment pipelines, my team has relied on Team Foundation Server for years. But you know what? They support it! I couldn’t believe it at first though it makes sense when you think about it. If they support the IDE, the language and provide hosting options for .NET Framework applications, why would they ignore the de-facto standard CI/CD tools for .NET? Thus, they provide the AWS Toolkit for Azure DevOps, a convenient extension that brings the AWS related tasks you need to deploy on AWS from Team Foundation Server. Indeed, the extension works both on premise with Team Foundation Server or on Azure DevOps, the SaaS offering. Mind blowing!
Back to the future — hello .NET Core / .NET
You probably know that .NET Framework has no future. Only .NET does. So we were stuck in the middle of nowhere if we don’t port our .NET Framework applications to .NET at some point in time. We had this in the back of our heads for a while. The upcoming release of .NET 6 which is a Long Term Support seems a good compelling event for us to do so. .NET Core is now mature enough to taste without any risks. AWS has a nice helper tool for us: the Porting Assistant for .NET. It runs a compatibility assessment of your .NET Framework code and assists you while your port your code to .NET on Linux. Yes, the Porting Assistant is strongly opinionated (in my opinion): it ports your code to .NET on Linux assuming it is the best place to run next gen .NET applications :)
The one thing which drove me crazy — infrastructure as code in C#
If you read our blog since spring 2021, you probably read the post of our Java buddies, who were happy to write their infrastructure as code in Java. For once, we won’t be jealous! We can define our infrastructure as code by writing C# piece of code using the AWS Cloud Development Kit. For the fist time, we can embed in the same Visual Studio solution the code of our application and the code of our infrastructure and get them versioned all together! No need for us to learn a new language or declarative file format or language based on YAML. Just plain C# and the relevant NuGet packages. Amazing!
Where are we going now?
We finally reached the acceptance step. AWS seemed to give everything we needed for migrating our trusty ol’ .NET Framework applications to AWS. So we started to work on this. !Spoiler alert!: we succeeded 😉I won’t tell you that everything has been a quiet walk in the park, but we made it. And we are more than proud of where we landed. Stay tuned for the next post. I will give a bit of a taste of what was our architecture before we migrated.
In the meantime, if you have comments, questions or feedback, feel free to reply to this post and follow us to be notified of next posts.