AWS Serverless Application Model for ASP.Net Core Apps

Ravi Aakula
Dec 16, 2019 · 8 min read

The AWS Serverless Application Model (SAM) is an open-source framework for building serverless applications. It provides templates with shorthand syntax to express functions, APIs, databases, and event source mappings. These templates are extension of AWS CloudFormation templates. AWS team created some sample SAM templates for major technologies.

In this article we will learn how to deploy asp.net core apps(webapi/web)in AWS using SAM templates. When we publish the app using these templates, it creates a cloudformation stack and creates appropriate AWS resources such as API Gateway , IAM Roles and Lambda.


How to go Serverless

We can use either dotnet cli to create and deploy apps to AWS using SAM or Visual studio. Personally i like dotnet cli method, because it is light weight and i can use any OS or any code editor (VS code / Atom ..)

Method1 :Create and deploy asp.net core app using dotnet cli

  • First install dotnet sdk from here. and check dotnet version
dotnet --version
  • Install AWS lambda and serverless templates using this command
dotnet new -i Amazon.Lambda.Templates
  • Create a new Asp.Net Core webi application using the aws templates. Instead you can also create Asp.Net Core web application with Razer as well.
dotnet new serverless.AspNetCoreWebAPI --name AWSServerlessAPI
  • Navigate to project folder and Restore all dependencies and run the project to verify app is working fine.
cd AWSServerlessAPI\src\AWSServerlessAPI
dotnet restore
dotnet run
  • Open the project in your favorite code editor, i used VSCode.
  • Most of the files and folder structure in this project is same as normal dotnet new project, except few new files.
  • serverless.template file is the SAM template file. It is a cloud formation json file, that got instructons what services needs for this serverless app.
  • As this is webapi project and we would like to test it from client browser, planning to use swagger for API documentation. Add a swagger packages for ASP.Net Core.
dotnet add package Swashbuckle.AspNetCore
  • Register the Swagger generator in Configure services place.
services.AddSwaggerGen(c =>{c.SwaggerDoc("v1", new Info { Title = "AWS Serverless Asp.Net Core Web API", Version = "v1" });});
  • Enable swagger middleware and use swagger UI .
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint(swaggerEnv + "/swagger/v1/swagger.json", "AWS Serverless Asp.Net Core Web API");
c.RoutePrefix = "swagger";
});
  • Run application in local environment to check swagger documentation at the route “ http://localhost:5000/swagger
  • Install lambda tools to publish this application to AWS
dotnet tool install -g Amazon.Lambda.Tools
  • Create a S3 bucket in AWS console to upload source code packages and build outputs.
  • Create an IAM user and download creadentials to local machine and configure AWS profile in your local machine.
  • Now publish this application to AWS as serverless model.
dotnet lambda deploy-serverless --stackname samplewebapi
--profile personal --region us-west-1
--s3-bucket samplewebapibuilds
  • Copy URL from output and browse swagger route. You should be able to see the swagger UI.

Method2: Create and deploy asp.net core app using Visual Studio 2017/2019

  • Create new project by selecting AWS Serverless Application in the AWS Lambda templates of Visual studio.
  • Next select appropriate template for your need. I used Web API template.
  • Add Swagger nuget package to the project for API documentation.
  • Add swagger entries in Startup.cs file same as we did in dotnet cli process.
  • Run application in local machine and make sure you are able to see swagger UI.
  • Publish the application to AWS using the Visual studio helper screens.
  • Select Region , AWS profile and S3 bucket to deploy app to AWS .
  • Follow the prompts in the next screens and you should be able to see the below screen with URL once the deployment is completed.
  • Browse the URL along with Swagger route and test any of the endpoint.
  • One of the Endpoint is for S3 Proxy controller. To test this URL, first upload any files to S3 bucket and test Get method in Swagger URL.

You can find sample application code in github.

What’s Happening Here?

Awesome, we successfully deployed sample app as serverless to AWS. But we haven’t learned what is happening under the hood. What is written in SAM template and how template is transforming to AWS resources?

  • First thing there is no Program.cs file in this project structure, instead there two files.
  • LocalEntryPoint.cs → This contains the main method and it is the starting point when we run app in local machine.
  • LambdaEntryPoint.cs → This contains almost same code as local entry point without Main. And this is the starting method when you deploy to AWS.
  • serverless.template → This is the main file in our journey towards serverless in AWS. If you open this file you could see all instructions what resources it use and all other configuration.
