Deploy your ASP.NET Core Web API to AWS Lambda
Categories:
4 minute read
Today I’ll show you how to Deploy your ASP.NET Core Web API to AWS Lambda.
First be aware of the following prerequisites:
- You’ll need an AWS account: https://aws.amazon.com/
- You’ll need AWS CLI installed: http://docs.aws.amazon.com/cli/latest/userguide/installing.html
- You’ll need your AWS security credentials
- Some basic knowledge on AWS Stacks, API Gateway, Lambda and Buckets
Now let’s start:
Create a folder for your new project
Open a command promt an run
mkdir aws.lambda
Create the project
cd aws.lambda
dotnet new webapi
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:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<UserSecretsId>aspnet-aws.lambda-FD62E418-7AF9-462F-B391-DD806F38F03A</UserSecretsId>
<PreserveCompilationContext>false</PreserveCompilationContext>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="1.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.0.0" />
<PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.3.0.3" />
<PackageReference Include="Amazon.Lambda.Core" Version="1.0.0" />
<PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.1.0" />
<PackageReference Include="Amazon.Lambda.AspNetCoreServer" Version="0.10.1-preview1" />
<PackageReference Include="Amazon.Lambda.Logging.AspNetCore" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0" />
<DotNetCliToolReference Include="Amazon.Lambda.Tools" Version="1.6.0" />
</ItemGroup>
</Project>
Restore the packages
You just changed the project files so restore the packages:
dotnet restore
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:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
namespace aws.lambda
{
/// <summary>
/// The Main function can be used to run the ASP.NET Core application locally using the Kestrel webserver.
/// </summary>
public class LocalEntryPoint
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}
Note: This will be the entry point while you are developing.
Create a file LambdaFunction.cs
Create a LambdaFunction.cs file and copy the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using System.IO;
namespace aws.lambda
{
public class LambdaFunction : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
{
protected override void Init(IWebHostBuilder builder)
{
builder
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseApiGateway();
}
}
}
Note: This class will be the entry point once you deploy the Web API to AWS Lambda.
Replace the contents of Startup.cs
Replace the contents of the Startup.cs file with the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace aws.lambda
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public static IConfigurationRoot Configuration { get; private set; }
// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Pull in any SDK configuration from Configuration object
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddLambdaLogger(Configuration.GetLambdaLoggerOptions());
app.UseMvc();
}
}
}
Note: Check lines 34 & 40 for special AWS configurations.
Create aws-lambda-tools-defaults.json
Create a aws-lambda-tools-defaults.json file with the following code
{
"Information": [
"This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
"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.",
"dotnet lambda help",
"All the command line options for the Lambda command can be specified in this file."
],
"profile": "default",
"region": "eu-west-1",
"configuration": "Release",
"framework": "netcoreapp1.0",
"function-runtime": "dotnetcore1.0",
"template": "serverless.template"
}
Note: Be aware of teh region specified in this file.
Create serverless.template
Create a file: serverless.template with the following contents
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Transform" : "AWS::Serverless-2016-10-31",
"Description" : "Starting template for an AWS Serverless Application.",
"Parameters" : {
},
"Resources" : {
"DefaultFunction" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"Handler": "aws.lambda::aws.lambda.LambdaFunction::FunctionHandlerAsync",
"Runtime": "dotnetcore1.0",
"CodeUri": "",
"Description": "Default function",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaFullAccess" ],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "ANY"
}
}
}
}
}
},
"Outputs" : {
}
}
Note: be aware of the Handler property in this file. It should be in the form:
[Assembly Name]::[Namespace].LambdaFunction::FunctionHandlerAsync
Build the application
Build the application:
dotnet build
11. Deploy to AWS Lambda
Run the following commands (you’ll need your access key for AWS):
aws configure
aws s3api create-bucket --bucket mylambdabucket --region eu-west-1 --create-bucket-configuration LocationConstraint=eu-west-1
dotnet lambda deploy-serverless
Get your api id
Run the following commands and copy the api id for your stack:
aws apigateway get-rest-apis
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!