Get Started with AWS SAM and ASP.NET Core
AWS Serverless Application Model, aka SAM, is the bundling AWS services such as Lambda, APIGateway and DynamoDB, etc. Also, AWS provides tools to help developers easily develop serverless applications. AWS SAM supports many programming languages such as nodejs, go, python, etc. However, in this article, I used .NET and its web framework ASP.NET Core to demonstrate.
The reason I chose .NET not only I am familiar with it, but also AWS provides other tools for .NET. These tools make development easier than other programming languages (at least it is how I feel about it).
Why Use Serverless Applications?
There are many benefits of serverless applications such as it is cheaper. Unlike normal web applications which have to run 7/24. Serverless applications only run on-demand. If no one is using your web application, you almost pay nothing. The below figures are based on AWS Pricing Calculator for monthly payment:
Serverless Applications
- 0 requests, the payment is about $0 USD
- 10,000 request, the payment is about $1 USD
- 1,000,000 requests, the payment is about $10 USD
Applications on EC2
- 0 requests, the payment is about $10 USD for 1 t2.micro
- 10,000 requests, the payment is about $10 USD for 1 t2.micro
- 1,000,000 requests, the payment is about $100 USD for 1 t4g.large
It is a huge cutting for a small web application.
NOTE: These figures only compared Lambda and APIGateway to EC2. There might be other fees like for Route53 and S3. Also, the lambda is set to run 2000 MS and use 256 MB memory.
Requirements
These are the requirements
- A AWS Account
You don’t needs to install AWS-CLI in order to run SAM, but you need to put AWS credential either in Environment Variables or ~/.aws/credentials
- A AWS Bucket
Code will be pushed to the bucket
At the time I wrote this article, AWS Lambda doesn’t supports .NET 5 or 6 unless you use Container, but it is out of the topic.
After .NET SDK is installed, run the below commands to install lambda tools and templates.
# install lambda toolsdotnet tool install --global Amazon.Lambda.Tools
# install templatesdotnet new -i "Amazon.Lambda.Templates::*"
# you can run this command to list the lambda templatesdotnet new serverless --list
These are the templates for serverless
Create a Serverless Application
We will use serverless.AspNetCoreWebAPI
template because it won't generate too much or too less files. We can run this command to create MyFirstSAM project.
dotnet new serverless.AspNetCoreWebAPI --name MyFirstSAM
cd MyFirstSAM
These are the generated files. It is almost exact the same as webapi
template. It has three new files and one rename.
- aws-lambda-tools-defaults.json: When use
dotnet lambda
command, if we don't give the specific options value, it will use the value in this files. - LambdaEntryPoint.cs: The entry point for lambda.
- serverless.template: The AWS CloudFormation template to create resources.
- LocalEntryPrint.cs: It is the rename of Program.cs for running the applications locally.
The good things of serverless.AspNetCoreWebAPI
template are
- It creates LambdaEntryPoint.cs to convert Lambda Event to ASP.NET Context implicitly. We can write the app as a regular APS.NET app and there is no additional staff to adopt. (we even can deploy the app outside of AWS SAM, like Azure)
- The app can run locally. If you use other templates like
serverless.EmptyServerless
. The code can not run locally out of box.
Since it is a regular ASP.NET, we can add supporting MVC or Razor pages ourselves. For example, change the services as the below code.
// Startup.cs
public void ConfigureServices(IServiceCollection services) {
services
.AddRazorPages() // support Razor Pages
.AddControllersWithViews(); // support MVC
}
serverless.template
AWS creates the type AWS::Serverless::Function
for SAM. This type will be converted to AWS::Lambda::Function
and AWS::ApiGatewayV2::Api
and other resources at deployment, you can read the official document to know more about AWS::Serverless::Function.
By default, the template includes an APIGateway resources by defining Events
. Type Api
is old version REST API and it generated a useless path /Prod
for stage. Because it is really difficult to create stages in one SAM. So we can change the type to HttpAPi
and do some modify as below.
The serverless.template supports JSON and YAML format. So I usually convert it from JSON to YAML for better to read and write. However, you can still use JSON format.
If you change to HttpApi
, you also need to change the inherit type at LambdaEntryPoint.cs
- LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction+ LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayHttpApiV2ProxyFunction
Deployment
The lambda tools also includes the deploy command dotnet lambda deploy-serverless <stack-name>
. This one command will
- Build the code
- Zip output files
- Push the zip to S3
- Push the template to CloudFormation
- Then CloudFormation will create the stack for us.
Since HttpApi doesn't support stage, we can create different stacks as stages. Like the below commands.
cd "src/MyFirstSAM"
dotnet lambda deploy-serverless MyFirstSAMProd
dotnet lambda deploy-serverless MyFirstSAMStaging
The output will show the url. You can test the app on SAM now.
Set Environment Variables
You can also define how to set environment variables of the app(lambda). There are two ways.
- via AWS SSM
- via
--template-parameter
option when execdeploy-serverless
commands.
For example, we can add parameters on serverless.template to support them.
In JSON, !Ref is { "Ref" : "MyTPENV" }
And pass the value via --template-parameter
or -tp
when deploying
dotnet lambda deploy-serverless $STACK -tp "MyTPEnv=$VALUE;"
Conclusion
In my opinion, AWS SAM is a great cloud hosting solution for .NET developers. It is cheap and easy to use.