AWS Lambda
Features
Lambda is the so called as "server-less architecture" of AWS. It is different from the previous two as it is event driven; so the code uploaded in Lambda, is not given an execution environment to run code, until the defined event is triggered, and in this process, the user does not get to either provision or manage servers, and hence user only pay for the time used to consume compute resources. Due to this, there is a limitation, that whatever code is uploaded in Lambda, should complete execution within 5 minutes
Here, lot of application or back‑end service is supported and as there is no scope for administration, it integrates with many AWS services.
One of the most important features is that it is highly scalable.
Pricing changes with memory. An AWS user can consume memory from 128 to 3008 MB allocated for functions that are running on AWS Lambda.
As explained in IAM, Roles are used for one AWS service to communicate with other service
AWS Lambda supports versioning (max versions are 5) and each version is immutable, i.e., once published, they cannot be changed and if changes are required, publish a new version, so in all, it can look like this:
LambdaFunctionName
LambdaFunctionName:1 <- Immutable
LamdaFunctionName:2 <- Immutable
Execution Environment Lifecycle
Execution Environments are secure and isolated runtime environments
The lifecycle can be defined as shown below:

Extension INIT - In the Extension Init phase the system starts all extensions to let them apply their logic to the Lambda
Runtime INIT - The runtime is the combination of an operating system, programming language and a combination of software libraries required to invoke the Lambda function
Types of Invocations
AWS Lambda supports parallel invocations:
The characteristics of Lambda Execution environment are as follows:
Read Only File System
Memory based on Lambda configuration during setup
512 MB of disk space in /tmp directory
No inbound connections
Only TCP/IP Outbound connections are allowed
Max timeout of 15 minutes
The solution to above problem can be diagrammatically summarized as: Use Asynchronous events or Stream (Poll-based)
Improving Response Time by keeping Lambda Functions Warm

Layers in Lambda Functions
Layers can also have upto 5 versions and as they have versioning, they are also immutable.
Lambda Functions can use multiple layers which can be compatible with a runtime.
They are extracted to /opt directory as shown below:
Python - /opt/python/lib/python<version>/site-packages
Node.js - /opt/nodejs/node_modules
Binaries - /bin
Java - /opt/java/lib
As per ChatGPT
Each layer has specific ARN.
Layers can be stacked and ordering of layer matters
Max size of a layer is 250 MB
Lambda Environment Variables
Note that the id (which tell username) for an lambda environment generally tarts with sbx_user<number>
Lambda Alias Routing
Lambda supports not only creating alias of a function but also supports routing to it. This is generally used to test new features by traffic shifting to send a small percentage of traffic to a second function alias or version for a rolling deployment before production rollout. This is commonly called a canary release
Example: 90% of invocations route to the stable version while 10% route to alias new-feature pointing to version 3. If the 10% is successful, deployment can continue until all traffic is migrated to version 3, and the stable alias is then pointed to version 3.

Event and Context
The event
parameter contains data that is passed to the Lambda function at the time of invocation. This data is specific to the event source that triggers the Lambda function.

When Lambda runs the function, it passes a context
object to the handler. This object provides methods and properties that provide information about the invocation, function, and execution environment. It's main role is to provide information about the current execution environment. Unlike event
, the methods and properties of the context
object remain the same regardless of the lambda was invoked or triggered
Sample Code:
// Generated by ChatGPT
def lambda_handler(event, context):
# Accessing event data
print("Received event:", event)
# Accessing context data
print("Request ID:", context.aws_request_id)
print("Function Name:", context.function_name)
# Your processing logic here
return {
'statusCode': 200,
'body': 'Hello from Lambda!'
}
Runtime
It is mostly a script (bootstrap executable file) that executes everything in order for getting the proper work from everyone and giving the output to user, via Runtime API and Lambda service

So, runtime runs the function's setup code. It reads the handler name from an environment variable, reads the invocation event from lambda runtime API, passes the event data to function handler and posts the response from handler back to Lambda. It can distributed as public or private layers
Working and Execution Flow can be explained as follows:
Runtime API Path (https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html):
Invocation Request - GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next"
Invocation Response - POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/AwsRequestId/response"
Invocation Error - POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/AwsRequestId/error"
Invocation Error Path - POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/init/error"
Steps for using AWS Lambda
Example Scenario: Generate Symmetric keys using Lambda


