Lambda ARM64 Custom Runtime with .NET 6

Want to learn more about AWS Lambda and .NET? Check out my A Cloud Guru course on ASP.NET Web API and Lambda.

Full source code available here

This post was written before the .NET 6 managed runtime became available for Lambda. See this post if you want to use ARM64 on a managed runtime.

I have a few other posts on running .NET 6 on AWS Lambda.

Introduction

This post is very similar to one I wrote on running .NET 6 on a linux-x64 Lambda custom runtime.

Since writing that one, the Amazon.Lambda.Templates have been updated to include a .NET 6 Custom Runtime Template.

Here are the steps to run a .NET 6 application on AWS Lambda using an ARM64 processor.

Getting the tools

You need two AWS .NET tools, the Lambda templates, and the Amazon Lambda Tools.

Run this to install the templates -

dotnet new -i Amazon.Lambda.Templates

At the time of this writing, the latest version is 5.6.0, and includes a custom runtime template for .NET 6 (see the earlier post for a little on managed vs custom runtimes).

Run this to install the tools -

dotnet tool install -g Amazon.Lambda.Tools

Now run dotnet new lambda --list to see all the available templates.

You should see a list like below, note Lambda Custom Runtime Function (.NET 6), that’s the one we want -

Template Name                                         Short Name                                    Language  Tags
----------------------------------------------------  --------------------------------------------  --------  ---------------------
Lambda ASP.NET Core Web API                           serverless.AspNetCoreWebAPI                   [C#],F#   AWS/Lambda/Serverless
Lambda ASP.NET Core Web API (.NET 5 Container Image)  serverless.image.AspNetCoreWebAPI             [C#],F#   AWS/Lambda/Serverless
Lambda ASP.NET Core Web Application with Razor Pages  serverless.AspNetCoreWebApp                   [C#]      AWS/Lambda/Serverless
Lambda Custom Runtime Function (.NET 6)               lambda.CustomRuntimeFunction                  [C#],F#   AWS/Lambda/Function
Lambda Detect Image Labels                            lambda.DetectImageLabels                      [C#],F#   AWS/Lambda/Function
snip..

Create the project

Run -

dotnet new lambda.CustomRuntimeFunction --name LambdaNet6OnArm64

This will create two projects, one src and one test, for this blog I’m going to ignore the test project.

You’ll see something like -

"The template "Lambda Custom Runtime Function (.NET 6)" was created successfully.".

Changes to aws-lambda-tools-defaults.json

Open aws-lambda-tools-defaults.json, add a new line below the configuration with the following -

"function-architecture": "arm64",

Your file should look like this now -

{
  "Information": [
    "snip..."
  ],
  "profile": "",
  "region": "",
  "configuration": "Release",
  "function-architecture": "arm64",
  "function-runtime": "provided.al2",
  "function-memory-size": 256,
  "function-timeout": 30,
  "function-handler": "bootstrap::LambdaNet6OnArm64.Function::FunctionHandler",
  "msbuild-parameters": "--self-contained true"
}

The Function.cs file

Update the FunctionHandler method in Function.cs to the following -

public static string FunctionHandler(string input, ILambdaContext context)
{
    var architecture = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture;
    var dotnetVersion = Environment.Version.ToString();
    return $"Architecture: {architecture}, .NET Version: {dotnetVersion} -- {input?.ToUpper()}";
}

With these changes, the Lambda will tell us what architecture it is running on, and what version of .NET it is running.

Deploying the Lambda

This is where the Amazon Lambda Tools you installed earlier come into use.

Make sure you are in the directory with the source code, if you have been following along it should be something like somewhere...\LambdaNet6OnArm64\src\LambdaNet6OnArm64

dotnet lambda deploy-function LambdaNet6OnArm64

You will see it spit out a bunch of compile/publish info, note that the framework is net6.0 and the runtime is linux-arm64.

"C:\dev\aws\lambda\arm64\LambdaNet6OnArm64\src\LambdaNet6OnArm64\bin\Release\net6.0\publish" --configuration "Release" --framework "net6.0" --self-contained true /p:GenerateRuntimeConfigurationFiles=true --runtime linux-arm64
Then you’ll be asked which IAM role you want to use, the last number on the list will be for *** Create new IAM Role ***, pick that.

Then enter a name for the role, something like LambdaNet6OnArm64_role will do.

Finally, you’ll be asked what permissions to grant, select AWSLambdaRole.

It will then take a moment or two to create the role.

You should then see -

New Lambda function created. 

Running the Lambda

To execute the Lambda, run this -

dotnet lambda invoke-function LambdaNet6OnArm64 --payload "hello lambda"

You will see output that contains -

Payload:
"Architecture: Arm64, .NET Version: 6.0.0 -- HELLO LAMBDA"

There is .NET 6 running on an ARM64 processor in a Lambda!

Trimming and Ready to Run

Take a look in the .csproj file, you will see PublishReadyToRun and PublishTrimmed, I wrote a little about these in another post.

Full source code available here

comments powered by Disqus

Related