Build a Serverless Dotnet Core Web API with AWS Lambda and API Gateway
Tags: aws, dotnet
Published: 2020-12-01 12:04:30

**Introduction**
In this article, we are going to deploy the ASP.NET Core Web API in AWS Lambda and AWS API Gateway.

**AWS Lambda**
AWS Lambda lets you run code without managing servers. you pay only for the compute time you consume.

With Lambda, you can run code for virtually any type of application or backend service - all with zero administration. Just upload your code and Lambda takes care of everything required to run and scale your code with high availability. 
You can set up your code to automatically trigger from other AWS services or call it directly from any web or mobile app.

**API Gateway**
Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. APIs act as the "front door" for applications to access data, business logic, or functionality from your backend services. 

Using API Gateway, you can create RESTful APIs and WebSocket APIs that enable real-time two-way communication applications. API Gateway supports containerized and serverless workloads, as well as web applications.

**AWS Architecture:**
Below is the AWS services we are going to use for the deployment of Web API.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ztorwwev6qm76koiy4b9.png)

**Pre-requisites**
To complete this learning path, you will need:
✓ An AWS Account
✓ An IAM user with access key credentials
✓ Visual Studio Code or Visual Studio 2019+ for Windows

If you don't have an account visit https://aws.amazon.com and click Sign Up.
You must have a set of valid AWS credentials, consisting of an access key and a secret key, which are used to sign programmatic requests to AWS. You can obtain a set of account credentials when you create your account, although we recommend you do not use these credentials and instead create an IAM user and use those credentials.

**Installing the AWS CLI:**
Install the `AWS CLI` for Windows, Mac, or Linux: https://aws.amazon.com/cli/

Once installed, you can configure the CLI by running the `aws configure` command in a terminal or command-line window.

When prompted, enter your `AWS Access Key ID` and press Enter.

Enter your `AWS Secret Access Key` when prompted and then press Enter.

For the `default region name` you should enter your chosen region code (e.g. eu-west-1)

Finally, for the `default output` format you can just press Enter.

**Installing the AWS Lambda Tools:**

`dotnet tool install -g Amazon.Lambda.Tools`
`dotnet tool install --global Amazon.Lambda.TestTool-3.1`

Read the below articles for creating the postgres RDS instance and managing the connection string using Systems Manager
[Creating the AWS RDS Instance for PostgreSQL](https://dev.to/sunilkumarmedium/postgresql-database-instance-creation-and-configuration-in-aws-rds-4p60)
[AWS Systems Manager Parameter Store and retrieving using C#](https://dev.to/sunilkumarmedium/aws-systems-manager-parameter-store-for-managing-configuration-and-retrieve-at-runtime-using-c-58of)
{% github https://github.com/sunilkumarmedium/CleanArchitectureApp %}
**Creating the AWS Lambda Web Api Project using command line**

`dotnet new --help`  will display the installed AWS project templates
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/skp2w30nuqsgjzcegoxc.png)

To create a serverless project run the below command
`dotnet new serverless.AspNetCoreWebAPI -n CleanArchitectureApp`

**Adding Lambda Support to existing ASP.NET Core Web API Project**

Below are the steps to add AWS Lambda support for existing projects

**Step 1:** In csproj file add the below tag
`<AWSProjectType>Lambda</AWSProjectType>`

Include the below AWS package references to the projects
```
<PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.3.101" />
<PackageReference Include="Amazon.Lambda.AspNetCoreServer" Version="5.2.0" />
```

**Step 2:** Create a c# file with name "LambdaEntryPoint.cs" and inherit the appropriate class based on your requirement. Below are some details 
- API Gateway REST API                         -> Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
- API Gateway HTTP API payload version 1.0     -> Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
- API Gateway HTTP API payload version 2.0     -> Amazon.Lambda.AspNetCoreServer.APIGatewayHttpApiV2ProxyFunction
- Application Load Balancer                    -> Amazon.Lambda.AspNetCoreServer.ApplicationLoadBalancerFunction

Call the Startup.cs in the override method.
```
 protected override void Init(IWebHostBuilder builder)
        {
            builder
                .UseStartup<Startup>();
        }
```
		
**Step 3:** Create a json file "aws-lambda-tools-defaults.json" to read the default lambda configuration.

**Step 4:** create a serverless declarative template  "serverless.template" and this will be used by the AWS Cloud Formation for creating the required resources during the Lambda deployment.

Specify the dotnet core runtime, lambda handler, memory and policies
```
 "Resources": {
    "AspNetCoreFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Handler": "CleanArchitectureApp.WebApi::CleanArchitectureApp.WebApi.LambdaEntryPoint::FunctionHandlerAsync",
        "Runtime": "dotnetcore3.1",
        "CodeUri": "",
        "MemorySize": 256,
        "Timeout": 30,
        "Role": null,
        "Policies": [
          "AWSLambdaFullAccess", "AmazonSSMFullAccess","AWSLambdaVPCAccessExecutionRole"
        ],
```


Below is the full implementation
{% gist https://gist.github.com/sunilkumarmedium/8fb60a1c5de81fc98e8aa11387170b55 %}


**Deploying the WebApi to AWS Lambda**

Open the command line on Windows and change the repository working directory to:
`cd D:\GitHub_Projects\CleanArchitectureApp\CleanArchitectureApp.WebApi`

Enter the below command and hit enter
`dotnet lambda deploy-serverless --template serverless.template`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t6yxw9x123ltq15z9pla.png)

**Cloud Formation Stack Creation In Progress**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wwp7hovgrcedmdqam591.png)

**Lambda Function Deployed**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lt2nrek9yglg7w1nbdox.png)

**Lambda function permissions for connecting to RDS instance**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gav9kimlhkezgncicnz9.png)

**API Gateway Resource Creation**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nn17nhax6w9pef3fdq62.png)


Hit the API gateway endpoint 
`https://xxxx.execute-api.ap-south-1.amazonaws.com/Prod/swagger`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zh9xnrqeahoq6nsoan9z.png)

**Cloud Watch Logs:**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jcagmdsvkm5dienw7h64.png)

**Summary**
You can implement the Warmer function for faster ColdStart(startup) of Lambda Function.

Happy Coding!