From 8ec21130abd0062c140d0f45f11ffe09f3951d5c Mon Sep 17 00:00:00 2001 From: Kaustav Dey Date: Tue, 31 Dec 2024 16:03:16 -0500 Subject: [PATCH] Making the code AWS region agnostic --- .../README.md | 8 +++++--- ...rock-async-stream-subscription-cdk-stack.ts | 18 +++++++++++++----- .../lib/lambda/invocation/index.ts | 5 ++++- .../test/test.ts | 2 -- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/appsync-lambda-bedrock-async-stream-subscription-cdk/README.md b/appsync-lambda-bedrock-async-stream-subscription-cdk/README.md index 0a6ad478a..148672c83 100644 --- a/appsync-lambda-bedrock-async-stream-subscription-cdk/README.md +++ b/appsync-lambda-bedrock-async-stream-subscription-cdk/README.md @@ -2,7 +2,7 @@ This pattern demonstrates how to implement [long-running invocations](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html#long-running-invocations) with Amazon Bedrock using AWS AppSync subscriptions and AWS Lambda in Event Mode, following the official AWS AppSync documentation pattern. -Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/appsync-lambda-bedrock-async-stream-subscription-cdk +Learn more about this pattern at [Serverless Land Patterns](https://serverlessland.com/patterns/appsync-lambda-bedrock-async-stream-subscription-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. @@ -13,7 +13,7 @@ Important: this application uses various AWS services and there are costs associ * [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) * [Node and NPM](https://nodejs.org/en/download/) installed * [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html) (AWS CDK) installed -* Make sure to enable the **Anthropic - Claude Sonnet 3.5 V2** model on the [Bedrock console](https://console.aws.amazon.com/bedrock/home#/modelaccess). +* Enable the **Anthropic - Claude Sonnet 3.5 V2** model in **us-east-1** region through the [Bedrock console](https://console.aws.amazon.com/bedrock/home#/modelaccess). This implementation uses the [cross-region inference profile](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html#inference-profiles-support-system) from us-east-1. ## How it works @@ -75,7 +75,6 @@ After deployment, you can test the Bedrock streaming integration using the provi Open test/test.ts Replace APPSYNC_API_URL with the API URL from stack outputs Replace APPSYNC_API_KEY with the API Key from stack outputs - Replace the REGION with your AWS Account Region ``` 2. Run the test: @@ -105,6 +104,8 @@ chunk: 'up everything!' } ``` +If you do not receive any response, please check your Bedrock Model access for Claude Sonnet 3.5 V2 in us-east-1 region. + 4. Stop the test: ```sh Press Ctrl+C to terminate the process @@ -127,3 +128,4 @@ Solution Architect Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0 + diff --git a/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/appsync-lambda-bedrock-async-stream-subscription-cdk-stack.ts b/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/appsync-lambda-bedrock-async-stream-subscription-cdk-stack.ts index fb6cecb5d..59a25375e 100644 --- a/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/appsync-lambda-bedrock-async-stream-subscription-cdk-stack.ts +++ b/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/appsync-lambda-bedrock-async-stream-subscription-cdk-stack.ts @@ -9,7 +9,13 @@ import * as path from 'path'; export class AppsyncLambdaBedrockAsyncStreamSubscriptionCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { - super(scope, id, props); + super(scope, id, { + ...props, + env: { + account: process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_DEFAULT_REGION, + }, + }); const api = new appsync.GraphqlApi(this, 'Api', { name: 'bedrock-streaming-api', @@ -47,14 +53,14 @@ export class AppsyncLambdaBedrockAsyncStreamSubscriptionCdkStack extends cdk.Sta }); - // Add Bedrock permissions to Lambda + // Add Bedrock permissions to Lambda. Add IAM policies for all regions covered under the Inference profile invocationHandler.addToRolePolicy(new iam.PolicyStatement({ actions: ['bedrock:InvokeModelWithResponseStream'], resources: [ 'arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', 'arn:aws:bedrock:us-east-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', - 'arn:aws:bedrock:us-east-1:275631959608:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0' + `arn:aws:bedrock:us-east-1:${this.account}:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0` ] })); @@ -67,12 +73,14 @@ export class AppsyncLambdaBedrockAsyncStreamSubscriptionCdkStack extends cdk.Sta // Add CloudWatch Logs permissions to Lambda invocationHandler.addToRolePolicy(new iam.PolicyStatement({ actions: [ - 'logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents' ], - resources: ['*'] + resources: [ + `arn:aws:logs:${this.region}:${this.account}:log-group:/aws/lambda/*` + ] })); + const invocationDS = api.addLambdaDataSource('InvocationDataSource', invocationHandler); diff --git a/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/lambda/invocation/index.ts b/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/lambda/invocation/index.ts index 723bf7d12..cdfdfb7d3 100644 --- a/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/lambda/invocation/index.ts +++ b/appsync-lambda-bedrock-async-stream-subscription-cdk/lib/lambda/invocation/index.ts @@ -29,7 +29,10 @@ export const handler = async (event: Event) => { console.log(`Starting Bedrock stream for conversationId: ${conversationId}`); - const bedrockClient = new BedrockRuntimeClient({}); + // Using the us-east-1 Bedrock Inference Profile for Claude Sonnet 3.5 V2 + const bedrockClient = new BedrockRuntimeClient({ + region: 'us-east-1' + }); const graphQLClient = new GraphQLClient(process.env.APPSYNC_ENDPOINT!, { headers: { 'x-api-key': process.env.APPSYNC_API_KEY! }, }); diff --git a/appsync-lambda-bedrock-async-stream-subscription-cdk/test/test.ts b/appsync-lambda-bedrock-async-stream-subscription-cdk/test/test.ts index d14b124f6..e030be89c 100644 --- a/appsync-lambda-bedrock-async-stream-subscription-cdk/test/test.ts +++ b/appsync-lambda-bedrock-async-stream-subscription-cdk/test/test.ts @@ -5,14 +5,12 @@ import { generateClient } from 'aws-amplify/api'; const APPSYNC_API_URL = ''; const APPSYNC_API_KEY = ''; -const REGION = '' // Configure Amplify Amplify.configure({ API: { GraphQL: { endpoint: APPSYNC_API_URL, - region: REGION, defaultAuthMode: 'apiKey', apiKey: APPSYNC_API_KEY }