Skip to content

Commit 639b605

Browse files
author
purohmid
committed
sqs lambda tenant isolation first checkin
1 parent 3a3fb36 commit 639b605

11 files changed

Lines changed: 168 additions & 0 deletions

File tree

17 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

dynamodb-lambda-cdk-kotlin/.gradle/9.2.0/gc.properties

Whitespace-only changes.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Lambda Tenant Isolation Demo
2+
3+
Multi-tenant application demonstrating AWS Lambda's tenant isolation feature.
4+
5+
## Architecture
6+
7+
```
8+
SQS Queue → SQS Processor Lambda → Tenant-Isolated Lambda
9+
(reads customer-id) (processes with tenant isolation)
10+
```
11+
12+
## Components
13+
14+
### 1. SQS Processor (`sqs-processor/`)
15+
- Triggered by SQS queue messages
16+
- Extracts `customer-id` from message payload
17+
- Invokes tenant-isolated Lambda asynchronously with `TenantId` parameter
18+
19+
### 2. Tenant-Isolated Processor (`tenant-isolated-processor/`)
20+
- Configured with tenant isolation mode enabled
21+
- Processes requests in isolated execution environments per tenant
22+
- Accesses tenant ID via `context.identity.tenant_id`
23+
24+
## Message Format
25+
26+
```json
27+
{
28+
"customer-id": "tenant-123",
29+
"data": "your payload here"
30+
}
31+
```
32+
33+
## Deployment
34+
35+
```bash
36+
sam build
37+
sam deploy --guided
38+
```
39+
40+
## Testing
41+
42+
Send a message to the SQS queue:
43+
44+
```bash
45+
aws sqs send-message \
46+
--queue-url <QUEUE_URL> \
47+
--message-body '{"customer-id": "tenant-123", "data": "test payload"}'
48+
```
49+
50+
## Key Features
51+
52+
- Tenant isolation at infrastructure level (no custom routing logic)
53+
- Execution environments never shared between tenants
54+
- Asynchronous invocation pattern
55+
- Automatic tenant context propagation
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import json
2+
import boto3
3+
import os
4+
5+
lambda_client = boto3.client('lambda')
6+
TENANT_ISOLATED_FUNCTION = os.environ['TENANT_ISOLATED_FUNCTION_NAME']
7+
8+
def handler(event, context):
9+
for record in event['Records']:
10+
body = json.loads(record['body'])
11+
customer_id = body.get('customer-id')
12+
13+
if not customer_id:
14+
print(f"Missing customer-id in message: {body}")
15+
continue
16+
17+
lambda_client.invoke(
18+
FunctionName=TENANT_ISOLATED_FUNCTION,
19+
InvocationType='Event',
20+
Payload=json.dumps(body),
21+
TenantId=customer_id
22+
)
23+
24+
print(f"Invoked tenant-isolated function for customer: {customer_id}")
25+
26+
return {'statusCode': 200}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
boto3>=1.26.0
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: Lambda Tenant Isolation Demo
4+
5+
Resources:
6+
ProcessingQueue:
7+
Type: AWS::SQS::Queue
8+
Properties:
9+
QueueName: tenant-isolation-queue
10+
VisibilityTimeout: 300
11+
12+
TenantIsolatedFunctionRole:
13+
Type: AWS::IAM::Role
14+
Properties:
15+
AssumeRolePolicyDocument:
16+
Version: '2012-10-17'
17+
Statement:
18+
- Effect: Allow
19+
Principal:
20+
Service: lambda.amazonaws.com
21+
Action: sts:AssumeRole
22+
ManagedPolicyArns:
23+
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
24+
25+
TenantIsolatedFunction:
26+
Type: AWS::Serverless::Function
27+
Properties:
28+
FunctionName: tenant-isolated-processor
29+
CodeUri: tenant-isolated-processor/
30+
Handler: index.handler
31+
Runtime: python3.12
32+
Timeout: 120
33+
Role: !GetAtt TenantIsolatedFunctionRole.Arn
34+
TenancyConfig:
35+
TenantIsolationMode: PER_TENANT
36+
37+
SQSProcessorFunction:
38+
Type: AWS::Serverless::Function
39+
Properties:
40+
FunctionName: sqs-processor
41+
CodeUri: sqs-processor/
42+
Handler: index.handler
43+
Runtime: python3.12
44+
Timeout: 60
45+
Environment:
46+
Variables:
47+
TENANT_ISOLATED_FUNCTION_NAME: !Ref TenantIsolatedFunction
48+
Policies:
49+
- Statement:
50+
- Effect: Allow
51+
Action:
52+
- lambda:InvokeFunction
53+
Resource: !GetAtt TenantIsolatedFunction.Arn
54+
Events:
55+
SQSEvent:
56+
Type: SQS
57+
Properties:
58+
Queue: !GetAtt ProcessingQueue.Arn
59+
BatchSize: 10
60+
61+
Outputs:
62+
QueueUrl:
63+
Value: !Ref ProcessingQueue
64+
QueueArn:
65+
Value: !GetAtt ProcessingQueue.Arn
66+
TenantIsolatedFunctionArn:
67+
Value: !GetAtt TenantIsolatedFunction.Arn
68+
SQSProcessorFunctionArn:
69+
Value: !GetAtt SQSProcessorFunction.Arn
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import json
2+
3+
def handler(event, context):
4+
tenant_id = context.tenant_id
5+
6+
print(f"Processing request for tenant: {tenant_id}")
7+
print(f"Event data: {json.dumps(event)}")
8+
9+
# Process tenant-specific logic here
10+
result = {
11+
'tenant_id': tenant_id,
12+
'message': 'Request processed successfully',
13+
'data': event
14+
}
15+
16+
return result

0 commit comments

Comments
 (0)