Using the Serverless Framework to Deploy a .NET Core 3.1 Web API Lambda Function
By: Charles Salmon
Tags: Deployment, Serverless, Dotnet, Dotnet Core, C Sharp Programming

Prerequisites

Foreword

I have always been a fan of serverless architecture, because it allows developers to deliver business value quickly, without incurring significant upfront cost. The Serverless Framework takes the thinking out of deploying serverless services across many different cloud providers.

Typically when deploying a serverless function, many other cloud resources need to be created to support this. If you’re working in AWS, you’d typically need to consider the creation of:

An S3 bucket to retain artifacts

An API Gateway endpoint as an entry point for the serverless function

CloudWatch log groups to retain logging

An IAM role to provide the lambda function with the privileges it requires to write logs

The Serverless Framework abstracts these details away from you, so that you can simply think in terms of the event that you would like your function to respond to, write the business functionality that you wish to deliver, and configure more specific requirements as they arise.

I have noted that the Serverless Framework provides much better support for Node.js and Python services than for other runtimes. Availability of documentation explaining other use cases is fairly limited, so without further ado, I will explain how you can go about deploying a .NET Core 3.1 Web API lambda function using the framework. I am yet to explore the details that will be involved to deploy a .NET 5 lambda function, but I am hoping that this will be a similarly painless exercise.

Generate the .NET Core 3.1 Web API Scaffold

The following command will scaffold a new .NET Core 3.1 Web API, into a new directory:

dotnet new webapi \

--name CharlesDotFish.DotnetCoreHttpLambda \

--output CharlesDotFish.DotnetCoreHttpLambda

Install the Amazon.Lambda.AspNetCoreServer NuGet Package

I would encourage you to read this documentation, which explains the intended usage of the package. The Serverless Framework will deploy a AWS::Serverless::Function resource, so we will be taking interest in the APIGatewayHttpApiV2ProxyFunction base class.

The following command will install the package into the project you’ve just created, when executed from the context of the directory containing your project file:

dotnet add package Amazon.Lambda.AspNetCoreServer

Create a Lambda Entry Point

Create a new class, perhaps with the name LambdaEntryPoint inside the project. This class will need to extend the APIGatewayHttpApiV2ProxyFunction base class, and override the method with the void Init(IWebHostBuilder builder) signature, like so:

using Amazon.Lambda.AspNetCoreServer;

using Microsoft.AspNetCore.Hosting;



namespace CharlesDotFish.DotnetCoreHttpLambda

{

public class LambdaEntryPoint : APIGatewayHttpApiV2ProxyFunction

{

protected override void Init(IWebHostBuilder builder)

{

builder.UseStartup<Startup>();

}

}

}

Create the Serverless YAML Configuration File

This resource provides a detailed reference on all of the available configuration options that the Serverless Framework exposes, when setting out with the goal of deploying a service into AWS.

Create a file with the name serverless.yml . Assuming you’ve used the same names as myself, the following configuration is what will minimally be required to deploy the .NET Core Web API as a lambda function:

service: weather-forecast



provider:

name: aws

runtime: dotnetcore3.1



package:

artifact: bin/Release/netcoreapp3.1/CharlesDotFish.DotnetCoreHttpLambda.zip



functions:

weatherForecast:

handler: CharlesDotFish.DotnetCoreHttpLambda::CharlesDotFish.DotnetCoreHttpLambda.LambdaEntryPoint::FunctionHandlerAsync

events:

- httpApi:

method: GET

path: /WeatherForecast

Build the Package

Execute the following command from the context of the directory containing your project file:

dotnet lambda package

This will produce a Release configuration artifact, which will be placed at the relative directory indicated in the package.artifact property of the YAML configuration we defined above.

Deploy the Stack

Execute the following command from the context of the directory containing your project file:

sls deploy

This will create a CloudFormation stack, containing all resources required to support the lambda function, and will deploy the lambda itself. Once this has finished, a URL will be output in your terminal, indicating where the API Gateway endpoint can be invoked from.

Example Response

Destroy the Stack

Once you’ve finished admiring your work, you can execute the following command from the context of the directory containing your project file to tear the stack down again:

sls remove

If you encounter any errors, it wasn’t my fault!