Deploy .NET Lambda functions with container images
There are three ways to build a container image for a .NET Lambda function:
-
Using an AWS base image for .NET
The AWS base images are preloaded with a language runtime, a runtime interface client to manage the interaction between Lambda and your function code, and a runtime interface emulator for local testing.
-
Using an AWS OS-only base image
AWS OS-only base images
contain an Amazon Linux distribution and the runtime interface emulator . These images are commonly used to create container images for compiled languages, such as Go and Rust, and for a language or language version that Lambda doesn't provide a base image for, such as Node.js 19. You can also use OS-only base images to implement a custom runtime. To make the image compatible with Lambda, you must include the the runtime interface client for .NET in the image. -
You can use an alternative base image from another container registry, such as Alpine Linux or Debian. You can also use a custom image created by your organization. To make the image compatible with Lambda, you must include the the runtime interface client for .NET in the image.
Tip
To reduce the time it takes for Lambda container functions to become active, see Use multi-stage builds
This page explains how to build, test, and deploy container images for Lambda.
Topics
AWS base images for .NET
AWS provides the following base images for .NET:
Tags | Runtime | Operating system | Dockerfile | Deprecation |
---|---|---|---|---|
8 |
.NET 8 | Amazon Linux 2023 | Dockerfile
for .NET 8 on GitHub |
Not scheduled |
6 |
.NET 6 | Amazon Linux 2 | Dockerfile
for .NET 6 on GitHub |
Dec 20, 2024 |
Amazon ECR repository: gallery.ecr.aws/lambda/dotnet
Using an AWS base image for .NET
Prerequisites
To complete the steps in this section, you must have the following:
-
.NET SDK
– The following steps use the .NET 8 base image. Make sure that your .NET version matches the version of the base image that you specify in your Dockerfile.
Creating and deploying an image using a base image
In the following steps, you use Amazon.Lambda.Templates
-
Install the Amazon.Lambda.Templates
NuGet package. dotnet new install Amazon.Lambda.Templates
-
Create a .NET project using the
lambda.image.EmptyFunction
template.dotnet new lambda.image.EmptyFunction --name
MyFunction
--regionus-east-1
-
Navigate to the
directory. This is where the project files are stored. Examine the following files:MyFunction
/src/MyFunction
-
aws-lambda-tools-defaults.json – This file is where you specify the command line options when deploying your Lambda function.
-
Function.cs – Your Lambda handler function code. This is a C# template that includes the default
Amazon.Lambda.Core
library and a defaultLambdaSerializer
attribute. For more information about serialization requirements and options, see Serialization in Lambda functions. You can use the provided code for testing, or replace it with your own. -
MyFunction.csproj – A .NET project file
, which lists the files and assemblies that comprise your application. -
Readme.md – This file contains more information about the sample Lambda function.
-
-
Examine the Dockerfile in the
src/
directory. You can use the provided Dockerfile for testing, or replace it with your own. If you use your own, make sure to:MyFunction
-
Set the
FROM
property to the URI of the base image. Your .NET version must match the version of the base image. -
Set the
CMD
argument to the Lambda function handler. This should match theimage-command
inaws-lambda-tools-defaults.json
.
Note that the example Dockerfile does not include a USER instruction
. When you deploy a container image to Lambda, Lambda automatically defines a default Linux user with least-privileged permissions. This is different from standard Docker behavior which defaults to the root
user when noUSER
instruction is provided.Example Dockerfile
# You can also pull these images from DockerHub amazon/aws-lambda-dotnet:8 FROM
public.ecr.aws/lambda/dotnet:8
# Copy function code to Lambda-defined environment variable COPY publish/* ${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "MyFunction::MyFunction.Function::FunctionHandler
" ] -
-
Install the Amazon.Lambda.Tools .NET Global Tool
. dotnet tool install -g Amazon.Lambda.Tools
If Amazon.Lambda.Tools is already installed, make sure that you have the latest version.
dotnet tool update -g Amazon.Lambda.Tools
-
Change the directory to
, if you're not there already.MyFunction
/src/MyFunction
cd src/
MyFunction
-
Use Amazon.Lambda.Tools to build the Docker image, push it to a new Amazon ECR repository, and deploy the Lambda function.
For
--function-role
, specify the role name—not the Amazon Resource Name (ARN)—of the execution role for the function. For example,lambda-role
.dotnet lambda deploy-function
MyFunction
--function-rolelambda-role
For more information about the Amazon.Lambda.Tools .NET Global Tool, see the AWS Extensions for .NET CLI
repository on GitHub. -
Invoke the function.
dotnet lambda invoke-function
MyFunction
--payload "Testing the function"If everything is successful, you see the following:
Payload: "TESTING THE FUNCTION" Log Tail: START RequestId:
id
Version: $LATEST END RequestId:id
REPORT RequestId:id
Duration: 0.99 ms Billed Duration: 1 ms Memory Size: 256 MB Max Memory Used: 12 MB -
Delete the Lambda function.
dotnet lambda delete-function
MyFunction
Using an alternative base image with the runtime interface client
If you use an OS-only base image or an alternative base image, you must include the runtime interface client in your image. The runtime interface client extends the Using the Lambda runtime API for custom runtimes, which manages the interaction between Lambda and your function code.
The following example demonstrates how to build a container image for .NET using a non-AWS base image, and how to add the Amazon.Lambda.RuntimeSupport package
Prerequisites
To complete the steps in this section, you must have the following:
-
.NET SDK
– The following steps use a .NET 8 base image. Make sure that your .NET version matches the version of the base image that you specify in your Dockerfile.
Creating and deploying an image using an alternative base image
-
Install the Amazon.Lambda.Templates
NuGet package. dotnet new install Amazon.Lambda.Templates
-
Create a .NET project using the
lambda.CustomRuntimeFunction
template. This template includes the Amazon.Lambda.RuntimeSupportpackage. dotnet new lambda.CustomRuntimeFunction --name
MyFunction
--regionus-east-1
-
Navigate to the
directory. This is where the project files are stored. Examine the following files:MyFunction
/src/MyFunction
-
aws-lambda-tools-defaults.json – This file is where you specify the command line options when deploying your Lambda function.
-
Function.cs – The code contains a class with a
Main
method that initializes theAmazon.Lambda.RuntimeSupport
library as the bootstrap. TheMain
method is the entry point for the function's process. TheMain
method wraps the function handler in a wrapper that the bootstrap can work with. For more information, see Using Amazon.Lambda.RuntimeSupport as a class libraryin the GitHub repository. -
MyFunction.csproj – A .NET project file
, which lists the files and assemblies that comprise your application. -
Readme.md – This file contains more information about the sample Lambda function.
-
-
Open the
aws-lambda-tools-defaults.json
file and Add the following lines:"package-type": "image",
"docker-host-build-output-dir": "./bin/Release/lambda-publish"
-
package-type: Defines the deployment package as a container image.
-
docker-host-build-output-dir: Sets the output directory for the build process.
Example aws-lambda-tools-defaults.json
{ "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": "", "region": "us-east-1", "configuration": "Release", "function-runtime": "provided.al2023", "function-memory-size": 256, "function-timeout": 30, "function-handler": "bootstrap", "msbuild-parameters": "--self-contained true",
"package-type": "image",
"docker-host-build-output-dir": "./bin/Release/lambda-publish"
} -
-
Create a Dockerfile in the
directory. The following example Dockerfile uses a Microsoft .NET base image instead of an AWS base image.MyFunction
/src/MyFunction
-
Set the
FROM
property to the base image identifier. Your .NET version must match the version of the base image. -
Use the
COPY
command to copy the function into the/var/task
directory. -
Set the
ENTRYPOINT
to the module that you want the Docker container to run when it starts. In this case, the module is the bootstrap, which initializes theAmazon.Lambda.RuntimeSupport
library.
Note that the example Dockerfile does not include a USER instruction
. When you deploy a container image to Lambda, Lambda automatically defines a default Linux user with least-privileged permissions. This is different from standard Docker behavior which defaults to the root
user when noUSER
instruction is provided.Example Dockerfile
# You can also pull these images from DockerHub amazon/aws-lambda-dotnet:8 FROM
mcr.microsoft.com/dotnet/runtime:8.0
# Set the image's internal work directory WORKDIR /var/task # Copy function code to Lambda-defined environment variable COPY "bin/Release/net8.0/linux-x64" . # Set the entrypoint to the bootstrap ENTRYPOINT ["/usr/bin/dotnet", "exec", "/var/task/bootstrap.dll
"] -
-
Install the Amazon.Lambda.Tools .NET Global Tools extension
. dotnet tool install -g Amazon.Lambda.Tools
If Amazon.Lambda.Tools is already installed, make sure that you have the latest version.
dotnet tool update -g Amazon.Lambda.Tools
-
Use Amazon.Lambda.Tools to build the Docker image, push it to a new Amazon ECR repository, and deploy the Lambda function.
For
--function-role
, specify the role name—not the Amazon Resource Name (ARN)—of the execution role for the function. For example,lambda-role
.dotnet lambda deploy-function
MyFunction
--function-rolelambda-role
For more information about the Amazon.Lambda.Tools .NET CLI extension, see the AWS Extensions for .NET CLI
repository on GitHub. -
Invoke the function.
dotnet lambda invoke-function
MyFunction
--payload "Testing the function"If everything is successful, you see the following:
Payload: "TESTING THE FUNCTION" Log Tail: START RequestId:
id
Version: $LATEST END RequestId:id
REPORT RequestId:id
Duration: 0.99 ms Billed Duration: 1 ms Memory Size: 256 MB Max Memory Used: 12 MB -
Delete the Lambda function.
dotnet lambda delete-function
MyFunction