Links
Description
Serverless service / Function as a service allowing to run code without having to worry about underlying hardware and OS.
Event driven: the lambda is triggered by an event.
Pay only for what you use: per request and based on the duration of the code execution.
Use cases
- Data transformation (Kinesis Data Stream as input)
- File processing (when uploaded to S3 bucket)
- Website backend microservice
- Scheduled tasks
Bad use cases
- Long running processes (timeout after 15mn)
- Constant workload (no scalability and high cost)
- Large code base (needed to be loaded at startup)
- State management (lambda are stateless)
Anti-patterns
- Monolithic function
- increase package size
- hard to enforce least privilege permissions
- hard to upgrade, maintain and test
- Recursion
- Orchestration
- avoid complex workflow logic
- ties lambda with other systems
- instead consider AWS Step Functions or EventBridge
- Chaining (synchronously invoke another lambda)
- instead use EventBridge or QueueService
- Waiting (synchronously call services or databases)
- instead use asynchronous calls
Runtime
- OS
- Libraries
- Programming language (.NET, Node.js, Python, Go, Ruby, Java)
Environnement variables
DOTNET_STARTUP_HOOKS |
ex: path to an assembly to inject logging
|
Wrapper scripts
Execute the wrapper on top of the runtime and the lambda function.
- run shell commands and binaries
Use AWS_LAMBDA_EXEC_WRAPPER to point to your wrapper script.
Custom runtime
Provide your custom runtime.
- unsupported programming language
Method responsible for processing input events.
synchronous execution |
result returned to the calling app
|
asynchronous execution |
result sent to the configured destination otherwise lost
|
Using the C# 9's top-level statements feature, you generate an executable assembly which will be run by the Lambda. You provide Lambda only with the name of the executable assembly to run.
|
var handler = async (string argument1, ILambdaContext context) => { };
// bootstrap the Lambda runtime and pass it the handler method
await LambdaBootstrapBuilder.Create(handler, new DefaultLambdaJsonSerializer()).Build().RunAsync();
|
Library lambda
|
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.CamelCaseLambdaJsonSerializer))]
namespace MyNamespace;
public class Function
{
public APIGatewayProxyResponse Handle(APIGatewayProxyRequest request, ILambdaContext context)
{
var id = request.PathParameters["id"];
var function = $"{context.FunctionName} {context.FunctionVersion}";
var cognitoIdentity = context.Identity;
context.Logger.LogLine("Message");
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Body = JsonSerializer.Serialize(id)
};
}
public void Handle(SQSEvent sqsEvent, ILambdaContext context) { }
}
|
|
# install the VS project template
dotnet new install Amazon.Lambda.Templates
# install the command line tools
dotnet tool install -g Amazon.Lambda.Tools
|
.NET 8
scenario
|
description
|
Native AOT |
|
Custom Runtime Function |
to use .NET 8
|
Container Image |
lambda function package as a container image
|
On VS, if the extension AWS Toolkit is installed you have the AWS .NET Mock Lambda Test Tool available.
A debug configuration is created for you lambda.
Properties\launchSettings.json
|
{
"profiles": {
"Mock Lambda Test Tool": {
"commandName": "Executable",
"commandLineArgs": "--port 5050",
"executablePath": "<home-directory>\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe",
"workingDirectory": ".\\bin\\Debug\\net6.0"
}
}
}
|
Call a lambda from code
|
var jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter() }
};
var amazonLambdaClient = new AmazonLambdaClient();
var request = new InvokeRequest
{
FunctionName = functionName,
Payload = JsonSerializer.Serialize(myObject, jsonSerializerOptions),
LogType = LogType.Tail
};
var response = await this.amazonLambdaClient.InvokeAsync(request);
if(response.HttpStatusCode == System.Net.HttpStatusCode.OK)
{
var payload = Encoding.ASCII.GetString(response.Payload.ToArray()); // to debug only
var result = JsonSerializer.Deserialize<AwsJobResult<LambdaJob>>(response.Payload, jsonSerializerOptions);
}
|