Deploy a .NET Core Web API with AWS Lambda and the serverless framework
Tags: netcore, webapi, serverless, lambda
Published: 2018-10-03 20:16:32

---
title: Deploy a .NET Core Web API with AWS Lambda and the serverless framework
published: true
description: tutorial on how to deploy a .net Core Web Api with the serverless framework to AWS lambda
tags: .net core, Web Api, serverless, lambda
---

One of the cool things you can do with lambdas triggered by API Gateway is that you can simply let your code handle the routing. This should work for all serverless stacks and I have already used it for nodejs (check out [this](https://dev.to/adnanrahic/how-to-deploy-a-nodejs-application-to-aws-lambda-using-serverless-2nc7) dev.to article explaining how this works for nodejs).

Of course you could also go and define a lot of separate functions and create a new API Gateway Resource/Method for each. What I really like about running your entire application instead of function by function is the fact that you can firstly run existing apps without a huge change. You can actually simply run the same app in the lambda run time, in a container or by hitting F5...

Secondly you will not have to reinvent the wheel when it comes to standards you already have established in your .net core Web APIs e.g. health check endpoints, logging standards and all the other middleware you really appreciate.

There are already a bunch of tutorials out there that help you set up your .net core Web API with lambda. They do however use Visual Studio templates or .net core cli templates. The problem for me with this templates is that they don't rely on one tool that is a must for me when it comes to serverless - the serverless framework. So in this post I would like to explain how to set up a .net Core Web API on lambda with the serverless framework. This is not very complicated, but I will not go into detail about things covered in other tutorials.

The final result will be something like this:


![api_gw_lambda_aspnetcore](https://thepracticaldev.s3.amazonaws.com/i/1be13u90bvutctdgh7ow.png)


## Prerequisites

You should have a couple of things set up already

* [AWS account](https://aws.amazon.com/console/)

* [Node.js and npm installed](https://nodejs.org/en/download/)

* [.net Core SDK 2.1 installed](https://www.microsoft.com/net/download/dotnet-core/2.1)

* [Serverless Framework installed](https://serverless.com/framework/docs/providers/aws/guide/installation/)

## Creating the API

Create a new folder you want your code to reside in and run:

```bash
dotnet new webapi
```

You can test that it works locally by running the following commands and then opening http://localhost:5000/api/values:

```bash
dotnet restore
dotnet run
```

## Adding the serverless framework to it

Add a file called serverless.yml with the following content:


```yaml
service: exampleservice

provider:
  name: aws
  runtime: dotnetcore2.1
  region: eu-west-1
  
package:
  artifact: bin/release/netcoreapp2.1/deploy-package.zip

functions:
  api:
    handler: exampleservice::exampleservice.LambdaEntryPoint::FunctionHandlerAsync
    events:
     - http:
         path: /{proxy+}
         method: ANY
```

If you already are using the serverless framework you should be familiar with most of the file's content.
We are adding an API Gateway that has a wildcard path => {proxy+} and the handler points to a not yet existing function.
(Change the region to something that makes sense for you).

## Adding additional dependencies

Open your csproj file and change it to something like this (don't forget to run dotnet restore afterwards):

```xml
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0" />
    <PackageReference Include="Amazon.Lambda.Core" Version="1.0.0" />
    <PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.4.0" />
    <PackageReference Include="Amazon.Lambda.AspNetCoreServer" Version="2.1.0" />
  </ItemGroup>

</Project>  
```

! It is important to explicitly point to a specific version of Microsoft.AspNetCore.App. The dotnet new webapi command will not do that by default.

## Add the lambda entry point (handler)

Additionally to your Program.cs file which handles the initialization of your app when you start it locally we need to add an handler for the lambda to hook into. Check the serverless.yml file we created earlier for reference. The handler in the serverless.yml has to be exactly correct ->  {assemblyname}::{namespace}.{class}::FunctionHandlerAsync. Create a file called LambdaEntryPoint.cs:

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using System.IO;

namespace exampleservice
{
    public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
    {
        protected override void Init(IWebHostBuilder builder)
        {
            builder
                .UseStartup<Startup>();
        }
    }
}
```

## Add build/package scripts for your application

Before you can package your lambda you will have to install the dotnet-lambda cli tool:

```bash
dotnet tool install --global Amazon.Lambda.Tools --version 3.0.1
```

for windows systems add a file called build.ps1 :

```powershell
dotnet restore
dotnet lambda package --configuration release --framework netcoreapp2.1 --output-package bin/release/netcoreapp2.1/deploy-package.zip
```

if you run this in debian (e.g. docker image microsoft/dotnet) add build.sh :

```bash
#!/bin/bash

#install zip on debian OS, since microsoft/dotnet container doesn't have zip by default
if [ -f /etc/debian_version ]
then
  apt -qq update
  apt -qq -y install zip
fi

dotnet restore
dotnet lambda package --configuration release --framework netcoreapp2.1 --output-package bin/release/netcoreapp2.1/deploy-package.zip
```

Test the build by running the build script for your environment e.g.

```powershell
.\build.ps1
```

! You will have to run this every time your code changes. Perfectly fine when you run this as part of a CI/CD pipe since you will have to execute that script anyways, but easy to forget if you just play around with it and deploy from your machine. 

## Publish your application!

This should be it! It is time to deploy the app. This assumes that you have followed the serverless install instructions and set up your AWS account (may mean that you have to adjust your serverless.yml file to make that work for you):

```bash
serverless deploy -v
```

This should result in something like this:

![serverless-log](https://thepracticaldev.s3.amazonaws.com/i/xfq6xey3mdxyxntget6v.png)

Copy the highlighted link, replace {proxy+} with api/values and you should get the same result as before! Congrats!

This was a quick write up! If you miss information for some of the steps please add a comment so I can be more clear.

The example repository can be found here: [https://github.com/schwamster/lambda_webapi_serverless](https://github.com/schwamster/lambda_webapi_serverless)