@aws/ml-container-creator 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/bin/cli.js +31 -137
  2. package/config/parameter-schema-v2.json +2065 -0
  3. package/package.json +6 -3
  4. package/servers/lib/catalogs/jumpstart-public.json +101 -16
  5. package/servers/lib/catalogs/models.json +182 -26
  6. package/src/app.js +6 -389
  7. package/src/lib/bootstrap-command-handler.js +75 -1078
  8. package/src/lib/bootstrap-profile-manager.js +634 -0
  9. package/src/lib/bootstrap-provisioners.js +421 -0
  10. package/src/lib/config-loader.js +405 -0
  11. package/src/lib/config-manager.js +59 -1668
  12. package/src/lib/config-mcp-client.js +118 -0
  13. package/src/lib/config-validator.js +634 -0
  14. package/src/lib/cuda-resolver.js +140 -0
  15. package/src/lib/e2e-catalog-validator.js +251 -3
  16. package/src/lib/e2e-ci-recorder.js +103 -0
  17. package/src/lib/generated/cli-options.js +471 -0
  18. package/src/lib/generated/parameter-matrix.js +671 -0
  19. package/src/lib/generated/validation-rules.js +202 -0
  20. package/src/lib/marketplace-flow.js +276 -0
  21. package/src/lib/mcp-query-runner.js +768 -0
  22. package/src/lib/parameter-schema-validator.js +62 -18
  23. package/src/lib/prompt-runner.js +41 -1504
  24. package/src/lib/prompts/feature-prompts.js +172 -0
  25. package/src/lib/prompts/index.js +48 -0
  26. package/src/lib/prompts/infrastructure-prompts.js +690 -0
  27. package/src/lib/prompts/model-prompts.js +552 -0
  28. package/src/lib/prompts/project-prompts.js +70 -0
  29. package/src/lib/prompts.js +2 -1446
  30. package/src/lib/registry-command-handler.js +135 -3
  31. package/src/lib/secrets-prompt-runner.js +251 -0
  32. package/src/lib/template-variable-resolver.js +398 -0
  33. package/templates/code/serve +5 -134
  34. package/templates/code/serve.d/lmi.ejs +19 -0
  35. package/templates/code/serve.d/sglang.ejs +47 -0
  36. package/templates/code/serve.d/tensorrt-llm.ejs +53 -0
  37. package/templates/code/serve.d/vllm.ejs +48 -0
  38. package/templates/do/clean +1 -1387
  39. package/templates/do/clean.d/async-inference.ejs +508 -0
  40. package/templates/do/clean.d/batch-transform.ejs +512 -0
  41. package/templates/do/clean.d/hyperpod-eks.ejs +481 -0
  42. package/templates/do/clean.d/managed-inference.ejs +1043 -0
  43. package/templates/do/deploy +1 -1766
  44. package/templates/do/deploy.d/async-inference.ejs +501 -0
  45. package/templates/do/deploy.d/batch-transform.ejs +529 -0
  46. package/templates/do/deploy.d/hyperpod-eks.ejs +339 -0
  47. package/templates/do/deploy.d/managed-inference.ejs +726 -0
  48. package/config/parameter-schema.json +0 -88
