Today I’ll show you how to Deploy your ASP.NET Core Web API to AWS Lambda.

First be aware of the following prerequisites:

Now let’s start:

1. Create a folder for your new project#


Open a command promt an run

1mkdir aws.lambda

2. Create the project#


1cd aws.lambda
2dotnet new webapi

3. Replace the contents of aws.lambda.csproj#


You need to target netcoreapp1.0 in order for your Web API to work on AWS Lambda. You’ll also need to reference some nuget packages from aws so replace the contents of the aws.lamda.csproj file with the following lines:

 1<Project Sdk="Microsoft.NET.Sdk.Web">
 2
 3  <PropertyGroup>
 4    <TargetFramework>netcoreapp1.0</TargetFramework>
 5    <UserSecretsId>aspnet-aws.lambda-FD62E418-7AF9-462F-B391-DD806F38F03A</UserSecretsId>
 6    <PreserveCompilationContext>false</PreserveCompilationContext>
 7  </PropertyGroup>
 8
 9  <ItemGroup>
10    <Folder Include="wwwroot\" />
11  </ItemGroup>
12
13<ItemGroup>
14    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.0.0" />
15    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.0.1" />
16    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.0.1" />
17    <PackageReference Include="Microsoft.AspNetCore.Routing" Version="1.0.1" />
18    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.0.0" />
19    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.0.0" />
20    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.0" />
21    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.0.0" />
22    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.0.0" />
23
24    <PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.3.0.3" />
25
26    <PackageReference Include="Amazon.Lambda.Core" Version="1.0.0" />
27    <PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.1.0" />
28    <PackageReference Include="Amazon.Lambda.AspNetCoreServer" Version="0.10.1-preview1" />
29    <PackageReference Include="Amazon.Lambda.Logging.AspNetCore" Version="1.1.0" />
30  </ItemGroup>
31  
32  <ItemGroup>
33    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0" />
34    <DotNetCliToolReference Include="Amazon.Lambda.Tools" Version="1.6.0" />
35  </ItemGroup>
36
37</Project>

4. Restore the packages#


You just changed the project files so restore the packages:

1dotnet restore

5. Rename Program.cs and replace it’s contents#


Rename Program.cs to LocalEntrypoint.cs and replace the contents of the file with the following lines:

 1using System;
 2using System.Collections.Generic;
 3using System.IO;
 4using System.Linq;
 5using System.Threading.Tasks;
 6using Microsoft.AspNetCore.Hosting;
 7using Microsoft.AspNetCore.Builder;
 8
 9namespace aws.lambda
10{
11    /// <summary>
12    /// The Main function can be used to run the ASP.NET Core application locally using the Kestrel webserver.
13    /// </summary>
14    public class LocalEntryPoint
15    {
16        public static void Main(string[] args)
17        {
18            var host = new WebHostBuilder()
19                .UseKestrel()
20                .UseContentRoot(Directory.GetCurrentDirectory())
21                .UseIISIntegration()
22                .UseStartup<Startup>()
23                .Build();
24
25            host.Run();
26        }
27    }
28}

Note: This will be the entry point while you are developing.

6. Create a file LambdaFunction.cs#


Create a LambdaFunction.cs file and copy the following code

 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Net;
 5using System.Threading.Tasks;
 6using Microsoft.AspNetCore.Hosting;
 7using System.IO;
 8
 9namespace aws.lambda
10{
11    public class LambdaFunction : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
12    {
13        protected override void Init(IWebHostBuilder builder)
14        {
15            builder
16                .UseContentRoot(Directory.GetCurrentDirectory())
17                .UseStartup<Startup>()
18                .UseApiGateway();
19        }
20    }
21}

Note: This class will be the entry point once you deploy the Web API to AWS Lambda.

7. Replace the contents of Startup.cs#


Replace the contents of the Startup.cs file with the following code

 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Threading.Tasks;
 5using Microsoft.AspNetCore.Builder;
 6using Microsoft.AspNetCore.Hosting;
 7using Microsoft.Extensions.Configuration;
 8using Microsoft.Extensions.DependencyInjection;
 9using Microsoft.Extensions.Logging;
10
11namespace aws.lambda
12{
13    public class Startup
14    {
15        public Startup(IHostingEnvironment env)
16        {
17            var builder = new ConfigurationBuilder()
18                .SetBasePath(env.ContentRootPath)
19                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
20                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
21
22            builder.AddEnvironmentVariables();
23            Configuration = builder.Build();
24        }
25
26        public static IConfigurationRoot Configuration { get; private set; }
27
28        // This method gets called by the runtime. Use this method to add services to the container
29        public void ConfigureServices(IServiceCollection services)
30        {
31            services.AddMvc();
32
33            // Pull in any SDK configuration from Configuration object
34            services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
35        }
36
37        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
38        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
39        {
40            loggerFactory.AddLambdaLogger(Configuration.GetLambdaLoggerOptions());
41            app.UseMvc();
42        }
43    }
44}

Note: Check lines 34 & 40 for special AWS configurations.

8. Create aws-lambda-tools-defaults.json#

Create a aws-lambda-tools-defaults.json file with the following code

 1{
 2    "Information": [
 3        "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
 4        "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
 5        "dotnet lambda help",
 6        "All the command line options for the Lambda command can be specified in this file."
 7    ],
 8    "profile": "default",
 9    "region": "eu-west-1",
10    "configuration": "Release",
11    "framework": "netcoreapp1.0",
12    "function-runtime": "dotnetcore1.0",
13    "template": "serverless.template"
14}

Note: Be aware of teh region specified in this file.

9. Create serverless.template#


Create a file: serverless.template with the following contents

 1{
 2  "AWSTemplateFormatVersion" : "2010-09-09",
 3  "Transform" : "AWS::Serverless-2016-10-31",
 4  "Description" : "Starting template for an AWS Serverless Application.",
 5  "Parameters" : {
 6  },
 7  "Resources" : {
 8    "DefaultFunction" : {
 9      "Type" : "AWS::Serverless::Function",
10      "Properties": {
11        "Handler": "aws.lambda::aws.lambda.LambdaFunction::FunctionHandlerAsync",
12        "Runtime": "dotnetcore1.0",
13        "CodeUri": "",
14        "Description": "Default function",
15        "MemorySize": 256,
16        "Timeout": 30,
17        "Role": null,
18        "Policies": [ "AWSLambdaFullAccess" ],
19        "Events": {
20          "PutResource": {
21            "Type": "Api",
22            "Properties": {
23              "Path": "/{proxy+}",
24              "Method": "ANY"
25            }
26          }
27        }
28      }
29    }
30  },
31  "Outputs" : {
32  }
33}

Note: be aware of the Handler property in this file. It should be in the form: [Assembly Name]::[Namespace].LambdaFunction::FunctionHandlerAsync

10. Build the application#


Build the application:

1dotnet build

11. Deploy to AWS Lambda#


Run the following commands (you’ll need your access key for AWS):

1aws configure
2aws s3api create-bucket --bucket mylambdabucket --region eu-west-1 --create-bucket-configuration LocationConstraint=eu-west-1 
3dotnet lambda deploy-serverless

12. Get your api id#


Run the following commands and copy the api id for your stack:

1aws apigateway get-rest-apis

13. Browse to your web api#


You are good to go so browse to: https://[api id from step 11].execute-api.eu-west-1.amazonaws.com/Prod/api/values

The browser should show: [“value1″,“value2”]

You can get the code here: https://github.com/cmendible/dotnetcore.samples/tree/main/aws.lambda

Hope it helps!