Skip to content

Commit 13e77c1

Browse files
authored
Merge pull request #2895 from biswanathmukherjee/biswanathmukherjee-feature-apigw-lambda-tenant-isolation
AWS Lambda tenant isolation
2 parents 06968df + 54a21ad commit 13e77c1

File tree

7 files changed

+941
-0
lines changed

7 files changed

+941
-0
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Multi-tenant API with AWS Lambda tenant isolation
2+
3+
This sample project demonstrates tenant isolation mode of AWS Lambda functions by comparing two Lambda functions - one with tenant isolation enabled and one without. The demonstration uses in-memory counters to visually show how tenant isolation provides separate execution environments for different tenants.
4+
5+
## Requirements
6+
7+
- [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
8+
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
9+
- [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
10+
- [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) (AWS SAM) installed
11+
- [Python 3.14 or above](https://www.python.org/downloads/) installed
12+
13+
14+
## Deployment Instructions
15+
16+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
17+
18+
```bash
19+
git clone https://github.com/aws-samples/serverless-patterns
20+
```
21+
22+
2. Change directory to the pattern directory:
23+
24+
```bash
25+
cd serverless-patterns/apigw-lambda-tenant-isolation
26+
```
27+
28+
3. From the command line, run the following commands:
29+
30+
```bash
31+
sam build
32+
sam deploy --guided --capabilities CAPABILITY_NAMED_IAM
33+
```
34+
35+
4. During the prompts:
36+
37+
- Enter a stack name
38+
- Enter the desired AWS Region e.g. `us-east-1`.
39+
- Allow SAM CLI to create IAM roles with the required permissions.
40+
- Keep default values to the rest of the parameters.
41+
42+
Once you have run `sam deploy --guided` mode once and saved arguments to a configuration file (samconfig.toml), you can use `sam deploy` in future to use these defaults.
43+
44+
5. Note the outputs from the SAM deployment process. These contain the resource names and/or ARNs which are used for next step as well as testing.
45+
46+
## How it works
47+
48+
The SAM template deploys two Lambda functions - one with tenant isolation mode enabled, and another with tenant mode disabled.
49+
50+
![End to End Architecture](diagram/architecture.png)
51+
52+
Here's a breakdown of the steps:
53+
54+
1. **Standard AWS Lambda Function**: Receives tenant headers (`x-tenant-id`) but shares execution environment across all tenants. The counter variable, when increased for one tenant, impacts the other tenants (demonstrates the limitation)
55+
56+
2. **Tenant-Isolated AWS Lambda Function**: Maintains separate execution environments per tenant using AWS Lambda tenant isolation mode (demonstrates the solution)
57+
58+
3. **Amazon API Gateway**: Provides REST endpoints for both functions with header mapping
59+
60+
## Testing
61+
62+
Use [curl](https://curl.se/) to send a HTTP POST request to the API. Make sure to replace `api-id` with the one from your `sam deploy --guided` output:
63+
64+
### Standard Function (The limitation)
65+
66+
The standard function receives tenant headers but cannot isolate tenants - all requests share the same counter:
67+
68+
Replace with `StandardMultiTenantAPIEndpointUrl`:
69+
70+
```bash
71+
STANDARD_URL="https://your-api-id.execute-api.region.amazonaws.com/dev/standard"
72+
```
73+
74+
BlueTenant request:
75+
76+
```bash
77+
curl -H "tenant-id: BlueTenant" "$STANDARD_URL"
78+
```
79+
80+
Response:
81+
82+
```bash
83+
{
84+
"counter": 1,
85+
"tenant_id": "BlueTenant",
86+
"isolation_enabled": false,
87+
"message": "Counter incremented successfully - SHARED across all tenants! (Received tenant: BlueTenant)",
88+
"warning": "This function does NOT provide tenant isolation - all tenants share the same counter!"
89+
}
90+
```
91+
92+
RedTenant request:
93+
94+
```bash
95+
curl -H "x-tenant-id: RedTenant" "$STANDARD_URL"
96+
```
97+
98+
Response:
99+
100+
```bash
101+
{
102+
"counter": 2,
103+
"tenant_id": "RedTenant",
104+
"isolation_enabled": false,
105+
"message": "Counter incremented successfully - SHARED across all tenants! (Received tenant: RedTenant)",
106+
"warning": "This function does NOT provide tenant isolation - all tenants share the same counter!"
107+
}
108+
```
109+
110+
GreenTenant request:
111+
112+
```bash
113+
curl -H "x-tenant-id: GreenTenant" "$STANDARD_URL"
114+
```
115+
116+
Response:
117+
118+
```bash
119+
{
120+
"counter": 3,
121+
"tenant_id": "GreenTenant",
122+
"isolation_enabled": false,
123+
"message": "Counter incremented successfully - SHARED across all tenants! (Received tenant: GreenTenant)",
124+
"warning": "This function does NOT provide tenant isolation - all tenants share the same counter!"
125+
}
126+
```
127+
128+
Continue to invoke the API for different tenants. Note the `counter` values. As all the three tenants are reusing the same Lambda execution environment, the counter variable is also shared and continuously increasing across tenants.
129+
130+
### Isolated Function (The solution)
131+
132+
The isolated function provides true tenant isolation - each tenant gets separate Lambda execution environments:
133+
134+
Replace with `IsolatedTenantAPIEndpointUrl`:
135+
136+
```bash
137+
138+
ISOLATED_URL="https://your-api-id.execute-api.region.amazonaws.com/dev/isolated"
139+
```
140+
141+
BlueTenant requests (independent counter):
142+
143+
```bash
144+
curl -H "x-tenant-id: BlueTenant" "$ISOLATED_URL"
145+
```
146+
147+
Response:
148+
149+
```bash
150+
{
151+
"counter": 1,
152+
"tenant_id": "BlueTenant",
153+
"isolation_enabled": true,
154+
"message": "Counter incremented successfully for tenant BlueTenant"
155+
}
156+
```
157+
158+
GreenTenant requests (separate independent counter):
159+
160+
```bash
161+
curl -H "x-tenant-id: GreenTenant" "$ISOLATED_URL"
162+
```
163+
164+
Response:
165+
166+
```bash
167+
{
168+
"counter": 1,
169+
"tenant_id": "GreenTenant",
170+
"isolation_enabled": true,
171+
"message": "Counter incremented successfully for tenant GreenTenant"
172+
}
173+
```
174+
175+
Continue to invoke the API for different tenants. Note the `counter` values. Each tenant maintains independent counters (BlueTenant: 1→2→3, GreenTenant: 1→2), showing true isolation.
176+
177+
### Monitoring
178+
179+
Check CloudWatch logs to see tenant isolation in action:
180+
181+
```bash
182+
# View logs for standard function
183+
aws logs filter-log-events \
184+
--log-group-name "/aws/lambda/your-stack-name-counter-standard" \
185+
--start-time $(date -d '10 minutes ago' +%s)000
186+
187+
# View logs for isolated function (notice tenantId in platform events)
188+
aws logs filter-log-events \
189+
--log-group-name "/aws/lambda/your-stack-name-counter-isolated" \
190+
--start-time $(date -d '10 minutes ago' +%s)000
191+
```
192+
193+
## Cleanup
194+
195+
1. To delete the resources deployed to your AWS account via AWS SAM, run the following command:
196+
197+
```bash
198+
sam delete
199+
```
200+
201+
---
202+
203+
Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
204+
205+
SPDX-License-Identifier: MIT-0
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"title": "Multi-tenant API with AWS Lambda tenant isolation",
3+
"description": "This sample project demonstrates the tenant isolation mode of AWS Lambda functions.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "AWS SAM",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"Amazon API Gateway receives the HTTP GET request with tenant id in the header x-tenant-id.",
11+
"The API Gateway triggers either the standard or the tenant isolated Lambda functions depending on the URI.",
12+
"Observe the counter variable value between standard and tenant isolation mode enabled Lambda function as you invoke the APIs for different tenant."
13+
]
14+
},
15+
"gitHub": {
16+
"template": {
17+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-lambda-tenant-isolation",
18+
"templateURL": "serverless-patterns/apigw-lambda-tenant-isolation",
19+
"projectFolder": "apigw-lambda-tenant-isolation",
20+
"templateFile": "template.yaml"
21+
}
22+
},
23+
"resources": {
24+
"bullets": [
25+
{
26+
"text": "AWS Lambda tenant isolation",
27+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/tenant-isolation.html"
28+
},
29+
{
30+
"text": "AWS Blog - Building multi-tenant SaaS applications with AWS Lambda’s new tenant isolation mode",
31+
"link": "https://aws.amazon.com/blogs/compute/building-multi-tenant-saas-applications-with-aws-lambdas-new-tenant-isolation-mode/"
32+
}
33+
]
34+
},
35+
"deploy": {
36+
"text": [
37+
"sam build",
38+
"sam deploy --guided"
39+
]
40+
},
41+
"testing": {
42+
"text": [
43+
"See the GitHub repo for detailed testing instructions."
44+
]
45+
},
46+
"cleanup": {
47+
"text": [
48+
"Delete the stack: <code>sam delete</code>."
49+
]
50+
},
51+
"authors": [
52+
{
53+
"name": "Biswanath Mukherjee",
54+
"image": "https://serverlessland.com/assets/images/resources/contributors/biswanath-mukherjee.jpg",
55+
"bio": "I am a Sr. Solutions Architect working at AWS India. I help strategic global enterprise customer to architect their workload to run on AWS.",
56+
"linkedin": "biswanathmukherjee"
57+
}
58+
],
59+
"patternArch": {
60+
"icon1": {
61+
"x": 20,
62+
"y": 50,
63+
"service": "apigw",
64+
"label": "API Gateway REST API"
65+
},
66+
"icon2": {
67+
"x": 80,
68+
"y": 50,
69+
"service": "lambda",
70+
"label": "AWS Lambda"
71+
},
72+
"line1": {
73+
"from": "icon1",
74+
"to": "icon2",
75+
"label": "Request by tenant"
76+
}
77+
}
78+
}
29.7 KB
Loading
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"title": "Multi-tenant API with AWS Lambda functions tenant isolation",
3+
"description": "This sample project demonstrates tenant isolation mode of AWS Lambda functions.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "AWS SAM",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"Amazon API Gateway receives the HTTP GET request with tenant id in the header x-tenant-id.",
11+
"The API Gateway triggers either the standard or the tenant isolated Lambda functions depending on the URI.",
12+
"Observe the counter variable value between standard and tenant isolation mode enabled Lambda functions are you invoke the APIs for different tenant."
13+
]
14+
},
15+
"gitHub": {
16+
"template": {
17+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-lambda-tenant-isolation",
18+
"templateURL": "serverless-patterns/apigw-lambda-tenant-isolation",
19+
"projectFolder": "apigw-lambda-tenant-isolation",
20+
"templateFile": "template.yaml"
21+
}
22+
},
23+
"resources": {
24+
"bullets": [
25+
{
26+
"text": "AWS Lambda tenant isolation",
27+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/tenant-isolation.html"
28+
},
29+
{
30+
"text": "AWS Blog - Building multi-tenant SaaS applications with AWS Lambda’s new tenant isolation mode",
31+
"link": "https://aws.amazon.com/blogs/compute/building-multi-tenant-saas-applications-with-aws-lambdas-new-tenant-isolation-mode/"
32+
}
33+
]
34+
},
35+
"deploy": {
36+
"text": [
37+
"sam build",
38+
"sam deploy --guided"
39+
]
40+
},
41+
"testing": {
42+
"text": [
43+
"See the GitHub repo for detailed testing instructions."
44+
]
45+
},
46+
"cleanup": {
47+
"text": [
48+
"Delete the stack: <code>sam delete</code>."
49+
]
50+
},
51+
"authors": [
52+
{
53+
"name": "Biswanath Mukherjee",
54+
"image": "https://serverlessland.com/assets/images/resources/contributors/biswanath-mukherjee.jpg",
55+
"bio": "I am a Sr. Solutions Architect working at AWS India. I help strategic global enterprise customer to architect their workload to run on AWS.",
56+
"linkedin": "biswanathmukherjee"
57+
}
58+
]
59+
}

0 commit comments

Comments
 (0)