"AspNetCoreFunction" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"Handler":"AWSServerless::LambdaEntryPoint::FunctionHandlerAsync",
"Runtime": "dotnetcore2.1",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaFullAccess" ],
"Environment" : {},
"Events": {
"ProxyResource": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "ANY"
}
},
"RootResource": {
"Type": "Api",
"Properties": {
"Path": "/",
"Method": "ANY"
}
}
}
}
  • If you look at the AspNetCoreFunction resource, it is of type AWS::Serverless::Function. You can find all possible properties for this resource in this github page.
  • By default template comes with main properties such as Run-time(technology), Memory, Timeout,Policies, Role Environment Variables and Events. You can add or modify any properties here.
  • Eventually this function creates a Lambda function, IAM execution role, and event source mappings which trigger the function.
  • Another important property in this function declaration is “Events”, which defines the events that trigger this function. It could be S3, Dynamodb or Api . In our case it is Api.
  • This Api event actually creates AWS API Gateway resources , so that we can trigger the function using http methods.
  • Every Request gets through API Gateway then forwarded to Lambda and dotnet application will be executed in lambda to serve the request.
  • Within lambda all asp.net core middleware (routing/ security and custom) will be executed then request will be processed by respective action of controller.
  • Along with function and API declarations, we could also define any AWS resources in this SAM could formation template such as S3 buckets , Dynamo DB , etc.
  • In our sample temple there is a S3 bucket declaration with its parameters, this S3 bucket is used in S3Proxy Controller methods.
  • We can use this template in any CI/CD tool to automate build and publish application.

API Gateway

  • The final URL we get from the template output is API Gateway URL. It is fully managed AWS Service to create, publish, maintain, monitor, and secure APIs at any scale.
  • You can check sample application API Gateway by logging into AWS console.
  • In the search box of AWS Console, type “API Gateway ” and Navigate to Sample webapi application.
  • Path “/{proxy+}” indicates that all routes should be send to lambda.
  • Method “Any” indicates all http methods should be forwarded to Lambda.
  • Stages tab shows all environments this api is deployed, by default Prod .
  • You can examine and all other tabs such as Authorization to implement security, Dashboard to Monitor requests and Settings.

Lambda

  • AWS Lambda lets you run code without provisioning or managing servers.
  • This is where dotnet code will execute and all function properties in the SAM templates will reflect in this Lambda console.
  • You can Navigate to lambda function just by clicking on the far right box in the api gatway page Or just search for lambda service in AWS Console.
  • We can browse through all tabs and sections such as Monitoring to monitor all logs, Function Code to change runtime and sourcecode, Environment variables, Roles and Memory.
  • Whatever you feel to change in the console, you can directly change and save directly or you can change them in SAM template and re-deploy.
  • Every serverless framework comes with certain limitations. AWS Lambda also got limitations such as max 3 GB , concurrency , response time and 15 mins timeout.
  • But most annoying limitation is cold start for dotnet framework.
  • Cold start: AWS uses its internally technology to run these lambda on EC2 servers. Most probably , they launch containers on EC2 host machines whenever someone request lambda to execute. And they kill these containers, when there is no active requests coming in certain time frame, say 5 mins. If a new request comes, after this 5 mins, it takes at least 10–20 seconds to respond.

Optimize AWS Lambda Function Cold Starts

There are various techniques and articles explain how to keep your serverless lambda warm , so that app/api is always responsive and high available. I loved Jeremy Daly’s idea to ping function every 5 mins and make chain function calls as many concurrency functions as your app demands.

courtesy: https://www.jeremydaly.com/lambda-warmer-optimize-aws-lambda-function-cold-starts/
  • To implement this idea, you need to create a AWS Cloudwatch Alarm, that pings lambda every five minutes and passes number of concurrency functions should be always available .
  • Write logic in the function handler (middle ware in .net) to launch the same function asynchronously, required number of times.
  • This article will help you to implement these steps dotnet core apps.

Conclusion

This is just an introduction to SAM with .Net Core. There are much more to learn and understand how to deploy dotnet apps securely in AWS plotform. As world of devops going towards serverless, it is the best time to adopt serverless. However i wont suggest serverless for every application, specially large scale complex apps due to limitations such as cold start, memory, concurrences, and timeouts. I am strongly hopeful that AWS team will find solutions for these hurdles and we can deploy any application in near future.

Happy Serverless Development.

Ravi Aakula

Written by

Full stack .Net Developer. Passionate about cloud technologies.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade