Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lambda-managed-instances-bedrock-cdk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.js
!src/*.js
*.d.ts
node_modules
cdk.out
package-lock.json
3 changes: 3 additions & 0 deletions lambda-managed-instances-bedrock-cdk/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.ts
!*.d.ts
cdk.out
76 changes: 76 additions & 0 deletions lambda-managed-instances-bedrock-cdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Lambda Managed Instances with Amazon Bedrock

This pattern deploys a Lambda function on [Managed Instances](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html) (EC2-backed compute) that invokes Amazon Bedrock (Claude) for text generation.

Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/lambda-managed-instances-bedrock-cdk

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.

## Requirements

* [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.
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [Node and NPM](https://nodejs.org/en/download/) installed
* [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) installed

## How it works

Lambda Managed Instances combine EC2 flexibility with serverless simplicity:

- **EC2-backed compute**: Your function runs on dedicated EC2 instances in your VPC
- **Serverless management**: AWS handles provisioning, scaling, OS patching, and load balancing
- **Cost optimization**: Use Compute Savings Plans and Reserved Instances for Lambda workloads
- **Specialized hardware**: Access Graviton, GPU, and network-optimized instance types

This pattern adds Bedrock integration to demonstrate a real-world use case beyond hello-world.

## Architecture

```
User → Lambda Function (on Managed Instances / EC2)
├── VPC with private subnets
├── CapacityProvider (ARM64)
└── Bedrock InvokeModel → Claude response
```

## Deployment Instructions

1. Clone the repository and navigate to the pattern directory:
```bash
git clone https://github.com/aws-samples/serverless-patterns
cd serverless-patterns/lambda-managed-instances-bedrock-cdk
```

2. Install dependencies:
```bash
npm install
```

3. Deploy the stack:
```bash
cdk deploy
```

## Testing

Invoke the function:

```bash
aws lambda invoke \
--function-name managed-instances-bedrock-cdk \
--payload '{"prompt":"Explain Lambda Managed Instances in 3 sentences"}' \
--cli-binary-format raw-in-base64-out \
output.json && cat output.json | python3 -m json.tool
```

## Cleanup

```bash
cdk destroy
```

----
Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.

SPDX-License-Identifier: MIT-0
7 changes: 7 additions & 0 deletions lambda-managed-instances-bedrock-cdk/bin/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { LambdaManagedInstancesBedrockStack } from "../lib/lambda-managed-instances-bedrock-stack";

const app = new cdk.App();
new LambdaManagedInstancesBedrockStack(app, "LambdaManagedInstancesBedrockStack");
3 changes: 3 additions & 0 deletions lambda-managed-instances-bedrock-cdk/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"app": "npx ts-node bin/app.ts"
}
51 changes: 51 additions & 0 deletions lambda-managed-instances-bedrock-cdk/example-pattern.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"title": "Lambda Managed Instances with Amazon Bedrock",
"description": "Run Amazon Bedrock model invocations on Lambda Managed Instances (EC2-backed compute) using AWS CDK, combining serverless simplicity with EC2 flexibility.",
"language": "TypeScript",
"level": "200",
"framework": "CDK",
"introBox": {
"headline": "How it works",
"text": [
"This pattern deploys a Lambda function on Managed Instances (EC2-backed compute) that invokes Amazon Bedrock (Claude) for text generation.",
"Lambda Managed Instances provide EC2 flexibility (Graviton, GPU, specialized hardware) with serverless operational simplicity — AWS handles provisioning, scaling, and maintenance.",
"The function runs on dedicated EC2 capacity in your VPC via a CapacityProvider, enabling access to EC2 pricing models (Savings Plans, Reserved Instances) while maintaining the Lambda programming model."
]
},
"gitHub": {
"template": {
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/lambda-managed-instances-bedrock-cdk",
"templateURL": "serverless-patterns/lambda-managed-instances-bedrock-cdk",
"projectFolder": "lambda-managed-instances-bedrock-cdk",
"templateFile": "lib/lambda-managed-instances-bedrock-stack.ts"
}
},
"resources": {
"bullets": [
{ "text": "Lambda Managed Instances documentation", "link": "https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html" },
{ "text": "Lambda Managed Instances launch blog", "link": "https://aws.amazon.com/blogs/aws/introducing-aws-lambda-managed-instances-serverless-simplicity-with-ec2-flexibility/" },
{ "text": "Amazon Bedrock documentation", "link": "https://docs.aws.amazon.com/bedrock/latest/userguide/" }
]
},
"deploy": {
"text": ["cdk deploy"]
},
"testing": {
"text": ["See the README for testing instructions."]
},
"cleanup": {
"text": ["cdk destroy"]
},
"authors": [
{
"name": "Nithin Chandran R",
"bio": "Technical Account Manager at AWS",
"linkedin": "nithin-chandran-r"
}
],
"patternArch": {
"icon1": { "x": 20, "y": 50, "service": "lambda", "label": "Lambda (Managed Instances)" },
"icon2": { "x": 80, "y": 50, "service": "bedrock", "label": "Amazon Bedrock" },
"line1": { "from": "icon1", "to": "icon2" }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as cdk from "aws-cdk-lib";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as iam from "aws-cdk-lib/aws-iam";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as logs from "aws-cdk-lib/aws-logs";
import { Construct } from "constructs";

export class LambdaManagedInstancesBedrockStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const modelId = new cdk.CfnParameter(this, "BedrockModelId", {
type: "String",
default: "us.anthropic.claude-sonnet-4-20250514-v1:0",
description: "Bedrock inference profile model ID",
});

const functionName = "managed-instances-bedrock-cdk";

const logGroup = new logs.LogGroup(this, "LogGroup", {
logGroupName: `/aws/lambda/${functionName}`,
retention: logs.RetentionDays.TWO_WEEKS,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});

const fn = new lambda.Function(this, "BedrockFn", {
runtime: lambda.Runtime.NODEJS_24_X,
handler: "index.handler",
code: lambda.Code.fromAsset("src"),
timeout: cdk.Duration.minutes(5),
memorySize: 2048, // Managed Instances require >= 2048 MB
architecture: lambda.Architecture.ARM_64,
functionName,
description: "Bedrock invocation on Lambda Managed Instances (EC2-backed)",
loggingFormat: lambda.LoggingFormat.JSON,
logGroup,
environment: { MODEL_ID: modelId.valueAsString },
});

fn.addToRolePolicy(
new iam.PolicyStatement({
actions: ["bedrock:InvokeModel"],
resources: [
`arn:aws:bedrock:${this.region}:${this.account}:inference-profile/${modelId.valueAsString}`,
"arn:aws:bedrock:*::foundation-model/*",
],
})
);

// Lambda Managed Instances: EC2-backed compute with serverless management
const vpc = new ec2.Vpc(this, "ManagedInstancesVpc", {
maxAzs: 2,
natGateways: 1,
});

const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
vpc,
description: "Lambda Managed Instances security group",
});

const capacityProvider = new lambda.CapacityProvider(this, "CapacityProvider", {
capacityProviderName: "bedrock-capacity-provider",
subnets: vpc.privateSubnets,
securityGroups: [securityGroup],
architectures: [lambda.Architecture.ARM_64],
});

capacityProvider.addFunction(fn);

new cdk.CfnOutput(this, "FunctionName", { value: fn.functionName });
new cdk.CfnOutput(this, "FunctionArn", { value: fn.functionArn });
new cdk.CfnOutput(this, "LogGroupName", { value: logGroup.logGroupName });
}
}
15 changes: 15 additions & 0 deletions lambda-managed-instances-bedrock-cdk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "lambda-managed-instances-bedrock-cdk",
"version": "1.0.0",
"bin": { "app": "bin/app.ts" },
"scripts": { "build": "tsc", "cdk": "cdk" },
"dependencies": {
"aws-cdk-lib": "2.236.0",
"constructs": "10.4.2"
},
"devDependencies": {
"@types/node": "^22.0.0",
"ts-node": "^10.9.0",
"typescript": "~5.7.0"
}
}
33 changes: 33 additions & 0 deletions lambda-managed-instances-bedrock-cdk/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { BedrockRuntimeClient, InvokeModelCommand } = require("@aws-sdk/client-bedrock-runtime");

const client = new BedrockRuntimeClient();
const MODEL_ID = process.env.MODEL_ID;

exports.handler = async (event) => {
const prompt = event.prompt || "What are the benefits of Lambda Managed Instances?";

const res = await client.send(
new InvokeModelCommand({
modelId: MODEL_ID,
contentType: "application/json",
accept: "application/json",
body: JSON.stringify({
anthropic_version: "bedrock-2023-05-31",
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
}),
})
);

const body = JSON.parse(new TextDecoder().decode(res.body));

return {
statusCode: 200,
body: JSON.stringify({
prompt,
response: body.content[0].text,
model: MODEL_ID,
usage: body.usage,
}),
};
};
22 changes: 22 additions & 0 deletions lambda-managed-instances-bedrock-cdk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["es2020"],
"declaration": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": false,
"inlineSourceMap": true,
"inlineSources": true,
"experimentalDecorators": true,
"strictPropertyInitialization": false
},
"exclude": ["cdk.out"]
}