Skip to content

Commit 0f885fa

Browse files
committed
Update integ test roles, run against Bedrock in us-east-2
1 parent b35ea79 commit 0f885fa

File tree

8 files changed

+79
-60
lines changed

8 files changed

+79
-60
lines changed

.github/workflows/integ-tests.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,7 @@ jobs:
4949

5050
- name: Clean up
5151
if: always()
52-
run: ./e2e_tests/clean_up_integ_test.sh
52+
run: |
53+
source src/python/.venv/bin/activate
54+
./e2e_tests/clean_up_integ_test.sh
5355
working-directory: ${{ github.workspace }}

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ await this.client.connect(transport);
178178

179179
First, install the [AWS CDK CLI](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install).
180180

181+
Request [Bedrock model access](https://us-east-2.console.aws.amazon.com/bedrock/home?region=us-east-2#/modelaccess)
182+
to Anthropic Claude 3.5 Sonnet v2 in region us-east-2.
183+
181184
Install the mcp-lambda Python module from source:
182185

183186
```bash
@@ -194,7 +197,7 @@ uv run pyright
194197
uv run pytest
195198
```
196199

197-
Create an IAM role for the example Lambda functions:
200+
Create an IAM role for the example Lambda functions and bootstrap the account for CDK:
198201

199202
```bash
200203
aws iam create-role \
@@ -204,6 +207,8 @@ aws iam create-role \
204207
aws iam attach-role-policy \
205208
--role-name mcp-lambda-example-servers \
206209
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
210+
211+
cdk bootstrap aws://<aws account id>/us-east-2
207212
```
208213

209214
Deploy the Lambda 'time' function - the deployed function will be named "mcp-server-time".
@@ -213,8 +218,6 @@ cd examples/servers/time/
213218

214219
uv pip install -r requirements.txt
215220

216-
cdk bootstrap aws://<aws account id>/us-east-2
217-
218221
cdk deploy --app 'python3 cdk_stack.py'
219222
```
220223

@@ -241,8 +244,6 @@ npm link mcp-lambda
241244

242245
npm run build
243246

244-
cdk bootstrap aws://<aws account id>/us-east-2
245-
246247
cdk deploy --app 'node lib/weather-alerts-mcp-server.js'
247248
```
248249

e2e_tests/python/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Configuration:
2525
def __init__(
2626
self,
2727
model_id="anthropic.claude-3-5-sonnet-20241022-v2:0",
28-
region="us-west-2",
28+
region="us-east-2",
2929
) -> None:
3030
"""Initialize configuration."""
3131
self.model_id = model_id

e2e_tests/setup/integ-test-authentication.yaml

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
# This CloudFormation template configures an IAM identity provider that uses GitHub's OIDC,
22
# enabling GitHub Actions to run the integration tests against the AWS account where this
33
# template is deployed.
4-
# aws cloudformation deploy \
5-
# --template-file integ-test-authentication.yaml \
6-
# --stack-name github-integ-test-identity-provider \
7-
# --parameter-overrides GitHubOrg=awslabs RepositoryName=utilities-for-model-context-protocol-with-aws-lambda \
8-
# --capabilities CAPABILITY_NAMED_IAM \
9-
# --region us-east-2 \
10-
# --profile mcp-lambda-cfn-integ-test-account
114

125
Parameters:
136
GitHubOrg:
@@ -69,58 +62,33 @@ Resources:
6962
# Allow integration tests to manage CloudFormation stacks to deploy the example MCP servers
7063
- Effect: Allow
7164
Action:
72-
- "cloudformation:ContinueUpdateRollback"
73-
- "cloudformation:CreateChangeSet"
74-
- "cloudformation:DeleteChangeSet"
75-
- "cloudformation:DeleteStack"
76-
- "cloudformation:DescribeChangeSet"
77-
- "cloudformation:DescribeStacks"
78-
- "cloudformation:ExecuteChangeSet"
65+
- "cloudformation:*"
7966
Resource:
8067
- !Sub "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/LambdaMcpServer-*"
8168
- Effect: Allow
8269
Action:
8370
- "ssm:GetParameter"
71+
- "ssm:GetParameters"
8472
Resource:
8573
- !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/cdk-bootstrap/*/version"
86-
# Allow CloudFormation to provision the resources for the example MCP servers
87-
- Effect: Allow
88-
Action:
89-
- "lambda:*"
90-
- "logs:*"
91-
Resource: "*"
92-
Condition:
93-
"ForAnyValue:StringEquals":
94-
"aws:CalledVia":
95-
- cloudformation.amazonaws.com
9674
- Effect: Allow
9775
Action:
9876
- "iam:PassRole"
9977
Resource:
100-
- !GetAtt LambdaFunctionsRole.Arn
101-
Condition:
102-
"ForAnyValue:StringEquals":
103-
"aws:CalledVia":
104-
- cloudformation.amazonaws.com
105-
# Allow integration tests to upload templates and assets to the CDK bucket
78+
- !Sub "arn:aws:iam::${AWS::AccountId}:role/cdk-*-cfn-exec-role-${AWS::AccountId}-${AWS::Region}"
79+
# Allow CDK to manage templates and assets in the CDK bucket
10680
- Effect: Allow
10781
Action:
10882
- "s3:PutObject"
10983
- "s3:AbortMultipartUpload"
11084
- "s3:ListMultipartUploadParts"
111-
Resource:
112-
- "arn:aws:s3:::cdk*/*"
113-
# Allow CloudFormation and Lambda to download templates and assets from the CDK bucket
114-
- Effect: Allow
115-
Action:
11685
- "s3:GetObject"
11786
- "s3:GetObjectVersion"
87+
- "s3:ListBucket"
88+
- "s3:GetBucketLocation"
89+
- "s3:GetEncryptionConfiguration"
11890
Resource:
119-
- "arn:aws:s3:::cdk*/*"
120-
Condition:
121-
"ForAnyValue:StringEquals":
122-
"aws:CalledVia":
123-
- cloudformation.amazonaws.com
91+
- "arn:aws:s3:::cdk*"
12492
# Allow integration tests to invoke Lambda functions and Bedrock models
12593
- Effect: Allow
12694
Action:
@@ -135,6 +103,38 @@ Resources:
135103
Roles:
136104
- !Ref IntegrationTestRole
137105

106+
# CDK will bootstrap a role with this policy, and will set it
107+
# as the role for all deployed CloudFormation stacks
108+
CdkCfnExecutionPolicy:
109+
Type: "AWS::IAM::ManagedPolicy"
110+
Properties:
111+
ManagedPolicyName: mcp-lambda-integ-test-cdk-cfn-execution
112+
PolicyDocument:
113+
Version: "2012-10-17"
114+
Statement:
115+
- Effect: Allow
116+
Action:
117+
- "lambda:*"
118+
- "logs:*"
119+
Resource: "*"
120+
- Effect: Allow
121+
Action:
122+
- "iam:PassRole"
123+
Resource:
124+
- !GetAtt LambdaFunctionsRole.Arn
125+
- Effect: Allow
126+
Action:
127+
- "s3:GetObject"
128+
- "s3:GetObjectVersion"
129+
Resource:
130+
- "arn:aws:s3:::cdk*"
131+
- Effect: Allow
132+
Action:
133+
- "ssm:GetParameter"
134+
- "ssm:GetParameters"
135+
Resource:
136+
- !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/cdk-bootstrap/*/version"
137+
138138
LambdaFunctionsRole:
139139
Type: AWS::IAM::Role
140140
Properties:

e2e_tests/setup/setup.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
To set up an AWS account for running integration tests on GitHub:
2+
3+
```bash
4+
aws cloudformation deploy \
5+
--template-file integ-test-authentication.yaml \
6+
--stack-name github-integ-test-identity-provider \
7+
--parameter-overrides GitHubOrg=awslabs RepositoryName=utilities-for-model-context-protocol-with-aws-lambda \
8+
--capabilities CAPABILITY_NAMED_IAM \
9+
--region us-east-2
10+
11+
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
12+
13+
cdk bootstrap \
14+
aws://$AWS_ACCOUNT_ID/us-east-2 \
15+
--cloudformation-execution-policies "arn:aws:iam::$AWS_ACCOUNT_ID:policy/mcp-lambda-integ-test-cdk-cfn-execution"
16+
```

e2e_tests/typescript/src/configuration.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { BedrockRuntimeClient } from '@aws-sdk/client-bedrock-runtime';
2-
import * as fs from 'fs';
1+
import { BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime";
2+
import * as fs from "fs";
33

44
/**
55
* Manages configuration for the MCP client and the Bedrock client.
@@ -12,8 +12,8 @@ export class Configuration {
1212
* Initialize configuration.
1313
*/
1414
constructor(
15-
modelId: string = 'anthropic.claude-3-5-sonnet-20241022-v2:0',
16-
region: string = 'us-west-2'
15+
modelId: string = "anthropic.claude-3-5-sonnet-20241022-v2:0",
16+
region: string = "us-east-2"
1717
) {
1818
this.modelId = modelId;
1919
this.region = region;
@@ -27,10 +27,10 @@ export class Configuration {
2727
*/
2828
static loadConfig(filePath: string): Record<string, any> {
2929
try {
30-
const fileContent = fs.readFileSync(filePath, 'utf8');
30+
const fileContent = fs.readFileSync(filePath, "utf8");
3131
return JSON.parse(fileContent);
3232
} catch (e) {
33-
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
33+
if ((e as NodeJS.ErrnoException).code === "ENOENT") {
3434
throw new Error(`Configuration file not found: ${filePath}`);
3535
} else {
3636
throw new Error(`Error parsing configuration file: ${e}`);

examples/chatbots/python/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Configuration:
2525
def __init__(
2626
self,
2727
model_id="anthropic.claude-3-5-sonnet-20241022-v2:0",
28-
region="us-west-2",
28+
region="us-east-2",
2929
) -> None:
3030
"""Initialize configuration."""
3131
self.model_id = model_id

examples/chatbots/typescript/src/configuration.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { BedrockRuntimeClient } from '@aws-sdk/client-bedrock-runtime';
2-
import * as fs from 'fs';
1+
import { BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime";
2+
import * as fs from "fs";
33

44
/**
55
* Manages configuration for the MCP client and the Bedrock client.
@@ -12,8 +12,8 @@ export class Configuration {
1212
* Initialize configuration.
1313
*/
1414
constructor(
15-
modelId: string = 'anthropic.claude-3-5-sonnet-20241022-v2:0',
16-
region: string = 'us-west-2'
15+
modelId: string = "anthropic.claude-3-5-sonnet-20241022-v2:0",
16+
region: string = "us-east-2"
1717
) {
1818
this.modelId = modelId;
1919
this.region = region;
@@ -27,10 +27,10 @@ export class Configuration {
2727
*/
2828
static loadConfig(filePath: string): Record<string, any> {
2929
try {
30-
const fileContent = fs.readFileSync(filePath, 'utf8');
30+
const fileContent = fs.readFileSync(filePath, "utf8");
3131
return JSON.parse(fileContent);
3232
} catch (e) {
33-
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
33+
if ((e as NodeJS.ErrnoException).code === "ENOENT") {
3434
throw new Error(`Configuration file not found: ${filePath}`);
3535
} else {
3636
throw new Error(`Error parsing configuration file: ${e}`);

0 commit comments

Comments
 (0)