AWS Developer Tools Blog

Announcing Amazon.Lambda.RuntimeSupport

We’ve received many requests to include more versions of .NET Core in AWS Lambda. Customers want the flexibility to write Lambda functions in LTS, current, and preview versions of .NET Core. Until now, you could use only LTS versions. The new Amazon.Lambda.RuntimeSupport library changes that.

Today we’ve released the Amazon.Lambda.RuntimeSupport library that enables you to easily create Lambda functions using .NET standard 2.0-compatible runtimes. This means you can now author Lambda functions using .NET Core 2.2 and .NET Core 3.0 preview. Amazon.Lambda.RuntimeSupport is available as source code on GitHub, or as a NuGet package.

The latest version of .NET Core built into Lambda is 2.1. For that version, we recommend using the built-in .NET Core runtime when creating your AWS Lambda function, instead of the new library. Due to the short-term nature of current and preview versions, we plan to build only LTS versions of .NET Core directly into AWS Lambda. If you’re looking to use new features from .NET Core 2.2 or 3.0 preview, Amazon.Lambda.RuntimeSupport gives you a path forward.

The library makes use of a Lambda feature called custom runtimes. Custom runtimes give developers a way to implement Lambda functions in languages or runtimes that wouldn’t otherwise be supported. We encourage you to read more about Lambda custom runtimes here.

.NET Core receives periodic security updates and bug fixes. Built-in runtimes automatically receive these updates because they’re managed by Lambda. The customer manages updates to custom runtimes, but has flexibility to bring any version of a runtime to the platform. Keep this in mind when choosing between a built-in runtime and a custom runtime.

Authoring a custom .NET Core 2.2 function

To get started creating a Lambda function based on .NET Core 2.2, take a look at the following walkthrough. It includes the necessary steps, with a cursory explanation of how the function works. The lambda.CustomRuntimeFunction template is available only through the .NET Core CLI. An update to the AWS Toolkit for Visual Studio with the new template will follow soon.

For more details about Amazon.Lambda.RuntimeSupport, visit the GitHub page.

Prerequisites

Creating, deploying, and invoking the function

To generate a project with code for the new function, run the following.


dotnet new lambda.CustomRuntimeFunction --name CustomRuntimeFunction

This generates source and test projects. The important files in the source project are listed below.

  • CustomRuntimeFunction.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
	<OutputType>Exe</OutputType>
	<TargetFramework>netcoreapp2.2</TargetFramework>
	<LangVersion>latest</LangVersion>
	<AWSProjectType>Lambda</AWSProjectType>
  </PropertyGroup>
  <ItemGroup>
	<!--AWS Lambda executes the bootstrap shell script as the startup process for your function.-->
	<Content Include="bootstrap">
	  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
	</Content>
  </ItemGroup>
  <ItemGroup>
	<PackageReference Include="Amazon.Lambda.RuntimeSupport" Version ="1.0.0" />
	<PackageReference Include="Amazon.Lambda.Core" Version="1.1.0" />
	<PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.4.0" />
  </ItemGroup>
</Project>
  • Function.cs – Contains a class with a Main entry point that starts the function, and a single function handler method.

using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport;
using Amazon.Lambda.Serialization.Json;
using System;
using System.Threading.Tasks;

namespace CustomRuntimeFunction
{
	public class Function
	{
		/// <summary>
		/// The main entry point for the custom runtime.
		/// </summary>
		/// <param name="args"></param>
		private static async Task Main(string[] args)
		{
			// Wrap the FunctionHandler method in a form that LambdaBootstrap can work with.
			using(var handlerWrapper = HandlerWrapper.GetHandlerWrapper((Func<string, ILambdaContext, string>)FunctionHandler, new JsonSerializer()))
			{
				// Instantiate a LambdaBootstrap and run it.
				// It will wait for invocations from AWS Lambda and call
				// the handler function for each one.
				using(var bootstrap = new LambdaBootstrap(handlerWrapper))
				{
					await bootstrap.RunAsync();
				}
			}
		}

		/// <summary>
		/// A simple function that takes a string and does a ToUpper
		/// </summary>
		/// <param name="input"></param>
		/// <param name="context"></param>
		/// <returns></returns>
		public static string FunctionHandler(string input, ILambdaContext context)
		{
			return input?.ToUpper();
		}
	}
}
  • aws-lambda-tools-defaults.json – Default argument settings for use with command line deployment tools for AWS.

    • function-runtime is set to provided. This tells Lambda to treat the package as a custom runtime.
    • msbuild-parameters is set to --self-contained true so that all of the .NET Core runtime assemblies are included in the deployment package.
    • function-handler isn’t used for anything because the method to call is hard-coded into the executable.

{
	"profile":"",
	"region" : "",
	"configuration" : "Release",
	"framework" : "netcoreapp2.2",
	"function-runtime":"provided",
	"function-memory-size" : 256,
	"function-timeout" : 30,
	"function-handler" : "not_required_for_custom_runtime",
	"function-name" : "CustomRuntimeFunction",
	"msbuild-parameters": "--self-contained true"
}
  • bootstrap – A Linux bash script that’s invoked by the Lambda infrastructure to start the function.

#!/bin/sh
# This is the script that the Lambda host calls to start the custom runtime.

/var/task/CustomRuntimeFunction

To deploy and invoke the function, run the following.


cd ./CustomRuntimeFunction/src/CustomRuntimeFunction/
dotnet lambda deploy-function
dotnet lambda invoke-function -p "hello world"

You should receive a response with a payload of “HELLO WORLD”.

Converting the sample to .NET Core 3.0

If you have the .NET Core 3.0 SDK installed, you can easily convert the sample to use it.

In CustomRuntimeFunction.csproj and aws-lambda-tools-defaults.json change netcoreapp2.2 to netcoreapp3.0 then rerun.


dotnet lambda deploy-function
dotnet lambda invoke-function -p "hello world"

Summary

.NET developers now have a way to publish AWS Lambda functions in virtually any version of .NET Core. We hope you find the new Amazon.Lambda.RuntimeSupport library and tools useful. Try out our walkthrough today and let us know what you think. We welcome your questions and feedback on Amazon.Lambda.RuntimeSupport in our GitHub repo.