« Lambda » : différence entre les versions
Ligne 113 : | Ligne 113 : | ||
* Accessed via API | * Accessed via API | ||
= Roles, persissions and policies | = Roles, persissions and policies = | ||
== IAM == | == IAM == | ||
{| class="wikitable wtp" | {| class="wikitable wtp" |
Version du 17 avril 2024 à 12:06
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
- endless loop
- 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
Handler (entry point)
Method responsible for processing input events.
synchronous execution | result returned to the calling app |
asynchronous execution | result sent to the configured destination otherwise lost |
Configuration
Setting | Description |
---|---|
Memory | from 128 MB (default) to 10 GB |
vCPU | 1'769 MB = 1 vCPU, 10 GB = 6 vCPU, for single-threaded code allocated more than 1'769 MB is useless. Compare ARM and x86. |
timeout | from 1s to 15mn, default to 3s |
VPC |
|
Ephemeral storage | /tmp from 512 MB (default) to 10 GB |
Execution role | define what the function is allowed to do |
Resource-based policy | define what others are allowed to do to the function |
Storage
Directories
Path | Description |
---|---|
/var/task | Lambda package (function files) |
/tmp | Temporary storage with write access |
/opt | Lambda layer (layer files) |
Elastic File System (EFS)
- Persistent
- Serverless, scalable
- Support concurrent access
- Require VPC access
S3
- Persistent
- No VPC required
- Accessed via API
Roles, persissions and policies
IAM
Type | Description |
---|---|
User | individual with unique credentials |
Role | entity for temporary access (access to a db) |
Policy | permission for access to resources (apply to a user or a role to read from a specific db table) |
User group | logical collection of users for easier management |
Setting up your .NET development environment
# install the VS project template dotnet new install Amazon.Lambda.Templates # install the command line tools dotnet tool install -g Amazon.Lambda.Tools |
Install the AWS Toolkit for Visual Studio extension.
AWS Lambda application types
AWS Lambda application type | Description |
---|---|
Class library | |
Executable assembly | |
AWS Serverless Application | ASP.NET application hosted in the AWS environment. It has a handful of additional dependencies that make it interoperate with AWS runtime. |
C# class library
You provide Lambda with information about your function's handler in the form of a handler string: ASSEMBLY::TYPE::METHOD
- ASSEMBLY is the name of the .NET assembly file for your application. If you use the Amazon.Lambda.Tools CLI to build your application and you don't set the assembly name using the AssemblyName property in the .csproj file, then ASSEMBLY is simply the name of your .csproj file.
- TYPE is the full name of the handler type, which consists of the Namespace and the ClassName.
- METHOD is the name of the function handler method in your code.
ex: MyProject::MyNamespace.MyClass::MyFunctionHandler
Function.cs |
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace MyProject; public class Function { public string FunctionHandler(string input, ILambdaContext context) { return input.ToUpper(); } } |
aws-lambda-tools-defaults.json |
{ "Information": [ ], "profile": "MyAwsProfile", "region": "eu-central-1", "configuration": "Release", "function-architecture": "x86_64", "function-runtime": "dotnet8", "function-memory-size": 512, "function-timeout": 30, "function-handler": "MyProject::MyProject.Function::FunctionHandler" } |
On VS, if the extension AWS Toolkit is installed, you have the AWS .NET Mock Lambda Test Tool available which allows you to debug locally.
Properties/launchSettings.json |
{ "profiles": { "Mock Lambda Test Tool": { "commandName": "Executable", "commandLineArgs": "--port 5050", "workingDirectory": ".\\bin\\$(Configuration)\\net8.0", "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-8.0.exe" } } } |
C# executable assembly
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(); |
To debug locally you have to create the debug configuration file for you lambda.
Properties\launchSettings.json |
{ "profiles": { "Mock Lambda Test Tool": { "commandName": "Executable", "commandLineArgs": "--port 5050", "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-8.0.exe", "workingDirectory": ".\\bin\\$(Configuration)\\net8.0", "environmentVariables": { "AWS_LAMBDA_RUNTIME_API": "localhost:5050", "AWS_PROFILE": "MyProfile", "AWS_REGION": "us-east-1" } } } } |
Deployment
dotnet lambda deploy-function [AssemblyName] --profile [Profile] |
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); } |
Errors
Could not find the specified handler assembly with the file name LambdaTest
The Lambda on AWS has wrongly set the handler to LambdaTest.
AWS - Lambda - Functions - select your function - Code tab - Runtime settings - Edit - change the Handler
Your function doesn't have permission to write to Amazon CloudWatch Logs
- AWS → IAM → Roles → [the roles used by your lambda] → Persissions policies → Add permission → Create inline policy
- Service = CloudWatch Logs
- All CloudWatch Logs actions (logs:*)
- All Resources