Skip to content

Commit d2f641a

Browse files
authored
Merge pull request aws-samples#2885 from DmitryGulin/pattern/lambda-managed-instances-cdk
add a simplistic `lambda-managed-instances-cdk` pattern
2 parents 44de28d + 73bffc3 commit d2f641a

13 files changed

Lines changed: 763 additions & 0 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
*.js
2+
!jest.config.js
3+
*.d.ts
4+
node_modules
5+
6+
# CDK asset staging directory
7+
.cdk.staging
8+
cdk.out
9+
10+
# Parcel default cache directory
11+
.parcel-cache
12+
13+
# npm
14+
.npm
15+
16+
# yarn
17+
.yarn
18+
19+
# IDE
20+
.vscode/
21+
.idea/
22+
23+
# OS
24+
.DS_Store
25+
Thumbs.db
26+
27+
# Logs
28+
*.log
29+
30+
# Runtime data
31+
pids
32+
*.pid
33+
*.seed
34+
*.pid.lock
35+
36+
# Coverage directory used by tools like istanbul
37+
coverage
38+
*.lcov
39+
40+
# nyc test coverage
41+
.nyc_output
42+
43+
# Dependency directories
44+
node_modules/
45+
jspm_packages/
46+
47+
# Optional npm cache directory
48+
.npm
49+
50+
# Optional eslint cache
51+
.eslintcache
52+
53+
# Output of 'npm pack'
54+
*.tgz
55+
56+
# Yarn Integrity file
57+
.yarn-integrity
58+
59+
# dotenv environment variables file
60+
.env
61+
.env.test
62+
63+
# parcel-bundler cache (https://parceljs.org/)
64+
.cache
65+
.parcel-cache
66+
67+
# next.js build output
68+
.next
69+
70+
# nuxt.js build output
71+
.nuxt
72+
73+
# vuepress build output
74+
.vuepress/dist
75+
76+
# Serverless directories
77+
.serverless/
78+
79+
# FuseBox cache
80+
.fusebox/
81+
82+
# DynamoDB Local files
83+
.dynamodb/
84+
85+
# TernJS port file
86+
.tern-port
87+
88+
# CDK Context & Staging files
89+
.cdk.staging/
90+
cdk.out/
91+
cdk.context.json
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.ts
2+
!*.d.ts
3+
4+
# CDK asset staging directory
5+
.cdk.staging
6+
cdk.out
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Hello World on AWS Lambda Managed Instances
2+
3+
This pattern demonstrates how to deploy a simple Hello World Lambda function running on AWS Lambda Managed Instances using AWS CDK. AWS Lambda Managed Instances enables you to run Lambda functions on EC2 instances while maintaining Lambda's operational simplicity. It fully manages infrastructure tasks including instance lifecycle, OS and runtime patching, routing, load balancing, and auto scaling.
4+
5+
Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/lambda-managed-instances-cdk
6+
7+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
8+
9+
**Note**: AWS Lambda Managed Instances provision EC2 instances that are **NOT eligible for the AWS Free Tier**. These instances will incur charges immediately upon deployment, regardless of your Free Tier status.
10+
11+
## Requirements
12+
13+
* [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.
14+
* [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) (latest available version) installed and configured
15+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
16+
* [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html) (version 2.232.0 or later) installed and configured
17+
* [Node.js](https://nodejs.org/) (version 24.x or later)
18+
19+
## Deployment Instructions
20+
21+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
22+
```
23+
git clone https://github.com/aws-samples/serverless-patterns
24+
```
25+
1. Change directory to the pattern directory:
26+
```
27+
cd lambda-managed-instances-cdk
28+
```
29+
1. Install the project dependencies:
30+
```
31+
npm install
32+
```
33+
1. Deploy the CDK stack:
34+
```
35+
cdk deploy
36+
```
37+
Note: This stack will deploy to your default AWS region. Please refer to the [AWS capabilities explorer](https://builder.aws.com/build/capabilities/explore) for feature availability in your desired region.
38+
39+
1. Note the outputs from the CDK deployment process. These contain the resource names and/or ARNs which are used for testing.
40+
41+
## How it works
42+
43+
This pattern creates a capacity provider with VPC and security group configuration, then deploys a Node.js Lambda function (ARM64 architecture) that is associated with the capacity provider to run on managed EC2 instances. The function accepts an event with a name parameter and returns a greeting message, with execution logs captured in a dedicated CloudWatch log group.
44+
45+
## Testing
46+
47+
After deployment, you can test the Lambda function using AWS CLI or AWS Console.
48+
49+
### AWS CLI Testing
50+
51+
1. **Basic function invocation**:
52+
```bash
53+
aws lambda invoke \
54+
--function-name hello-world-managed-instances-cdk \
55+
--payload file://events/hello-world.json \
56+
--cli-binary-format raw-in-base64-out \
57+
response.json
58+
```
59+
60+
2. **View the response**:
61+
```bash
62+
cat response.json
63+
```
64+
65+
3. **Custom name invocation**:
66+
```bash
67+
echo '{"name":"Lambda Managed Instances"}' | aws lambda invoke \
68+
--function-name hello-world-managed-instances-cdk \
69+
--payload file:///dev/stdin \
70+
--cli-binary-format raw-in-base64-out \
71+
custom-response.json
72+
```
73+
74+
4. **View CloudWatch logs**:
75+
```bash
76+
aws logs filter-log-events \
77+
--log-group-name /demo/lambda/hello-world-managed-instances-cdk \
78+
--start-time $(date -d '5 minutes ago' +%s)000
79+
```
80+
81+
### AWS Console Testing
82+
83+
1. Navigate to the Lambda service in the AWS Console
84+
2. Find the function named `hello-world-managed-instances-cdk`
85+
3. Create a test event using the payload from `events/hello-world.json` or create a custom payload:
86+
```json
87+
{
88+
"name": "Your Custom Name"
89+
}
90+
```
91+
4. Execute the test and observe the results in the execution logs
92+
93+
### Expected Response
94+
95+
The function returns a JSON response with the following structure:
96+
97+
```json
98+
{
99+
"response": "Hello AWS Lambda on Managed Instances"
100+
}
101+
```
102+
103+
### Monitoring and Observability
104+
105+
Monitor the function execution through:
106+
- **CloudWatch Logs**: Detailed execution logs with event and response data in the dedicated log group
107+
- **Lambda Metrics**: Function performance and invocation statistics
108+
- **CloudWatch Metrics**: Custom metrics and alarms for monitoring
109+
110+
The stack outputs include the log group name for easy reference when setting up monitoring dashboards or log analysis tools.
111+
112+
## Inspecting AWS Lambda Managed Instances Infrastructure
113+
114+
AWS Lambda Managed Instances provision EC2 instances behind the scenes to run your Lambda functions. You can inspect this infrastructure using AWS CLI commands:
115+
116+
### View Capacity Provider Details
117+
118+
```bash
119+
aws lambda get-capacity-provider --capacity-provider-name lambda-capacity-provider-cdk
120+
```
121+
122+
This shows:
123+
- Capacity provider ARN and state
124+
- VPC configuration (subnets and security groups)
125+
- Instance requirements (architecture, scaling mode)
126+
- IAM roles and permissions
127+
128+
### List Associated EC2 Instances
129+
130+
```bash
131+
aws ec2 describe-instances \
132+
--filters "Name=tag:aws:lambda:capacity-provider,Values=arn:aws:lambda:*:capacity-provider:lambda-capacity-provider-cdk" \
133+
--query 'Reservations[*].Instances[*].[InstanceId,InstanceType,State.Name,LaunchTime,SubnetId,PrivateIpAddress]' \
134+
--output table
135+
```
136+
137+
This displays:
138+
- Instance IDs and types
139+
- Current state (running, pending, terminated)
140+
- Launch times and subnet distribution
141+
- Private IP addresses within the VPC
142+
143+
**Note**: For a complete list of supported EC2 instance types for AWS Lambda Managed Instances and their pricing, see the [AWS Lambda Pricing page](https://aws.amazon.com/lambda/pricing/).
144+
145+
### Understanding Instance Behavior
146+
147+
**Auto-scaling**: Instances are automatically created and terminated based on function demand
148+
- **Scale-up**: New instances launch when function invocation increases
149+
- **Scale-down**: Unused instances terminate after periods of low activity
150+
- **Multi-AZ**: Instances are distributed across availability zones for high availability
151+
152+
**Instance Lifecycle**:
153+
- Instances typically launch within 1-2 minutes of stack deployment
154+
- They remain running to provide immediate function execution
155+
- AWS manages all instance lifecycle operations automatically
156+
157+
### Automated Testing
158+
159+
The included test script (`./test-lambda.sh`) automatically inspects both the capacity provider and EC2 instances, providing a comprehensive view of the managed instances infrastructure.
160+
161+
## Regional Availability
162+
163+
This stack will deploy to your default AWS region. Before deploying, please verify that AWS Lambda Managed Instances feature is available in your target region by using the [AWS capabilities explorer](https://builder.aws.com/build/capabilities/explore) or consulting the official [AWS Lambda Managed Instances documentation](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html).
164+
165+
## Cleanup
166+
167+
1. Delete the stack
168+
```bash
169+
cdk destroy
170+
```
171+
1. Confirm the stack has been deleted by checking the AWS CloudFormation console or running:
172+
```bash
173+
aws cloudformation describe-stacks --stack-name lambda-managed-instances-cdk
174+
```
175+
176+
----
177+
Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
178+
179+
SPDX-License-Identifier: MIT-0
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env node
2+
import { App } from 'aws-cdk-lib/core';
3+
import { DemoStack } from '../lib/demo-stack';
4+
5+
const app = new App();
6+
new DemoStack(app, 'LambdaManagedInstancesDemo', {
7+
stackName: 'lambda-managed-instances-cdk',
8+
env: {
9+
account: process.env.CDK_DEFAULT_ACCOUNT,
10+
region: process.env.CDK_DEFAULT_REGION
11+
},
12+
description: 'Simple Hello World Lambda function running on Lambda Managed Instances',
13+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"app": "npx ts-node --prefer-ts-exts bin/app.ts",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"**/*.d.ts",
11+
"**/*.js",
12+
"tsconfig.json",
13+
"package*.json",
14+
"yarn.lock",
15+
"node_modules",
16+
"test"
17+
]
18+
},
19+
"context": {
20+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21+
"@aws-cdk/core:checkSecretUsage": true,
22+
"@aws-cdk/core:target-partitions": [
23+
"aws",
24+
"aws-cn"
25+
],
26+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
27+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
28+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
29+
"@aws-cdk/aws-iam:minimizePolicies": true,
30+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
31+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
32+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
33+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
34+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
35+
"@aws-cdk/core:enablePartitionLiterals": true,
36+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
37+
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
38+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
39+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
40+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
41+
"@aws-cdk/aws-route53-patters:useCertificate": true,
42+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
43+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
44+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
45+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
46+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
47+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
48+
"@aws-cdk/aws-redshift:columnId": true,
49+
"@aws-cdk/aws-stepfunctions-tasks:enableLogging": true,
50+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
51+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
52+
"@aws-cdk/aws-kms:aliasNameRef": true,
53+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
54+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
55+
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
56+
"@aws-cdk/aws-opensearchservice:enableLogging": true,
57+
"@aws-cdk/aws-normlizer:disable": true,
58+
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
59+
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
60+
"@aws-cdk/core:stackRelativeExports": true,
61+
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
62+
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
63+
"@aws-cdk/aws-rds:generateSecretManagerSecretName": true,
64+
"@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": true,
65+
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
66+
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
67+
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
68+
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForSourceAction": true
69+
}
70+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "AWS Lambda on Managed Instances"
3+
}

0 commit comments

Comments
 (0)