diff --git a/sfn-bedrock-invokemodel-cdk/.gitignore b/sfn-bedrock-invokemodel-cdk/.gitignore
new file mode 100644
index 000000000..745e8db83
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/.gitignore
@@ -0,0 +1,6 @@
+*.js
+*.d.ts
+node_modules
+cdk.out
+cdk.context.json
+package-lock.json
diff --git a/sfn-bedrock-invokemodel-cdk/.npmignore b/sfn-bedrock-invokemodel-cdk/.npmignore
new file mode 100644
index 000000000..72b28b5da
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/.npmignore
@@ -0,0 +1,3 @@
+*.ts
+!*.d.ts
+cdk.out
diff --git a/sfn-bedrock-invokemodel-cdk/README.md b/sfn-bedrock-invokemodel-cdk/README.md
new file mode 100644
index 000000000..ffda40dc3
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/README.md
@@ -0,0 +1,83 @@
+# AWS Step Functions Express workflow with optimized integration for Amazon Bedrock InvokeModel
+
+This pattern deploys a Step Functions Express workflow that invokes Amazon Bedrock (Claude Sonnet) directly using the optimized integration. Deployed with AWS CDK.
+
+Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/sfn-bedrock-invokemodel-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
+- [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) installed
+- [Node.js](https://nodejs.org/) 20.x or later
+- [Amazon Bedrock model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) enabled for a model of your choice (Anthropic Claude Sonnet is the default in this pattern) in your AWS account
+
+## How it works
+
+Step Functions has an optimized integration with Amazon Bedrock that lets you call `bedrock:InvokeModel` directly from a workflow state. The optimized integration provides native error handling, automatic retries, and direct payload mapping without intermediate compute.
+
+**Key points:**
+- Uses `arn:aws:states:::bedrock:invokeModel` resource (optimized integration)
+- Express workflow for synchronous execution (lower cost, sub-5-minute executions)
+- Built-in retry with exponential backoff for transient failures
+- `resultSelector` extracts just the response text, model, and usage from the Bedrock response
+
+```
+┌──────────────────────┐ ┌──────────────────────┐
+│ │ │ │
+│ Step Functions │────────▶│ Amazon Bedrock │
+│ (Express) │ │ Claude Sonnet │
+│ │◀────────│ │
+└──────────────────────┘ └──────────────────────┘
+```
+
+## Deployment
+
+1. Install dependencies:
+ ```bash
+ cd sfn-bedrock-invokemodel-cdk
+ npm install
+ ```
+
+2. Deploy the stack:
+ ```bash
+ cdk deploy
+ ```
+
+## Testing
+
+Start a synchronous execution of the Express workflow:
+
+```bash
+aws stepfunctions start-sync-execution \
+ --state-machine-arn $(aws cloudformation describe-stacks \
+ --stack-name SfnBedrockInvokemodelStack \
+ --query 'Stacks[0].Outputs[?OutputKey==`StateMachineArn`].OutputValue' \
+ --output text) \
+ --input '{"prompt": "What are the benefits of Step Functions native Bedrock integration?"}' \
+ --query '{status: status, output: output}' \
+ --output json
+```
+
+The response includes the generated text, model ID, and token usage:
+
+```json
+{
+ "status": "SUCCEEDED",
+ "output": "{\"response\": \"...\", \"model\": \"claude-...\", \"usage\": {\"input_tokens\": 15, \"output_tokens\": 200}}"
+}
+```
+
+## Cleanup
+
+```bash
+cdk destroy
+```
+
+---
+
+Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+SPDX-License-Identifier: MIT-0
diff --git a/sfn-bedrock-invokemodel-cdk/bin/app.ts b/sfn-bedrock-invokemodel-cdk/bin/app.ts
new file mode 100644
index 000000000..dd601cf18
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/bin/app.ts
@@ -0,0 +1,7 @@
+#!/usr/bin/env node
+import "source-map-support/register";
+import * as cdk from "aws-cdk-lib";
+import { SfnBedrockInvokemodelStack } from "../lib/sfn-bedrock-invokemodel-stack";
+
+const app = new cdk.App();
+new SfnBedrockInvokemodelStack(app, "SfnBedrockInvokemodelStack");
diff --git a/sfn-bedrock-invokemodel-cdk/cdk.json b/sfn-bedrock-invokemodel-cdk/cdk.json
new file mode 100644
index 000000000..27fe6d2ec
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/cdk.json
@@ -0,0 +1,3 @@
+{
+ "app": "npx ts-node bin/app.ts"
+}
diff --git a/sfn-bedrock-invokemodel-cdk/example-pattern.json b/sfn-bedrock-invokemodel-cdk/example-pattern.json
new file mode 100644
index 000000000..fe0fe11e3
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/example-pattern.json
@@ -0,0 +1,52 @@
+{
+ "title": "AWS Step Functions Express integration with Amazon Bedrock InvokeModel",
+ "description": "Invoke Amazon Bedrock directly from Step Functions using the native InvokeModel optimized integration. Deployed with AWS CDK.",
+ "language": "TypeScript",
+ "level": "200",
+ "framework": "AWS CDK",
+ "introBox": {
+ "headline": "How it works",
+ "text": [
+ "This pattern deploys a Step Functions Express workflow that invokes Amazon Bedrock (Claude Sonnet) directly using the bedrock:InvokeModel optimized integration.",
+ "The optimized integration provides native error handling, automatic retries, and direct payload mapping without intermediate compute.",
+ "The workflow accepts a prompt string as input, sends it to Bedrock, and returns the generated response with usage metadata.",
+ "Built-in retry logic handles transient failures with exponential backoff."
+ ]
+ },
+ "gitHub": {
+ "template": {
+ "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/sfn-bedrock-invokemodel-cdk",
+ "templateURL": "serverless-patterns/sfn-bedrock-invokemodel-cdk",
+ "projectFolder": "sfn-bedrock-invokemodel-cdk",
+ "templateFile": "lib/sfn-bedrock-invokemodel-stack.ts"
+ }
+ },
+ "resources": {
+ "bullets": [
+ { "text": "Step Functions optimized integration for Amazon Bedrock", "link": "https://aws.amazon.com/about-aws/whats-new/2023/11/aws-step-functions-optimized-integration-bedrock/" },
+ { "text": "Build generative AI apps using Step Functions and Bedrock", "link": "https://aws.amazon.com/blogs/aws/build-generative-ai-apps-using-aws-step-functions-and-amazon-bedrock/" },
+ { "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": "sfn", "label": "Step Functions" },
+ "icon2": { "x": 80, "y": 50, "service": "bedrock", "label": "Amazon Bedrock" },
+ "line1": { "from": "icon1", "to": "icon2" }
+ }
+}
diff --git a/sfn-bedrock-invokemodel-cdk/lib/sfn-bedrock-invokemodel-stack.ts b/sfn-bedrock-invokemodel-cdk/lib/sfn-bedrock-invokemodel-stack.ts
new file mode 100644
index 000000000..3822b76d5
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/lib/sfn-bedrock-invokemodel-stack.ts
@@ -0,0 +1,88 @@
+import * as cdk from "aws-cdk-lib";
+import * as sfn from "aws-cdk-lib/aws-stepfunctions";
+import * as tasks from "aws-cdk-lib/aws-stepfunctions-tasks";
+import * as bedrock from "aws-cdk-lib/aws-bedrock";
+import * as logs from "aws-cdk-lib/aws-logs";
+import * as iam from "aws-cdk-lib/aws-iam";
+import { Construct } from "constructs";
+
+export class SfnBedrockInvokemodelStack 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",
+ });
+
+ // Construct inference profile ARN for the model
+ const inferenceProfileArn = `arn:aws:bedrock:${this.region}:${this.account}:inference-profile/${modelId.valueAsString}`;
+ const model = bedrock.ProvisionedModel.fromProvisionedModelArn(
+ this,
+ "Model",
+ inferenceProfileArn
+ );
+
+ // Step Functions task: invoke Bedrock directly (no Lambda needed)
+ const invokeModel = new tasks.BedrockInvokeModel(this, "InvokeModel", {
+ model,
+ body: sfn.TaskInput.fromObject({
+ anthropic_version: "bedrock-2023-05-31",
+ max_tokens: 1024,
+ messages: [
+ {
+ role: "user",
+ content: sfn.JsonPath.stringAt("$.prompt"),
+ },
+ ],
+ }),
+ resultSelector: {
+ "response.$": "$.Body.content[0].text",
+ "model.$": "$.Body.model",
+ "usage.$": "$.Body.usage",
+ },
+ });
+
+ // Add retry for transient failures
+ invokeModel.addRetry({
+ errors: ["States.TaskFailed"],
+ interval: cdk.Duration.seconds(20),
+ maxAttempts: 3,
+ backoffRate: 2,
+ });
+
+ const logGroup = new logs.LogGroup(this, "LogGroup", {
+ logGroupName: "/aws/stepfunctions/sfn-bedrock-invokemodel",
+ retention: logs.RetentionDays.TWO_WEEKS,
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
+ });
+
+ const stateMachine = new sfn.StateMachine(this, "StateMachine", {
+ stateMachineName: "sfn-bedrock-invokemodel",
+ definitionBody: sfn.DefinitionBody.fromChainable(invokeModel),
+ stateMachineType: sfn.StateMachineType.EXPRESS,
+ timeout: cdk.Duration.minutes(5),
+ logs: {
+ destination: logGroup,
+ level: sfn.LogLevel.ALL,
+ includeExecutionData: true,
+ },
+ });
+
+ // Grant Bedrock access (inference profile + foundation model)
+ stateMachine.addToRolePolicy(
+ new iam.PolicyStatement({
+ actions: ["bedrock:InvokeModel"],
+ resources: [
+ `arn:aws:bedrock:${this.region}:${this.account}:inference-profile/${modelId.valueAsString}`,
+ "arn:aws:bedrock:*::foundation-model/*",
+ ],
+ })
+ );
+
+ new cdk.CfnOutput(this, "StateMachineArn", { value: stateMachine.stateMachineArn });
+ new cdk.CfnOutput(this, "StateMachineName", { value: stateMachine.stateMachineName! });
+ new cdk.CfnOutput(this, "LogGroupName", { value: logGroup.logGroupName });
+ }
+}
diff --git a/sfn-bedrock-invokemodel-cdk/package.json b/sfn-bedrock-invokemodel-cdk/package.json
new file mode 100644
index 000000000..54e8c47bc
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "sfn-bedrock-invokemodel-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"
+ }
+}
diff --git a/sfn-bedrock-invokemodel-cdk/tsconfig.json b/sfn-bedrock-invokemodel-cdk/tsconfig.json
new file mode 100644
index 000000000..5a9a7d6dd
--- /dev/null
+++ b/sfn-bedrock-invokemodel-cdk/tsconfig.json
@@ -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"]
+}