Lambda Execution
With Docker enabled, Lambda functions execute your code in real Docker containers using AWS Lambda base images from public.ecr.aws/lambda/. Your handler code runs the same way it does in real AWS - same runtime environment, same environment variables, same invocation protocol.
Prerequisites
SIMFRA_DOCKER=true- Lambda runtime images are pulled automatically on first invocation
Supported Runtimes
| Runtime | Image |
|---|---|
nodejs18.x, nodejs20.x, nodejs22.x, nodejs24.x |
public.ecr.aws/lambda/nodejs:{version} |
python3.8 through python3.13 |
public.ecr.aws/lambda/python:{version} |
java8, java8.al2, java11, java17, java21, java25 |
public.ecr.aws/lambda/java:{version} |
dotnet6, dotnet8, dotnet10 |
public.ecr.aws/lambda/dotnet:{version} |
ruby3.2, ruby3.3, ruby3.4 |
public.ecr.aws/lambda/ruby:{version} |
go1.x |
public.ecr.aws/lambda/go:1 |
provided, provided.al2, provided.al2023 |
public.ecr.aws/lambda/provided:{tag} |
Override the image registry with SIMFRA_LAMBDA_IMAGE_REGISTRY (default public.ecr.aws/lambda).
Deploy from Zip
Create a deployment package and deploy:
# Python example
cat > handler.py << 'EOF'
def handler(event, context):
return {"statusCode": 200, "body": f"Hello, {event.get('name', 'World')}!"}
EOF
zip function.zip handler.py
aws --endpoint-url http://localhost:4599 lambda create-function \
--function-name my-func \
--runtime python3.12 \
--handler handler.handler \
--zip-file fileb://function.zip \
--role arn:aws:iam::000000000000:role/lambda-role
Invoke:
aws --endpoint-url http://localhost:4599 lambda invoke \
--function-name my-func \
--payload '{"name": "Simfra"}' \
output.json
cat output.json
{"statusCode": 200, "body": "Hello, Simfra!"}
Deploy from ECR Image
Push a container image to Simfra's ECR (see ECR Image Management), then create the function with PackageType=Image:
aws --endpoint-url http://localhost:4599 lambda create-function \
--function-name my-image-func \
--package-type Image \
--code ImageUri=000000000000.dkr.ecr.us-east-1.localhost:4599/my-app:latest \
--role arn:aws:iam::000000000000:role/lambda-role
The image must be compatible with the Lambda Runtime Interface Emulator (RIE). AWS Lambda base images include the RIE by default.
Layers
Create a layer and attach it to a function:
zip layer.zip python/my_lib.py
aws --endpoint-url http://localhost:4599 lambda publish-layer-version \
--layer-name my-layer \
--zip-file fileb://layer.zip \
--compatible-runtimes python3.12
aws --endpoint-url http://localhost:4599 lambda update-function-configuration \
--function-name my-func \
--layers arn:aws:lambda:us-east-1:000000000000:layer:my-layer:1
Layer contents are extracted and mounted into the function container at /opt.
Environment Variables
Function environment variables are passed to the container:
aws --endpoint-url http://localhost:4599 lambda update-function-configuration \
--function-name my-func \
--environment 'Variables={DB_HOST=mydb.abcdef.us-east-1.rds.simfra.dev,DB_PORT=5432}'
Simfra also sets the standard AWS Lambda reserved environment variables: AWS_REGION, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_MEMORY_SIZE, AWS_LAMBDA_FUNCTION_VERSION, AWS_LAMBDA_LOG_GROUP_NAME, and others.
Execution Role Credentials
Lambda containers receive temporary STS credentials for their execution role, matching real AWS behavior. The AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN environment variables are set from an STS AssumeRole call. These credentials are valid for the container's lifetime and are refreshed when the container is recycled.
This means your function code can call other AWS services (S3, DynamoDB, SQS, etc.) against Simfra using the default credential chain, and IAM policies on the execution role are enforced.
Container Lifecycle
Lambda containers are kept warm for reuse. After an invocation, the container stays alive for SIMFRA_LAMBDA_KEEP_ALIVE seconds (default 300). Subsequent invocations of the same function version reuse the warm container, matching the real Lambda warm-start behavior.
Containers are cleaned up when:
- The keep-alive period expires without another invocation.
- The function is deleted.
- Execution role credentials are about to expire (container is recycled with fresh credentials).
- Simfra shuts down.
Event Source Mappings
Event source mappings auto-trigger Lambda invocations from event sources:
SQS
aws --endpoint-url http://localhost:4599 lambda create-event-source-mapping \
--function-name my-func \
--event-source-arn arn:aws:sqs:us-east-1:000000000000:my-queue \
--batch-size 10
The Lambda poller reads messages from the SQS queue, invokes the function with the message batch, and deletes messages on success.
DynamoDB Streams
aws --endpoint-url http://localhost:4599 lambda create-event-source-mapping \
--function-name my-func \
--event-source-arn arn:aws:dynamodb:us-east-1:000000000000:table/my-table/stream/2024-01-01T00:00:00.000 \
--starting-position LATEST \
--batch-size 100
Kinesis
aws --endpoint-url http://localhost:4599 lambda create-event-source-mapping \
--function-name my-func \
--event-source-arn arn:aws:kinesis:us-east-1:000000000000:stream/my-stream \
--starting-position LATEST \
--batch-size 100
Event source mapping pollers use the function's execution role to read from the source (poller-owned authorization model). If the role lacks the required permissions, the mapping pauses and retries.
VPC Configuration
Lambda functions can be placed in a VPC:
aws --endpoint-url http://localhost:4599 lambda create-function \
--function-name my-vpc-func \
--runtime python3.12 \
--handler handler.handler \
--zip-file fileb://function.zip \
--role arn:aws:iam::000000000000:role/lambda-role \
--vpc-config SubnetIds=subnet-xxx,SecurityGroupIds=sg-xxx
VPC-attached Lambda containers are placed on the VPC Docker network and use VPC DNS. They can reach RDS, ElastiCache, and other private resources by endpoint name. Non-VPC Lambda containers use bridge DNS to resolve Simfra service names.
Function URLs
Lambda function URLs provide a dedicated HTTP endpoint:
aws --endpoint-url http://localhost:4599 lambda create-function-url-config \
--function-name my-func \
--auth-type NONE
Aliases and Versions
Publish versions and create aliases:
aws --endpoint-url http://localhost:4599 lambda publish-version \
--function-name my-func
aws --endpoint-url http://localhost:4599 lambda create-alias \
--function-name my-func \
--name prod \
--function-version 1
Each version maintains its own warm container pool.
Logs
Lambda function output is captured and forwarded to CloudWatch Logs under the /aws/lambda/{function-name} log group. View logs via the CloudWatch Logs API or the Simfra web console.
Next Steps
- Writing Lambda Functions - build Lambda functions that run in Simfra
- ECR Image Management - deploy Lambda functions from container images
- Endpoint Discovery - how Lambda containers discover the Simfra endpoint