Now, to create a lambda function using dotnet cli, ensure that .NET SDK is installed from here.
Create a folder to host the source code
cd <to-the-created-folder>
dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org
dotnet new --install Amazon.Lambda.Templates
dotnet new lambda.EmptyFunction --name SymKeyGen
cd SymKeyGen
cd src
notepad SymKeyGen.csproj
// make the following changes
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework> //Change here
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AWSProjectType>Lambda</AWSProjectType>
<!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<!-- Generate ready to run images during publishing to improve cold start time. -->
<PublishReadyToRun>false</PublishReadyToRun> //Change here
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.Core" Version="2.3.0" />
</ItemGroup>
</Project>
dotnet add package Amazon.Lambda.Core
dotnet add package Amazon.Lambda.APIGatewayEvents
dotnet add package AWSSDK.S3
dotnet add package Newtonsoft.Json
notepad Function.cs
//Generated by ChatGPT
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.S3;
using Amazon.S3.Model;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
public class Function
{
private readonly string bucketName = "radifineuniquebucketname"; // Update with your S3 bucket name
private readonly IAmazonS3 s3Client;
public Function()
{
s3Client = new AmazonS3Client();
}
// Entry point for the Lambda function
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
return GenerateKey(request, context);
}
public APIGatewayProxyResponse GenerateKey(APIGatewayProxyRequest request, ILambdaContext context)
{
// Parse input parameters from the request
if (request.QueryStringParameters == null ||
!request.QueryStringParameters.TryGetValue("input", out var hexInput))
{
return new APIGatewayProxyResponse
{
StatusCode = 400,
Body = JsonConvert.SerializeObject(new { Error = "Input parameter is required." }),
Headers = new System.Collections.Generic.Dictionary<string, string>
{
{ "Content-Type", "application/json" }
}
};
}
// Decode hex input to original string
string inputParam = HexToString(hexInput);
// Validate the input
if (!IsValidInput(inputParam))
{
return new APIGatewayProxyResponse
{
StatusCode = 400,
Body = JsonConvert.SerializeObject(new { Error = "Invalid input parameter." }),
Headers = new System.Collections.Generic.Dictionary<string, string>
{
{ "Content-Type", "application/json" }
}
};
}
// Generate a symmetric key based on the input parameter
byte[] symmetricKey = GenerateKeyFromInput(inputParam);
var base64Key = Convert.ToBase64String(symmetricKey);
// Save the key to S3
string fileName = $"{inputParam}.txt"; // Name the file using the input string
var putRequest = new PutObjectRequest
{
BucketName = bucketName,
Key = fileName,
ContentBody = base64Key,
ContentType = "text/plain"
};
// Upload the key to S3
s3Client.PutObjectAsync(putRequest).Wait();
// Return the key and success message
var response = new
{
Key = base64Key,
Message = "Key generated and saved successfully."
};
return new APIGatewayProxyResponse
{
StatusCode = 200,
Body = JsonConvert.SerializeObject(response),
Headers = new System.Collections.Generic.Dictionary<string, string>
{
{ "Content-Type", "application/json" }
}
};
}
private bool IsValidInput(string input)
{
// Check for null or empty
if (string.IsNullOrWhiteSpace(input))
return false;
// Check length (e.g., maximum length of 255 characters)
if (input.Length > 255)
return false;
// Validate against a regex pattern (adjust as necessary)
string pattern = @"^[a-zA-Z0-9\-\.]+$"; // Example pattern: allows alphanumeric, hyphens, and dots
return Regex.IsMatch(input, pattern);
}
private byte[] GenerateKeyFromInput(string input)
{
using (var sha256 = SHA256.Create())
{
// Hash the input to create a fixed-length key
return sha256.ComputeHash(Encoding.UTF8.GetBytes(input));
}
}
private string HexToString(string hex)
{
StringBuilder result = new StringBuilder(hex.Length / 2);
for (int i = 0; i < hex.Length; i += 2)
{
result.Append((char)Convert.ToByte(hex.Substring(i, 2), 16));
}
return result.ToString();
}
}
dotnet build
dotnet publish -c Release -o ./publish
Compress-Archive -Path * -DestinationPath ../SymKeyGenSrc.zip


Edit the permissions for access to S3





For those interested, can head over API Gateway to have complete scenario based understanding.


Now, it should work
Last updated