-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
executable file
·292 lines (246 loc) · 8.82 KB
/
Copy pathdeploy.sh
File metadata and controls
executable file
·292 lines (246 loc) · 8.82 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
283
284
285
286
287
288
289
290
291
292
#!/bin/bash
set -e
REGION="us-east-1"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
STACK_NAME="sitrep"
FINDINGS_TABLE="SitRepFindings"
NOTES_TABLE="SitRepNotes"
LAMBDA_NAME="SitRepAPI"
API_NAME="SitRepAPI"
S3_BUCKET="sitrep-dashboard-${ACCOUNT_ID}"
ROLE_NAME="SitRepLambdaRole"
echo "=== SitRep Deployment ==="
echo "Account: $ACCOUNT_ID | Region: $REGION"
# ─── 1. DynamoDB Tables ───
echo ""
echo "[1/7] Creating DynamoDB tables..."
aws dynamodb create-table \
--table-name "$FINDINGS_TABLE" \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region "$REGION" 2>/dev/null && echo " Created $FINDINGS_TABLE" || echo " $FINDINGS_TABLE already exists"
aws dynamodb create-table \
--table-name "$NOTES_TABLE" \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region "$REGION" 2>/dev/null && echo " Created $NOTES_TABLE" || echo " $NOTES_TABLE already exists"
# Wait for tables to be active
echo " Waiting for tables..."
aws dynamodb wait table-exists --table-name "$FINDINGS_TABLE" --region "$REGION"
aws dynamodb wait table-exists --table-name "$NOTES_TABLE" --region "$REGION"
echo " Tables ready!"
# ─── 2. IAM Role ───
echo ""
echo "[2/7] Creating Lambda IAM role..."
TRUST_POLICY='{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
ROLE_ARN=$(aws iam create-role \
--role-name "$ROLE_NAME" \
--assume-role-policy-document "$TRUST_POLICY" \
--query 'Role.Arn' --output text 2>/dev/null) && echo " Created role" || {
ROLE_ARN=$(aws iam get-role --role-name "$ROLE_NAME" --query 'Role.Arn' --output text)
echo " Role already exists"
}
echo " Role ARN: $ROLE_ARN"
# Attach policies
aws iam attach-role-policy --role-name "$ROLE_NAME" \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 2>/dev/null || true
DYNAMO_POLICY='{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Scan",
"dynamodb:Query"
],
"Resource": [
"arn:aws:dynamodb:'"$REGION"':'"$ACCOUNT_ID"':table/SitRep*"
]
}]
}'
aws iam put-role-policy --role-name "$ROLE_NAME" \
--policy-name SitRepDynamoAccess \
--policy-document "$DYNAMO_POLICY"
echo " Policies attached"
# Wait for role propagation
echo " Waiting for IAM propagation..."
sleep 10
# ─── 3. Package Lambda ───
echo ""
echo "[3/7] Packaging Lambda function..."
cd /home/stephen/tracerFireTool/backend
zip -j /tmp/sitrep-lambda.zip lambda_function.py
echo " Lambda packaged"
# ─── 4. Create/Update Lambda ───
echo ""
echo "[4/7] Deploying Lambda function..."
LAMBDA_ARN=$(aws lambda create-function \
--function-name "$LAMBDA_NAME" \
--runtime python3.12 \
--handler lambda_function.lambda_handler \
--role "$ROLE_ARN" \
--zip-file fileb:///tmp/sitrep-lambda.zip \
--timeout 30 \
--memory-size 256 \
--environment "Variables={FINDINGS_TABLE=$FINDINGS_TABLE,NOTES_TABLE=$NOTES_TABLE,AWS_REGION_NAME=$REGION}" \
--region "$REGION" \
--query 'FunctionArn' --output text 2>/dev/null) && echo " Created Lambda" || {
aws lambda update-function-code \
--function-name "$LAMBDA_NAME" \
--zip-file fileb:///tmp/sitrep-lambda.zip \
--region "$REGION" > /dev/null
aws lambda update-function-configuration \
--function-name "$LAMBDA_NAME" \
--environment "Variables={FINDINGS_TABLE=$FINDINGS_TABLE,NOTES_TABLE=$NOTES_TABLE,AWS_REGION_NAME=$REGION}" \
--region "$REGION" > /dev/null
LAMBDA_ARN=$(aws lambda get-function --function-name "$LAMBDA_NAME" --region "$REGION" --query 'Configuration.FunctionArn' --output text)
echo " Updated Lambda"
}
echo " Lambda ARN: $LAMBDA_ARN"
# ─── 5. API Gateway ───
echo ""
echo "[5/7] Setting up API Gateway..."
# Check if API already exists
API_ID=$(aws apigateway get-rest-apis --region "$REGION" --query "items[?name=='$API_NAME'].id" --output text)
if [ -z "$API_ID" ] || [ "$API_ID" = "None" ]; then
API_ID=$(aws apigateway create-rest-api \
--name "$API_NAME" \
--description "SitRep CTF API" \
--endpoint-configuration '{"types":["REGIONAL"]}' \
--region "$REGION" \
--query 'id' --output text)
echo " Created API: $API_ID"
else
echo " API exists: $API_ID"
fi
# Get root resource
ROOT_ID=$(aws apigateway get-resources --rest-api-id "$API_ID" --region "$REGION" \
--query 'items[?path==`/`].id' --output text)
# Create proxy resource {proxy+}
PROXY_ID=$(aws apigateway get-resources --rest-api-id "$API_ID" --region "$REGION" \
--query 'items[?path==`/{proxy+}`].id' --output text)
if [ -z "$PROXY_ID" ] || [ "$PROXY_ID" = "None" ]; then
PROXY_ID=$(aws apigateway create-resource \
--rest-api-id "$API_ID" \
--parent-id "$ROOT_ID" \
--path-part '{proxy+}' \
--region "$REGION" \
--query 'id' --output text)
echo " Created proxy resource"
fi
# Setup ANY method on proxy resource
aws apigateway put-method \
--rest-api-id "$API_ID" \
--resource-id "$PROXY_ID" \
--http-method ANY \
--authorization-type NONE \
--region "$REGION" 2>/dev/null || true
aws apigateway put-integration \
--rest-api-id "$API_ID" \
--resource-id "$PROXY_ID" \
--http-method ANY \
--type AWS_PROXY \
--integration-http-method POST \
--uri "arn:aws:apigateway:${REGION}:lambda:path/2015-03-31/functions/${LAMBDA_ARN}/invocations" \
--region "$REGION" > /dev/null
# Also set up root path methods for OPTIONS
aws apigateway put-method \
--rest-api-id "$API_ID" \
--resource-id "$ROOT_ID" \
--http-method ANY \
--authorization-type NONE \
--region "$REGION" 2>/dev/null || true
aws apigateway put-integration \
--rest-api-id "$API_ID" \
--resource-id "$ROOT_ID" \
--http-method ANY \
--type AWS_PROXY \
--integration-http-method POST \
--uri "arn:aws:apigateway:${REGION}:lambda:path/2015-03-31/functions/${LAMBDA_ARN}/invocations" \
--region "$REGION" > /dev/null
# Deploy API
aws apigateway create-deployment \
--rest-api-id "$API_ID" \
--stage-name prod \
--region "$REGION" > /dev/null
echo " API deployed to prod stage"
API_URL="https://${API_ID}.execute-api.${REGION}.amazonaws.com/prod"
echo " API URL: $API_URL"
# Grant API Gateway permission to invoke Lambda
aws lambda add-permission \
--function-name "$LAMBDA_NAME" \
--statement-id apigateway-invoke-all \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:${REGION}:${ACCOUNT_ID}:${API_ID}/*" \
--region "$REGION" 2>/dev/null || true
echo " Lambda permission granted"
# ─── 6. Build Frontend ───
echo ""
echo "[6/7] Building frontend..."
cd /home/stephen/tracerFireTool/frontend
# Inject API URL into the build
cat > src/config.js << JSEOF
window.SITREP_API = "${API_URL}";
JSEOF
# Add config.js to index.html
sed -i 's|<div id="root">|<script src="%PUBLIC_URL%/config.js"></script>\n <div id="root">|' public/index.html
# Copy config to public for runtime
cp src/config.js public/config.js
npm install --legacy-peer-deps 2>&1 | tail -3
npm run build 2>&1 | tail -5
echo " Frontend built!"
# ─── 7. S3 Static Hosting ───
echo ""
echo "[7/7] Deploying frontend to S3..."
aws s3 mb "s3://$S3_BUCKET" --region "$REGION" 2>/dev/null || echo " Bucket exists"
# Disable block public access
aws s3api put-public-access-block \
--bucket "$S3_BUCKET" \
--public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false" \
--region "$REGION"
# Enable static website hosting
aws s3 website "s3://$S3_BUCKET" --index-document index.html --error-document index.html
# Bucket policy for public read
BUCKET_POLICY='{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::'"$S3_BUCKET"'/*"
}]
}'
aws s3api put-bucket-policy --bucket "$S3_BUCKET" --policy "$BUCKET_POLICY" --region "$REGION"
# Upload build
aws s3 sync build/ "s3://$S3_BUCKET/" --delete --region "$REGION" | tail -3
SITE_URL="http://${S3_BUCKET}.s3-website-${REGION}.amazonaws.com"
echo ""
echo "============================================"
echo " SitRep Deployment Complete!"
echo "============================================"
echo ""
echo " Dashboard: $SITE_URL"
echo " API: $API_URL"
echo ""
echo " DynamoDB: $FINDINGS_TABLE, $NOTES_TABLE"
echo " Lambda: $LAMBDA_NAME"
echo " S3 Bucket: $S3_BUCKET"
echo ""
echo " Test the API:"
echo " curl ${API_URL}/api/stats"
echo ""
echo "============================================"