A tech lead friend of mine is asking to explore AWS capabilities for running .NET apps. Their organization has a mix of Azure and AWS usage. But his group, for reasons he can’t explain to me fully, has to go to AWS instead of Azure.
Are you abandoning .NET and have your team use another programming language/platform to go to AWS, I ask? He says, no.
I suggest to him to stick with Azure.
But he insists, that he’s been tasked out by leadership to move their apps to the Amazon cloud not the Microsoft cloud.
I agree to help him because part of me is curious about why, to my perspective, there are more startups using AWS more than Azure. My friend says it’s about cost, AWS is supposed to be cheaper than Azure. But I’m not convinced that AWS is cheaper than Azure.
I want to see AWS in action and help friend through the process.
I decided my “Hello World” for this will be:
- .NET Core Web API – the “values controller” that gets stubbed out will suffice
- Run in a container – using Docker and/or Kubernetes
- The Web API running in an AWS web address
This is nothing fancy, but I feel just enough to test out key components of the AWS deployment and standing-up process.
When I set out to try deploying a test container app to run AWS, I failed with my first combination, which is the following:
- ASP.NET Core Web App 2.2 with “Enable Docker Support” (tried both Linux and Windows)
- AWS Launch Type: EC2
- EC2 windows + Networking Cluster
The issues I ran into ranged from not being able to download the required images (the correct .NET Core) into the containers, to the EC2 instance not provisioning such that the AWS task wouldn’t deploy at all!
First of all, I feel like if I’m going to the cloud, I might as well go totally server-less. Why would I mess-around with creating servers when it’s possible to run my apps and services and bypass all that, right?
The mistake in my exploratory exercise was shooting for an EC2 launch type when I should have targeted Fargate right off the bat. And if you’re like me, who’s more familiar with Azure, more of a developer than a network engineer, and just getting started with AWS, the more you can skip the details of server stuff, the better.
So, on to the exercise that actually worked..
Create ECS Cluster
The first step is creating an ECS cluster at AWS. This process is straightforward:
- Specify Cluster name
- Choose Provisioning Model
- Choose EC2 instance type
- Specify Networking
- Finally, specify Container instance IAM role = scsInstanceRole
Create an IAM User Account
If you haven’t already, create an IAM User Account. You will need it to login to AWS from Visual Studio.
Install additional software
You will need to install the following to your development workstation:
Now that you you should have all prerequisites installed, on to the good stuff…
Setup your AWS Profile in Visual Studio
In Visual Studio, login to AWS using your IAM Account and Account Number:
If you’re successful in setting up the account profile, you should be able to see your added Profile in the AWS Explorer, and all associated assets for that account in a particular Region.
Create the Test Application
Create a new web app in Visual Studio.
I select ASP.NET Core 2.2, API type project. Then in Advanced (to the right), I uncheck Configure for HTTPS (no need for this to test this out), and checked Enable Docker Support. Ensure you select Linux and not Windows. Fargate runs in Linux instances only.
When you click the Create button, it will setup the project obviously. Once the new project/solution, Container Tools will output some stuff related to running your app in Docker
Test the app locally first, make sure it runs in a Container
Run and debug the app. Normally, you would see Run button on the toolbar. But for this project, I selected Enable Docker Support on project creation. So, what I will see and need to push is the Docker-run button instead.
All API projects start out with the ValuesController. If I can run this successfully, this means:
- No compile errors–the app should run
- Dockerfile contents are mostly likely right (this is important)
Deployment to AWS
Local testing worked out fine. Time to deploy to AWS.
First, right-click the project and click Publish Container to AWS on the popup menu.
On the Publish Container AWS dialog:
- Select Account profile to use
- Select Region – Important! You must select the region where you created the ECS cluster
- Configuration, Release is ok
- Specify Docker Repository
- On Deployment Target, select Service on an ECS Cluster
- Hit Next
Next, under Launch Configuration:
- Pick your ECS Cluster
- For Launch Type, select FARGATE
- Set your CPU Max and Memory Max
- Select VPC Subnets
- Select Security Groups
- Check Assign Public IP Groups
Next, under Service Configuration:
- Create new service
- Specify service name
- Leave number of Tasks to 1
- The other fields, leave them to the default values
- Click Next
Next, Application Load Balancer Configuration:
- Don’t skip this as we need a web address for our app. I failed miserably trying to find out what my endpoint URL is in my first attempts the other day. It won’t generate URL unless you configure load balancer
- Create new Load Balancer
- Spec out Listener Port 80
- Create new Target Group
- Click Next
Finally, Task Definition:
- Create new Task Definition
- Create new Container
- For Task Role, select existing role: ecsTaskExecutionRole
- For Task Execution Role, select ecsTaskExecutionRole
- Leave Port Mapping to port 80
- Environment Variables – you can change that to “Test” if you want
Assuming you get no errors on Publishing to AWS, you will see the app’s URL by:
- Double-click the cluster in AWS Explorer
- Click the Services tab
- Find your service
- Look for the URL field – that’s the endpoint URL
- copy that URL and test it out in a browser. Or, you can just click that URL
Troubleshooting after Publishing
You get a 404 like this:
Go to ECS Management Console
- Go to the ECS Cluster
- Find the Service – open it
- You may find that Running count is 0
Patience is key–give it some time, especially if you picked the cheapo micro instances for your cluster. After awhile, you should see the Task as Running:
Test it again. The 404 may turn into 503.
Try again. Ensure you hit /api/values/–that’s where the test API is.
And it works: