The provided code sample demonstrates how to get a basic extension written in C# up and running.
Project files and folders:
csharp-example-extension.csproj
- .NET Core project file, which is mandatory for .NET Core build process. It defines<LangVersion>latest</LangVersion>
, so that the latest C# language features, like async Main could be used.Program.cs
- main entry point for this extension.ExtensionClient.cs
- Lambda Extension API client implementation.ExtensionEvent.cs
- Event types enumerable, so that the rest of the code can work with enum values, rather than string constants.extensions/csharp-example-extension
- Bash script that must be deployed toopt/extensions
folder as an executable file (see manual deployment steps below for details). This script will be used for .NET runtime dependent deployment.extensions/csharp-example-extension-self-contained
- Bash script that must be deployed toopt/extensions
folder as an executable file (see manual deployment steps below for details). This script will be used for self-contained deployment.
- .NET Core SDK - 5.0 or a later version with 3.1 targeting pack installed (if .NET Core 3.1 dependent deployment is used).
- AWS CLI v2 - version 2.1.14 or newer.
- Since this is an external .NET Core extension, we would require a lambda function with .NET Core 3.1 runtime published to test this extension. For more information on publishing a blank C# lambda function please refer here.
- Bash shell with
zip
command support. Linux and macOS operating systems have that shell available by default (although the macOS has recently switched to ZSH default shell, Bash is still available for Catalina and Big Sur anyway). Windows 10 users can install Windows Subsystem for Linux or just use Git Bash, which is included with Git for Windows installation package.
The following configuration setting must be set in AWS CLI configuration file (~/.aws/config
), so that AWS CLI v2 will use backward compatibility with the AWS CLI version 1 behavior where binary values must be passed literally:
cli_binary_format=raw-in-base64-out
git clone https://github.com/aws-samples/aws-lambda-extensions.git
cd aws-lambda-extensions/csharp-example-extension
csharp-example-extension.csproj
has all necessary configuration for deploying this extension as a self-contained executable or a .NET runtime dependent extension.
Self-contained executable does not require any runtime to be pre-installed for Lambda function, thus it is compatible with any Lambda functions (.NET, Java, NodeJS, etc.). All necessary .NET runtime libraries are packaged together with the extension, thus the result package is much larger, than the .NET runtime dependent package (10MB+ vs 10KB+).
- make sure that
csharp-example-extension
is your current folder andrun.sh
script has executable bit set -ls -l run.sh
output should start with-rwxr-xr-x
permissions mask. - make
run.sh
executable withchmod +x run.sh
if needed. - assuming that demo C# Lambda function has already been deployed to the current AWS account and its name is
test-dotnet
, execute the following command to build the extension and deploy it to the current AWS account as a Lambda layer, namedcsharp-example-extension
:
IMPORTANT: You will be able to attach this extension to .NET Core 3.1 Lambda functions only!!!
./run.sh -e csharp-example-extension -f test-dotnet
This type of deployment is compatible with any Lambda function runtime.
./run.sh -e csharp-example-extension -f test-dotnet -s
- Make sure that all scripts in
extensions/*
folder has executable bit set and set it if needed, otherwise Lambda initialization will fail withPermissionDenied
error (see Troubleshooting section for details):
chmod +x extensions/*
- Publish .NET Core project with
Release
configuration and targeting a specific framework.csharp-example-extension.csproj
file contains all necessary configuration for building and packaging the result if needed. This command (see below) will download all necessary NuGet packages, referenced by the project, build the binaries usingRelease
configuration settings and publish the result tobin/publish
folder. Please, refer to dotnet publish documentation for details and additional command line options.
dotnet publish -c Release -f netcoreapp3.1 -o bin/publish
-p:Platform=x64
switch will enable conditional build configuration in csharp-example-extension.csproj
to package extension together with linux-x64
runtime and wrap everything into a single bundle. This bundle doesn't require a custom shell script and will be deployed directly to extensions
folder.
dotnet publish -c Release -f net5.0 -p:Platform=x64 -o bin/publish
- Change your current folder to the publish destination folder:
cd bin/publish
- Move all publish results to
deploy.zip
archive recursively:
zip -rm ./deploy.zip *
- Define Lambda function and extension name variables, so that they can be easily referenced later. Make sure that
test-dotnet
Lambda function has already been published to the current AWS account (it can be any other, non-.NET function im case of the self-contained extension):
EXTENSION_NAME="csharp-example-extension"
LAMBDA_FUNCTION="test-dotnet"
- Publish extension archive as a new Lambda layer:
aws lambda publish-layer-version \
--layer-name "${EXTENSION_NAME}" \
--zip-file "fileb://deploy.zip"
- Update
test-dotnet
Lambda function to usecsharp-example-extension
layer
aws lambda update-function-configuration \
--function-name ${LAMBDA_FUNCTION} --layers $(aws lambda list-layer-versions --layer-name ${EXTENSION_NAME} \
--max-items 1 --no-paginate --query 'LayerVersions[0].LayerVersionArn' \
--output text)
You can use AWS Console or AWS CLI to invoke your test function (test-dotnet
):
aws lambda invoke \
--function-name "${LAMBDA_FUNCTION}" \
--payload '{"payload": "hello"}' /tmp/invoke-result \
--cli-binary-format raw-in-base64-out --log-type Tail
All logs can be fund in /aws/lambda/test-dotnet
Cloudwatch group - both Lambda extension and Lambda function log messages are reported to that group.
EXTENSION Name: csharp-example-extension State: LaunchError Events: [] Error Type: PermissionDenied
Validate that execution bit has been properly set on the extension shell script.
For example ls -la extensions
output should look like (notice x
bit set):
-rwxr-xr-x 1 user group 289 Dec 22 15:16 csharp-example-extension
Self-contained deployments must make sure that dotnet publish
output has proper executable flag set on the bundle file.