diff --git a/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/checksums/checksums.lock b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/checksums/checksums.lock new file mode 100644 index 0000000000..e90b553fa0 Binary files /dev/null and b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/checksums/checksums.lock differ diff --git a/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileChanges/last-build.bin b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileChanges/last-build.bin new file mode 100644 index 0000000000..f76dd238ad Binary files /dev/null and b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileChanges/last-build.bin differ diff --git a/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileHashes/fileHashes.bin b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileHashes/fileHashes.bin new file mode 100644 index 0000000000..4897deb50e Binary files /dev/null and b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileHashes/fileHashes.bin differ diff --git a/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileHashes/fileHashes.lock b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileHashes/fileHashes.lock new file mode 100644 index 0000000000..e128d3b7a7 Binary files /dev/null and b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/fileHashes/fileHashes.lock differ diff --git a/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/gc.properties b/dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/gc.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sqs-lambda-tenant-isolation-sam-py/README.md b/sqs-lambda-tenant-isolation-sam-py/README.md new file mode 100644 index 0000000000..0e3c44b0b6 --- /dev/null +++ b/sqs-lambda-tenant-isolation-sam-py/README.md @@ -0,0 +1,55 @@ +# Lambda Tenant Isolation Demo + +Multi-tenant application demonstrating AWS Lambda's tenant isolation feature. + +## Architecture + +``` +SQS Queue → SQS Processor Lambda → Tenant-Isolated Lambda + (reads customer-id) (processes with tenant isolation) +``` + +## Components + +### 1. SQS Processor (`sqs-processor/`) +- Triggered by SQS queue messages +- Extracts `customer-id` from message payload +- Invokes tenant-isolated Lambda asynchronously with `TenantId` parameter + +### 2. Tenant-Isolated Processor (`tenant-isolated-processor/`) +- Configured with tenant isolation mode enabled +- Processes requests in isolated execution environments per tenant +- Accesses tenant ID via `context.identity.tenant_id` + +## Message Format + +```json +{ + "customer-id": "tenant-123", + "data": "your payload here" +} +``` + +## Deployment + +```bash +sam build +sam deploy --guided +``` + +## Testing + +Send a message to the SQS queue: + +```bash +aws sqs send-message \ + --queue-url \ + --message-body '{"customer-id": "tenant-123", "data": "test payload"}' +``` + +## Key Features + +- Tenant isolation at infrastructure level (no custom routing logic) +- Execution environments never shared between tenants +- Asynchronous invocation pattern +- Automatic tenant context propagation diff --git a/sqs-lambda-tenant-isolation-sam-py/sqs-processor/index.py b/sqs-lambda-tenant-isolation-sam-py/sqs-processor/index.py new file mode 100644 index 0000000000..ecb798bb5a --- /dev/null +++ b/sqs-lambda-tenant-isolation-sam-py/sqs-processor/index.py @@ -0,0 +1,26 @@ +import json +import boto3 +import os + +lambda_client = boto3.client('lambda') +TENANT_ISOLATED_FUNCTION = os.environ['TENANT_ISOLATED_FUNCTION_NAME'] + +def handler(event, context): + for record in event['Records']: + body = json.loads(record['body']) + customer_id = body.get('customer-id') + + if not customer_id: + print(f"Missing customer-id in message: {body}") + continue + + lambda_client.invoke( + FunctionName=TENANT_ISOLATED_FUNCTION, + InvocationType='Event', + Payload=json.dumps(body), + TenantId=customer_id + ) + + print(f"Invoked tenant-isolated function for customer: {customer_id}") + + return {'statusCode': 200} diff --git a/sqs-lambda-tenant-isolation-sam-py/sqs-processor/requirements.txt b/sqs-lambda-tenant-isolation-sam-py/sqs-processor/requirements.txt new file mode 100644 index 0000000000..f6315cd5ca --- /dev/null +++ b/sqs-lambda-tenant-isolation-sam-py/sqs-processor/requirements.txt @@ -0,0 +1 @@ +boto3>=1.26.0 diff --git a/sqs-lambda-tenant-isolation-sam-py/template.yml b/sqs-lambda-tenant-isolation-sam-py/template.yml new file mode 100644 index 0000000000..080cfa065e --- /dev/null +++ b/sqs-lambda-tenant-isolation-sam-py/template.yml @@ -0,0 +1,69 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: Lambda Tenant Isolation Demo + +Resources: + ProcessingQueue: + Type: AWS::SQS::Queue + Properties: + QueueName: tenant-isolation-queue + VisibilityTimeout: 300 + + TenantIsolatedFunctionRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole + + TenantIsolatedFunction: + Type: AWS::Serverless::Function + Properties: + FunctionName: tenant-isolated-processor + CodeUri: tenant-isolated-processor/ + Handler: index.handler + Runtime: python3.12 + Timeout: 120 + Role: !GetAtt TenantIsolatedFunctionRole.Arn + TenancyConfig: + TenantIsolationMode: PER_TENANT + + SQSProcessorFunction: + Type: AWS::Serverless::Function + Properties: + FunctionName: sqs-processor + CodeUri: sqs-processor/ + Handler: index.handler + Runtime: python3.12 + Timeout: 60 + Environment: + Variables: + TENANT_ISOLATED_FUNCTION_NAME: !Ref TenantIsolatedFunction + Policies: + - Statement: + - Effect: Allow + Action: + - lambda:InvokeFunction + Resource: !GetAtt TenantIsolatedFunction.Arn + Events: + SQSEvent: + Type: SQS + Properties: + Queue: !GetAtt ProcessingQueue.Arn + BatchSize: 10 + +Outputs: + QueueUrl: + Value: !Ref ProcessingQueue + QueueArn: + Value: !GetAtt ProcessingQueue.Arn + TenantIsolatedFunctionArn: + Value: !GetAtt TenantIsolatedFunction.Arn + SQSProcessorFunctionArn: + Value: !GetAtt SQSProcessorFunction.Arn diff --git a/sqs-lambda-tenant-isolation-sam-py/tenant-isolated-processor/index.py b/sqs-lambda-tenant-isolation-sam-py/tenant-isolated-processor/index.py new file mode 100644 index 0000000000..d5432f88ef --- /dev/null +++ b/sqs-lambda-tenant-isolation-sam-py/tenant-isolated-processor/index.py @@ -0,0 +1,16 @@ +import json + +def handler(event, context): + tenant_id = context.tenant_id + + print(f"Processing request for tenant: {tenant_id}") + print(f"Event data: {json.dumps(event)}") + + # Process tenant-specific logic here + result = { + 'tenant_id': tenant_id, + 'message': 'Request processed successfully', + 'data': event + } + + return result diff --git a/sqs-lambda-tenant-isolation-sam-py/tenant-isolated-processor/requirements.txt b/sqs-lambda-tenant-isolation-sam-py/tenant-isolated-processor/requirements.txt new file mode 100644 index 0000000000..d2ce485de2 --- /dev/null +++ b/sqs-lambda-tenant-isolation-sam-py/tenant-isolated-processor/requirements.txt @@ -0,0 +1 @@ +# No external dependencies required