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/extensionsfolder 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/extensionsfolder 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
zipcommand 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-outgit clone https://github.com/aws-samples/aws-lambda-extensions.git
cd aws-lambda-extensions/csharp-example-extensioncsharp-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-extensionis your current folder andrun.shscript has executable bit set -ls -l run.shoutput should start with-rwxr-xr-xpermissions mask. - make
run.shexecutable withchmod +x run.shif 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-dotnetThis 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 withPermissionDeniederror (see Troubleshooting section for details):
chmod +x extensions/*- Publish .NET Core project with
Releaseconfiguration and targeting a specific framework.csharp-example-extension.csprojfile 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 usingReleaseconfiguration settings and publish the result tobin/publishfolder. 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.ziparchive recursively:
zip -rm ./deploy.zip *- Define Lambda function and extension name variables, so that they can be easily referenced later. Make sure that
test-dotnetLambda 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-dotnetLambda function to usecsharp-example-extensionlayer
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 TailAll 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.