@@ -0,0 +1,508 @@
1
+ #!/bin/bash
2
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ set -e
6
+ set -u
7
+ set -o pipefail
8
+
9
+ # Source configuration
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ source "${SCRIPT_DIR}/config"
12
+
13
+ # Parse arguments
14
+ CLEANUP_TARGET=""
15
+ CLEANUP_ARG=""
16
+ FORCE_CLEAN=false
17
+
18
+ for arg in "$@"; do
19
+ case "$arg" in
20
+ --force) FORCE_CLEAN=true ;;
21
+ -*) ;; # ignore other flags
22
+ *)
23
+ if [ -z "${CLEANUP_TARGET}" ]; then
24
+ CLEANUP_TARGET="$arg"
25
+ elif [ -z "${CLEANUP_ARG}" ]; then
26
+ CLEANUP_ARG="$arg"
27
+ fi
28
+ ;;
29
+ esac
30
+ done
31
+
32
+ # Function to display usage
33
+ show_usage() {
34
+ echo "Usage: ./do/clean [local|ecr|endpoint|codebuild|all]"
35
+ echo ""
36
+ echo "Cleanup targets:"
37
+ echo " local - Remove local Docker images"
38
+ echo " ecr - Remove images from Amazon ECR"
39
+ echo " endpoint - Delete SageMaker async endpoint, configuration, and inference component"
40
+ echo " codebuild - Delete CodeBuild project, IAM role, and S3 source artifacts"
41
+ echo " all - Perform all cleanup operations"
42
+ echo ""
43
+ echo "Examples:"
44
+ echo " ./do/clean local # Remove local Docker images only"
45
+ echo " ./do/clean endpoint # Delete SageMaker async resources only"
46
+ echo " ./do/clean codebuild # Delete CodeBuild project and rebuild fresh"
47
+ echo " ./do/clean all # Clean up everything"
48
+ }
49
+
50
+ # Function to confirm action (skipped when --force is set)
51
+ confirm_action() {
52
+ local message="$1"
53
+ if [ "${FORCE_CLEAN}" = true ]; then
54
+ return 0
55
+ fi
56
+ echo ""
57
+ echo "⚠️ ${message}"
58
+ read -p " Are you sure? (yes/no): " -r
59
+ echo ""
60
+ if [[ ! $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
61
+ echo "❌ Operation cancelled"
62
+ return 1
63
+ fi
64
+ return 0
65
+ }
66
+
67
+ # Function to clean local Docker images
68
+ clean_local() {
69
+ echo "🧹 Cleaning local Docker images"
70
+ echo " Project: ${PROJECT_NAME}"
71
+
72
+ LOCAL_PATTERN="^${PROJECT_NAME}:"
73
+ ECR_PATTERN="\.dkr\.ecr\..*\.amazonaws\.com/${ECR_REPOSITORY_NAME}:${PROJECT_NAME}-"
74
+
75
+ if ! docker images --format "{{.Repository}}:{{.Tag}}" | grep -qE "${LOCAL_PATTERN}|${ECR_PATTERN}"; then
76
+ echo "ℹ️ No local images found for ${PROJECT_NAME}"
77
+ return 0
78
+ fi
79
+
80
+ echo ""
81
+ echo "Images to be removed:"
82
+ docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "${LOCAL_PATTERN}|${ECR_PATTERN}" | while read -r image; do
83
+ echo " ${image}"
84
+ done
85
+
86
+ if ! confirm_action "This will remove all local Docker images for ${PROJECT_NAME}"; then
87
+ return 1
88
+ fi
89
+
90
+ echo "🗑️ Removing local images..."
91
+ docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "${LOCAL_PATTERN}|${ECR_PATTERN}" | while read -r image; do
92
+ echo " Removing: ${image}"
93
+ docker rmi "${image}" || echo " ⚠️ Failed to remove ${image}"
94
+ done
95
+
96
+ echo "✅ Local images cleaned"
97
+ }
98
+
99
+ # Function to clean ECR images
100
+ clean_ecr() {
101
+ echo "🧹 Cleaning ECR images"
102
+ echo " Repository: ${ECR_REPOSITORY_NAME}"
103
+ echo " Region: ${AWS_REGION}"
104
+
105
+ if ! aws sts get-caller-identity &> /dev/null; then
106
+ echo "❌ AWS credentials not configured"
107
+ echo " Run: aws configure"
108
+ exit 4
109
+ fi
110
+
111
+ AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
112
+
113
+ if ! aws ecr describe-repositories \
114
+ --repository-names "${ECR_REPOSITORY_NAME}" \
115
+ --region "${AWS_REGION}" &> /dev/null; then
116
+ echo "ℹ️ ECR repository ${ECR_REPOSITORY_NAME} does not exist"
117
+ return 0
118
+ fi
119
+
120
+ echo ""
121
+ echo "Checking for images in repository..."
122
+
123
+ if ! IMAGE_IDS=$(aws ecr list-images \
124
+ --repository-name "${ECR_REPOSITORY_NAME}" \
125
+ --region "${AWS_REGION}" \
126
+ --query "imageIds[?starts_with(imageTag, '${PROJECT_NAME}-')].[imageTag]" \
127
+ --output text 2>&1); then
128
+ echo "ℹ️ No images found for project: ${PROJECT_NAME}"
129
+ return 0
130
+ fi
131
+
132
+ if [ -z "${IMAGE_IDS}" ] || [ "${IMAGE_IDS}" = "None" ]; then
133
+ echo "ℹ️ No images found for project: ${PROJECT_NAME}"
134
+ return 0
135
+ fi
136
+
137
+ echo "Images for project ${PROJECT_NAME}:"
138
+ echo "${IMAGE_IDS}" | while read -r tag; do
139
+ if [ -n "${tag}" ] && [ "${tag}" != "None" ]; then
140
+ echo " - ${tag}"
141
+ fi
142
+ done
143
+
144
+ if ! confirm_action "This will remove all images from ECR repository ${ECR_REPOSITORY_NAME}"; then
145
+ return 1
146
+ fi
147
+
148
+ echo "🗑️ Removing ECR images..."
149
+
150
+ IMAGE_IDS_JSON=$(aws ecr list-images \
151
+ --repository-name "${ECR_REPOSITORY_NAME}" \
152
+ --region "${AWS_REGION}" \
153
+ --query "imageIds[?starts_with(imageTag, '${PROJECT_NAME}-')]" \
154
+ --output json)
155
+
156
+ if [ "${IMAGE_IDS_JSON}" != "[]" ] && [ -n "${IMAGE_IDS_JSON}" ]; then
157
+ if aws ecr batch-delete-image \
158
+ --repository-name "${ECR_REPOSITORY_NAME}" \
159
+ --region "${AWS_REGION}" \
160
+ --image-ids "${IMAGE_IDS_JSON}" &> /dev/null; then
161
+ echo "✅ ECR images removed for project: ${PROJECT_NAME}"
162
+ else
163
+ echo "❌ Failed to remove some ECR images"
164
+ return 1
165
+ fi
166
+ else
167
+ echo "ℹ️ No images to remove for project: ${PROJECT_NAME}"
168
+ fi
169
+ }
170
+
171
+ # Function to clean SageMaker async endpoint and model
172
+ clean_endpoint() {
173
+ echo "🧹 Cleaning SageMaker async resources"
174
+ echo " Project: ${PROJECT_NAME}"
175
+ echo " Region: ${AWS_REGION}"
176
+
177
+ if ! aws sts get-caller-identity &> /dev/null; then
178
+ echo "❌ AWS credentials not configured"
179
+ echo " Run: aws configure"
180
+ exit 4
181
+ fi
182
+
183
+ AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
184
+
185
+ local EP_NAME="${ENDPOINT_NAME:-}"
186
+ local EPC_NAME="${ENDPOINT_CONFIG_NAME:-}"
187
+ local SM_MODEL_NAME="${SAGEMAKER_MODEL_NAME:-}"
188
+
189
+ if [ -z "${EP_NAME}" ]; then
190
+ echo "❌ No endpoint name found"
191
+ echo " Run ./do/deploy first, or set ENDPOINT_NAME in do/config"
192
+ return 1
193
+ fi
194
+
195
+ echo ""
196
+ echo "Checking for SageMaker resources..."
197
+
198
+ local ENDPOINT_EXISTS=false
199
+
200
+ if aws sagemaker describe-endpoint \
201
+ --endpoint-name "${EP_NAME}" \
202
+ --region "${AWS_REGION}" &> /dev/null; then
203
+ ENDPOINT_EXISTS=true
204
+ echo " ✓ Endpoint: ${EP_NAME}"
205
+ else
206
+ echo "ℹ️ Endpoint not found: ${EP_NAME}"
207
+ return 0
208
+ fi
209
+
210
+ if ! confirm_action "This will delete the SageMaker async endpoint and model"; then
211
+ return 1
212
+ fi
213
+
214
+ # Delete endpoint
215
+ echo "🗑️ Deleting endpoint: ${EP_NAME}"
216
+ if aws sagemaker delete-endpoint \
217
+ --endpoint-name "${EP_NAME}" \
218
+ --region "${AWS_REGION}" &> /dev/null; then
219
+ echo "✅ Endpoint deleted"
220
+ echo "⏳ Waiting for endpoint deletion..."
221
+ aws sagemaker wait endpoint-deleted \
222
+ --endpoint-name "${EP_NAME}" \
223
+ --region "${AWS_REGION}" 2>/dev/null || sleep 10
224
+
225
+ ./do/manifest delete --id "arn:aws:sagemaker:${AWS_REGION}:${AWS_ACCOUNT_ID}:endpoint/${EP_NAME}" 2>/dev/null || true
226
+ else
227
+ echo "❌ Failed to delete endpoint"
228
+ fi
229
+
230
+ # Delete endpoint configuration
231
+ if [ -n "${EPC_NAME}" ]; then
232
+ echo "🗑️ Deleting endpoint configuration: ${EPC_NAME}"
233
+ if aws sagemaker delete-endpoint-config \
234
+ --endpoint-config-name "${EPC_NAME}" \
235
+ --region "${AWS_REGION}" &> /dev/null; then
236
+ echo "✅ Endpoint configuration deleted"
237
+
238
+ ./do/manifest delete --id "arn:aws:sagemaker:${AWS_REGION}:${AWS_ACCOUNT_ID}:endpoint-config/${EPC_NAME}" 2>/dev/null || true
239
+ else
240
+ echo "❌ Failed to delete endpoint configuration"
241
+ fi
242
+ fi
243
+
244
+ # Delete SageMaker model (async uses classic model-based flow)
245
+ if [ -n "${SM_MODEL_NAME}" ]; then
246
+ echo "🗑️ Deleting SageMaker model: ${SM_MODEL_NAME}"
247
+ if aws sagemaker delete-model \
248
+ --model-name "${SM_MODEL_NAME}" \
249
+ --region "${AWS_REGION}" &> /dev/null; then
250
+ echo "✅ SageMaker model deleted"
251
+
252
+ ./do/manifest delete --id "arn:aws:sagemaker:${AWS_REGION}:${AWS_ACCOUNT_ID}:model/${SM_MODEL_NAME}" 2>/dev/null || true
253
+ else
254
+ echo "❌ Failed to delete SageMaker model"
255
+ fi
256
+ fi
257
+
258
+ # Remove saved names from config
259
+ if grep -q "^export ENDPOINT_NAME=" "${SCRIPT_DIR}/config" 2>/dev/null; then
260
+ sed -i.bak '/^# Last deployed resources/d;/^export ENDPOINT_NAME=/d;/^export ENDPOINT_CONFIG_NAME=/d;/^export SAGEMAKER_MODEL_NAME=/d' "${SCRIPT_DIR}/config"
261
+ rm -f "${SCRIPT_DIR}/config.bak"
262
+ fi
263
+
264
+ echo "✅ SageMaker async resources cleaned"
265
+ }
266
+
267
+ # Function to clean CodeBuild project and related resources
268
+ clean_codebuild() {
269
+ echo "🧹 Cleaning CodeBuild resources"
270
+ echo " Project: ${CODEBUILD_PROJECT_NAME:-not set}"
271
+ echo " Region: ${AWS_REGION}"
272
+
273
+ if [ -z "${CODEBUILD_PROJECT_NAME:-}" ]; then
274
+ echo "ℹ️ No CodeBuild project name configured (build target may not be codebuild)"
275
+ return 0
276
+ fi
277
+
278
+ if ! aws sts get-caller-identity &> /dev/null; then
279
+ echo "❌ AWS credentials not configured"
280
+ echo " Run: aws configure"
281
+ exit 4
282
+ fi
283
+
284
+ AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
285
+
286
+ PROJECT_CHECK=$(aws codebuild batch-get-projects \
287
+ --names "${CODEBUILD_PROJECT_NAME}" \
288
+ --region "${AWS_REGION}" \
289
+ --query 'projects[0].name' \
290
+ --output text 2>/dev/null)
291
+
292
+ if [ "$PROJECT_CHECK" = "None" ] || [ -z "$PROJECT_CHECK" ] || [ "$PROJECT_CHECK" = "null" ]; then
293
+ echo "ℹ️ CodeBuild project not found: ${CODEBUILD_PROJECT_NAME}"
294
+ return 0
295
+ fi
296
+
297
+ echo ""
298
+ echo "Resources to be removed:"
299
+ echo " • CodeBuild project: ${CODEBUILD_PROJECT_NAME}"
300
+
301
+ ROLE_NAME="${CODEBUILD_PROJECT_NAME}-service-role"
302
+ ROLE_EXISTS=false
303
+ if aws iam get-role --role-name "${ROLE_NAME}" &> /dev/null; then
304
+ ROLE_EXISTS=true
305
+ echo " • IAM service role: ${ROLE_NAME}"
306
+ fi
307
+
308
+ S3_BUCKET="codebuild-source-${AWS_ACCOUNT_ID}-${AWS_REGION}"
309
+ S3_PREFIX="${PROJECT_NAME}/"
310
+ S3_EXISTS=false
311
+ if aws s3api head-bucket --bucket "$S3_BUCKET" --region "${AWS_REGION}" &> /dev/null; then
312
+ S3_COUNT=$(aws s3 ls "s3://$S3_BUCKET/$S3_PREFIX" --region "${AWS_REGION}" 2>/dev/null | wc -l | tr -d ' ')
313
+ if [ "$S3_COUNT" -gt 0 ]; then
314
+ S3_EXISTS=true
315
+ echo " • S3 source artifacts: s3://$S3_BUCKET/$S3_PREFIX ($S3_COUNT objects)"
316
+ fi
317
+ fi
318
+
319
+ if ! confirm_action "This will delete the CodeBuild project and associated resources"; then
320
+ return 1
321
+ fi
322
+
323
+ echo "🗑️ Deleting CodeBuild project: ${CODEBUILD_PROJECT_NAME}"
324
+ if aws codebuild delete-project \
325
+ --name "${CODEBUILD_PROJECT_NAME}" \
326
+ --region "${AWS_REGION}" &> /dev/null; then
327
+ echo "✅ CodeBuild project deleted"
328
+
329
+ ./do/manifest delete --id "arn:aws:codebuild:${AWS_REGION}:${AWS_ACCOUNT_ID}:project/${CODEBUILD_PROJECT_NAME}" 2>/dev/null || true
330
+ else
331
+ echo "❌ Failed to delete CodeBuild project"
332
+ fi
333
+
334
+ if [ "$ROLE_EXISTS" = true ]; then
335
+ echo "🗑️ Deleting IAM service role: ${ROLE_NAME}"
336
+ POLICIES=$(aws iam list-role-policies --role-name "${ROLE_NAME}" --query 'PolicyNames' --output text 2>/dev/null || echo "")
337
+ for policy in $POLICIES; do
338
+ aws iam delete-role-policy --role-name "${ROLE_NAME}" --policy-name "$policy" 2>/dev/null || true
339
+ done
340
+ if aws iam delete-role --role-name "${ROLE_NAME}" &> /dev/null; then
341
+ echo "✅ IAM service role deleted"
342
+
343
+ ./do/manifest delete --id "arn:aws:iam::${AWS_ACCOUNT_ID}:role/${ROLE_NAME}" 2>/dev/null || true
344
+ else
345
+ echo "❌ Failed to delete IAM service role"
346
+ fi
347
+ fi
348
+
349
+ if [ "$S3_EXISTS" = true ]; then
350
+ echo "🗑️ Deleting S3 source artifacts: s3://$S3_BUCKET/$S3_PREFIX"
351
+ if aws s3 rm "s3://$S3_BUCKET/$S3_PREFIX" --recursive --region "${AWS_REGION}" &> /dev/null; then
352
+ echo "✅ S3 source artifacts deleted"
353
+ else
354
+ echo "❌ Failed to delete S3 source artifacts"
355
+ fi
356
+ fi
357
+
358
+ echo "✅ CodeBuild resources cleaned"
359
+ }
360
+
361
+ # Main script logic
362
+ echo "🧹 Cleanup script for ${PROJECT_NAME}"
363
+ echo ""
364
+
365
+ if [ -z "${CLEANUP_TARGET}" ]; then
366
+ show_usage
367
+ exit 0
368
+ fi
369
+
370
+ case "${CLEANUP_TARGET}" in
371
+ local)
372
+ clean_local
373
+ ;;
374
+ ecr)
375
+ clean_ecr
376
+ ;;
377
+ endpoint)
378
+ clean_endpoint
379
+ ;;
380
+ codebuild)
381
+ clean_codebuild
382
+ ;;
383
+ <% if (typeof includeBenchmark !== 'undefined' && includeBenchmark) { %>
384
+ benchmark)
385
+ echo "🧹 Cleaning benchmark resources..."
386
+ WORKLOAD_CONFIG_NAME="${PROJECT_NAME}-benchmark-config"
387
+
388
+ if aws sagemaker describe-ai-workload-config \
389
+ --ai-workload-config-name "$WORKLOAD_CONFIG_NAME" \
390
+ --region "$AWS_REGION" 2>/dev/null; then
391
+ aws sagemaker delete-ai-workload-config \
392
+ --ai-workload-config-name "$WORKLOAD_CONFIG_NAME" \
393
+ --region "$AWS_REGION"
394
+ echo " ✓ Deleted workload config: $WORKLOAD_CONFIG_NAME"
395
+ fi
396
+
397
+ aws sagemaker list-ai-benchmark-jobs \
398
+ --name-contains "${PROJECT_NAME}-benchmark-" \
399
+ --region "$AWS_REGION" \
400
+ --query 'AIBenchmarkJobs[?AIBenchmarkJobStatus!=`InProgress`].AIBenchmarkJobName' \
401
+ --output text | tr '\t' '\n' | while read -r job; do
402
+ [ -z "$job" ] && continue
403
+ aws sagemaker delete-ai-benchmark-job \
404
+ --ai-benchmark-job-name "$job" \
405
+ --region "$AWS_REGION"
406
+ echo " ✓ Deleted benchmark job: $job"
407
+ done
408
+
409
+ if [ -d "${SCRIPT_DIR}/../benchmarks" ]; then
410
+ read -p "Delete local benchmark results? (Y/n) " CONFIRM_DELETE
411
+ CONFIRM_DELETE="${CONFIRM_DELETE:-Y}"
412
+ if [[ "${CONFIRM_DELETE}" =~ ^[Yy]$ ]]; then
413
+ rm -rf "${SCRIPT_DIR}/../benchmarks"
414
+ echo " ✓ Deleted local benchmarks/ directory"
415
+ else
416
+ echo " ⏭ Skipped local benchmarks/ deletion"
417
+ fi
418
+ fi
419
+
420
+ echo "✅ Benchmark cleanup complete"
421
+ ;;
422
+ <% } %>
423
+ all)
424
+ echo "🧹 Performing complete cleanup"
425
+ echo ""
426
+
427
+ CLEANED_ITEMS=()
428
+
429
+ if clean_local; then
430
+ CLEANED_ITEMS+=("Local Docker images")
431
+ fi
432
+
433
+ echo ""
434
+
435
+ if clean_ecr; then
436
+ CLEANED_ITEMS+=("ECR images")
437
+ fi
438
+
439
+ echo ""
440
+
441
+ # Clean SageMaker async resources
442
+ if clean_endpoint; then
443
+ CLEANED_ITEMS+=("SageMaker async resources")
444
+ fi
445
+
446
+ echo ""
447
+
448
+ if clean_codebuild; then
449
+ CLEANED_ITEMS+=("CodeBuild resources")
450
+ fi
451
+
452
+ <% if (typeof includeBenchmark !== 'undefined' && includeBenchmark) { %>
453
+ echo ""
454
+
455
+ WORKLOAD_CONFIG_NAME="${PROJECT_NAME}-benchmark-config"
456
+
457
+ if aws sagemaker describe-ai-workload-config \
458
+ --ai-workload-config-name "$WORKLOAD_CONFIG_NAME" \
459
+ --region "$AWS_REGION" 2>/dev/null; then
460
+ aws sagemaker delete-ai-workload-config \
461
+ --ai-workload-config-name "$WORKLOAD_CONFIG_NAME" \
462
+ --region "$AWS_REGION"
463
+ echo " ✓ Deleted workload config: $WORKLOAD_CONFIG_NAME"
464
+ fi
465
+
466
+ aws sagemaker list-ai-benchmark-jobs \
467
+ --name-contains "${PROJECT_NAME}-benchmark-" \
468
+ --region "$AWS_REGION" \
469
+ --query 'AIBenchmarkJobs[?AIBenchmarkJobStatus!=`InProgress`].AIBenchmarkJobName' \
470
+ --output text | tr '\t' '\n' | while read -r job; do
471
+ [ -z "$job" ] && continue
472
+ aws sagemaker delete-ai-benchmark-job \
473
+ --ai-benchmark-job-name "$job" \
474
+ --region "$AWS_REGION"
475
+ echo " ✓ Deleted benchmark job: $job"
476
+ done
477
+
478
+ if [ -d "${SCRIPT_DIR}/../benchmarks" ]; then
479
+ read -p "Delete local benchmark results? (Y/n) " CONFIRM_DELETE
480
+ CONFIRM_DELETE="${CONFIRM_DELETE:-Y}"
481
+ if [[ "${CONFIRM_DELETE}" =~ ^[Yy]$ ]]; then
482
+ rm -rf "${SCRIPT_DIR}/../benchmarks"
483
+ echo " ✓ Deleted local benchmarks/ directory"
484
+ else
485
+ echo " ⏭ Skipped local benchmarks/ deletion"
486
+ fi
487
+ fi
488
+
489
+ CLEANED_ITEMS+=("Benchmark resources")
490
+ <% } %>
491
+ echo ""
492
+ echo "✅ Cleanup complete!"
493
+ echo ""
494
+ echo "Summary of cleaned resources:"
495
+ for item in "${CLEANED_ITEMS[@]}"; do
496
+ echo " ✓ ${item}"
497
+ done
498
+ ;;
499
+ *)
500
+ echo "❌ Unknown cleanup target: ${CLEANUP_TARGET}"
501
+ echo ""
502
+ show_usage
503
+ exit 1
504
+ ;;
505
+ esac
506
+
507
+ echo ""
508
+ echo "Cleanup finished!"