-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
executable file
·282 lines (237 loc) · 8.25 KB
/
deploy.sh
File metadata and controls
executable file
·282 lines (237 loc) · 8.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#!/bin/bash
#
# deploy.sh - Deploy Simple OAuth2 M2M Demo
#
# Usage:
# ./deploy.sh [OPTIONS]
#
# Options:
# --region REGION AWS region (default: us-west-2)
# --skip-build Skip Docker image build (use existing image)
# --destroy Destroy the stack instead of deploying
# --help Show this help message
#
# Examples:
# ./deploy.sh --region us-west-2 # Full deploy with image build
# ./deploy.sh --skip-build # Quick deploy, reuse existing image
# ./deploy.sh --destroy # Tear down the stack
#
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKIP_BUILD=false
DESTROY=false
REGION="us-west-2"
STACK_NAME="SimpleOAuthDemo"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
print_step() {
echo -e "${GREEN}==>${NC} $1"
}
print_warning() {
echo -e "${YELLOW}Warning:${NC} $1"
}
print_error() {
echo -e "${RED}Error:${NC} $1"
}
show_help() {
head -25 "$0" | tail -22 | sed 's/^#//' | sed 's/^ //'
exit 0
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--skip-build)
SKIP_BUILD=true
shift
;;
--destroy)
DESTROY=true
shift
;;
--region)
REGION="$2"
shift 2
;;
--help|-h)
show_help
;;
*)
print_error "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
cd "$SCRIPT_DIR"
# Check prerequisites
print_step "Checking prerequisites..."
if ! command -v aws &> /dev/null; then
print_error "AWS CLI is not installed. Please install it first."
exit 1
fi
if ! command -v docker &> /dev/null; then
print_error "Docker is not installed. Please install it first."
exit 1
fi
if ! command -v python3 &> /dev/null; then
print_error "Python3 is not installed. Please install it first."
exit 1
fi
# Verify AWS credentials
if ! aws sts get-caller-identity &> /dev/null; then
print_error "AWS credentials are not configured or have expired."
exit 1
fi
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REPO_NAME=$(echo "$STACK_NAME" | tr '[:upper:]' '[:lower:]')-mcp-server
echo " AWS Account: $ACCOUNT_ID"
echo " Region: $REGION"
# Setup Python virtual environment
print_step "Setting up Python environment..."
if [ ! -d ".venv" ]; then
python3 -m venv .venv
fi
source .venv/bin/activate
pip install -q -r requirements.txt
# Handle destroy
if [ "$DESTROY" = true ]; then
print_step "Destroying stack..."
JSII_SILENCE_WARNING_UNTESTED_NODE_VERSION=1 cdk destroy --force
# Clean up ECR repository
print_step "Cleaning up ECR repository..."
aws ecr delete-repository --repository-name "$REPO_NAME" --region "$REGION" --force 2>/dev/null || true
echo ""
echo -e "${GREEN}Stack destroyed successfully!${NC}"
exit 0
fi
# Build and push Docker image (unless skipped)
if [ "$SKIP_BUILD" = false ]; then
print_step "Building Docker image for ARM64..."
# Check if Docker daemon is running
if ! docker info &> /dev/null; then
print_error "Docker daemon is not running. Please start Docker first."
exit 1
fi
# Setup buildx with QEMU for ARM64 cross-compilation
print_step "Setting up Docker buildx for ARM64..."
docker run --rm --privileged tonistiigi/binfmt --install arm64 > /dev/null 2>&1 || true
# Create or use existing builder
if ! docker buildx inspect arm64-builder &> /dev/null; then
docker buildx create --name arm64-builder --use > /dev/null
else
docker buildx use arm64-builder
fi
# Create ECR repository if it doesn't exist
print_step "Ensuring ECR repository exists..."
if ! aws ecr describe-repositories --repository-names "$REPO_NAME" --region "$REGION" &> /dev/null; then
aws ecr create-repository \
--repository-name "$REPO_NAME" \
--region "$REGION" \
--image-scanning-configuration scanOnPush=true > /dev/null
echo " Created ECR repository: $REPO_NAME"
else
echo " ECR repository exists: $REPO_NAME"
fi
# Login to ECR
print_step "Logging in to ECR..."
aws ecr get-login-password --region "$REGION" | \
docker login --username AWS --password-stdin "$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com" > /dev/null
# Build and push image
IMAGE_URI="$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:latest"
print_step "Building and pushing image..."
echo " Image: $IMAGE_URI"
docker buildx build \
--platform linux/arm64 \
-t "$IMAGE_URI" \
--push \
"$SCRIPT_DIR/mcp-server"
echo -e " ${GREEN}Image pushed successfully!${NC}"
else
print_warning "Skipping Docker build (--skip-build)"
fi
# Deploy CDK stack (may need retry due to Gateway Target timing)
print_step "Deploying CDK stack..."
# First attempt
if JSII_SILENCE_WARNING_UNTESTED_NODE_VERSION=1 cdk deploy --require-approval never 2>&1; then
echo " Deployment succeeded on first attempt"
else
# Check if it failed due to GatewayTarget timing issue
STACK_STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --region "$REGION" --query "Stacks[0].StackStatus" --output text 2>/dev/null || echo "DOES_NOT_EXIST")
if [ "$STACK_STATUS" = "ROLLBACK_COMPLETE" ]; then
print_warning "First deployment failed (Runtime may need time to stabilize). Cleaning up and retrying..."
# Delete the failed stack
aws cloudformation delete-stack --stack-name "$STACK_NAME" --region "$REGION"
aws cloudformation wait stack-delete-complete --stack-name "$STACK_NAME" --region "$REGION"
# Wait for services to stabilize
echo " Waiting 30 seconds for services to stabilize..."
sleep 30
# Retry deployment
print_step "Retrying deployment..."
JSII_SILENCE_WARNING_UNTESTED_NODE_VERSION=1 cdk deploy --require-approval never
else
print_error "Deployment failed with status: $STACK_STATUS"
exit 1
fi
fi
# =====================================================================
# WAIT FOR GATEWAY TO BE READY
# =====================================================================
# The interceptor is deployed inline with CDK. Just wait for Gateway to be operational.
print_step "Waiting for Gateway to be READY..."
GATEWAY_ID=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--region "$REGION" \
--query 'Stacks[0].Outputs[?OutputKey==`GatewayId`].OutputValue' \
--output text)
echo " Gateway ID: $GATEWAY_ID"
MAX_ATTEMPTS=60
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
STATUS=$(aws bedrock-agentcore-control get-gateway \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query 'status' \
--output text 2>/dev/null || echo "PENDING")
if [ "$STATUS" = "READY" ]; then
echo " Gateway is READY"
break
fi
echo " Gateway status: $STATUS, waiting... (attempt $((ATTEMPT+1))/$MAX_ATTEMPTS)"
sleep 5
ATTEMPT=$((ATTEMPT+1))
done
if [ "$STATUS" != "READY" ]; then
print_error "Gateway did not become READY within timeout"
exit 1
fi
# Verify interceptor is configured
echo " Verifying interceptor configuration..."
INTERCEPTOR_COUNT=$(aws bedrock-agentcore-control get-gateway \
--gateway-identifier "$GATEWAY_ID" \
--region "$REGION" \
--query 'length(interceptorConfigurations)' \
--output text 2>/dev/null || echo "0")
if [ "$INTERCEPTOR_COUNT" -gt 0 ]; then
echo -e " ${GREEN}Interceptor configured successfully!${NC}"
else
print_warning "Interceptor not found - check CDK deployment logs"
fi
# Get outputs and print demo command
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Deployment complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo "Next steps:"
echo ""
echo " Run the full test suite:"
echo " ./test.sh"
echo ""
echo " This will create test users and verify all auth modes:"
echo " - M2M mode (admin tools blocked - no user groups)"
echo " - Admin user (full access)"
echo " - Regular user (admin tools blocked)"
echo ""