@aws/nx-plugin 0.45.1 → 0.46.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.
- package/package.json +1 -1
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +3669 -0
- package/src/py/fast-api/generator.js +57 -50
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/fast-api/schema.d.ts +1 -0
- package/src/py/fast-api/schema.json +8 -0
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +590 -0
- package/src/py/mcp-server/generator.js +4 -18
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/mcp-server/schema.d.ts +1 -0
- package/src/py/mcp-server/schema.json +8 -0
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +590 -0
- package/src/py/strands-agent/generator.js +4 -18
- package/src/py/strands-agent/generator.js.map +1 -1
- package/src/py/strands-agent/schema.d.ts +1 -0
- package/src/py/strands-agent/schema.json +8 -0
- package/src/terraform/project/generator.js +23 -7
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +3669 -0
- package/src/trpc/backend/generator.js +6 -17
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/backend/schema.d.ts +1 -0
- package/src/trpc/backend/schema.json +8 -0
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +590 -0
- package/src/ts/mcp-server/generator.js +4 -18
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.d.ts +1 -0
- package/src/ts/mcp-server/schema.json +8 -0
- package/src/ts/nx-plugin/generator.js +1 -0
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +11 -5
- package/src/utils/agent-core-constructs/agent-core-constructs.js +51 -10
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +46 -0
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +536 -0
- package/src/utils/api-constructs/api-constructs.d.ts +4 -4
- package/src/utils/api-constructs/api-constructs.js +45 -5
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +382 -0
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +508 -0
- package/src/utils/api-constructs/files/terraform/core/api/http/http-api/http-api.tf.template +250 -0
- package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +150 -0
- package/src/utils/files/terraform/src/metrics/metrics.tf.template +3 -2
- package/src/utils/py.d.ts +5 -0
- package/src/utils/py.js +9 -1
- package/src/utils/py.js.map +1 -1
- package/src/utils/shared-constructs-constants.d.ts +2 -0
- package/src/utils/shared-constructs-constants.js +3 -1
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/shared-constructs.js +2 -2
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/versions.d.ts +3 -1
- package/src/utils/versions.js +2 -0
- package/src/utils/versions.js.map +1 -1
- /package/src/utils/agent-core-constructs/files/{app → cdk/app}/agent-core/__nameKebabCase__/Dockerfile.template +0 -0
- /package/src/utils/agent-core-constructs/files/{app → cdk/app}/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +0 -0
- /package/src/utils/agent-core-constructs/files/{core → cdk/core}/agent-core/runtime.ts.template +0 -0
- /package/src/utils/api-constructs/files/{app → cdk/app}/apis/http/__apiNameKebabCase__.ts.template +0 -0
- /package/src/utils/api-constructs/files/{app → cdk/app}/apis/rest/__apiNameKebabCase__.ts.template +0 -0
- /package/src/utils/api-constructs/files/{core → cdk/core}/api/http/http-api.ts.template +0 -0
- /package/src/utils/api-constructs/files/{core → cdk/core}/api/rest/rest-api.ts.template +0 -0
- /package/src/utils/api-constructs/files/{core → cdk/core}/api/trpc/trpc-utils.ts.template +0 -0
- /package/src/utils/api-constructs/files/{core → cdk/core}/api/utils/utils.ts.template +0 -0
|
@@ -297,6 +297,596 @@ export * from './runtime-config.js';
|
|
|
297
297
|
"
|
|
298
298
|
`;
|
|
299
299
|
|
|
300
|
+
exports[`py#strands-agent generator > should match snapshot for Terraform generated files > terraform-agent.tf 1`] = `
|
|
301
|
+
"variable "env" {
|
|
302
|
+
description = "Environment variables to pass to the agent core runtime"
|
|
303
|
+
type = map(string)
|
|
304
|
+
default = {}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
variable "additional_iam_policy_statements" {
|
|
308
|
+
description = "Additional IAM policy statements to attach to the agent core runtime role"
|
|
309
|
+
type = list(object({
|
|
310
|
+
Effect = string
|
|
311
|
+
Action = list(string)
|
|
312
|
+
Resource = list(string)
|
|
313
|
+
}))
|
|
314
|
+
default = []
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
variable "tags" {
|
|
318
|
+
description = "Tags to apply to resources"
|
|
319
|
+
type = map(string)
|
|
320
|
+
default = {}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
module "agent_core_runtime" {
|
|
324
|
+
source = "../../../core/agent-core"
|
|
325
|
+
agent_runtime_name = "TerraformSnapshotAgent"
|
|
326
|
+
docker_image_tag = "proj-terraform-snapshot-agent:latest"
|
|
327
|
+
server_protocol = "HTTP"
|
|
328
|
+
# customJWTAuthorizer = {
|
|
329
|
+
# discoveryUrl = "https://xxx/.well-known/openid-configuration",
|
|
330
|
+
# allowedClients = [ "xxx" ]
|
|
331
|
+
# }
|
|
332
|
+
|
|
333
|
+
env = var.env
|
|
334
|
+
additional_iam_policy_statements = var.additional_iam_policy_statements
|
|
335
|
+
tags = var.tags
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
output "agent_core_runtime_role_arn" {
|
|
339
|
+
description = "ARN of the agent core runtime role"
|
|
340
|
+
value = module.agent_core_runtime.agent_core_runtime_role_arn
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
output "agent_core_runtime_arn" {
|
|
344
|
+
description = "ARN of the Bedrock Agent Core runtime"
|
|
345
|
+
value = module.agent_core_runtime.agent_core_runtime_arn
|
|
346
|
+
}
|
|
347
|
+
"
|
|
348
|
+
`;
|
|
349
|
+
|
|
350
|
+
exports[`py#strands-agent generator > should match snapshot for Terraform generated files > terraform-agent-core-runtime.tf 1`] = `
|
|
351
|
+
"terraform {
|
|
352
|
+
required_version = ">= 1.0"
|
|
353
|
+
|
|
354
|
+
required_providers {
|
|
355
|
+
aws = {
|
|
356
|
+
source = "hashicorp/aws"
|
|
357
|
+
version = ">= 6.0"
|
|
358
|
+
}
|
|
359
|
+
null = {
|
|
360
|
+
source = "hashicorp/null"
|
|
361
|
+
version = ">= 3.0"
|
|
362
|
+
}
|
|
363
|
+
local = {
|
|
364
|
+
source = "hashicorp/local"
|
|
365
|
+
version = ">= 2.0"
|
|
366
|
+
}
|
|
367
|
+
random = {
|
|
368
|
+
source = "hashicorp/random"
|
|
369
|
+
version = ">= 3.0"
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
# Variables
|
|
375
|
+
variable "agent_runtime_name" {
|
|
376
|
+
description = "Name of the agent runtime"
|
|
377
|
+
type = string
|
|
378
|
+
validation {
|
|
379
|
+
condition = can(regex("^[a-zA-Z][a-zA-Z0-9_]{0,42}$", var.agent_runtime_name))
|
|
380
|
+
error_message = "Value must start with a letter and contain only letters, numbers, and underscores (1-43 characters)."
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
variable "server_protocol" {
|
|
385
|
+
description = "Whether this is an Agent (HTTP) or MCP Server (MCP)"
|
|
386
|
+
type = string
|
|
387
|
+
validation {
|
|
388
|
+
condition = contains(["MCP", "HTTP"], var.server_protocol)
|
|
389
|
+
error_message = "Protocol type must be either 'MCP' or 'HTTP'."
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
variable "customJWTAuthorizer" {
|
|
394
|
+
description = "Custom JWTAuthorizer Configuration"
|
|
395
|
+
type = object({
|
|
396
|
+
discoveryUrl = optional(string)
|
|
397
|
+
allowedAudience = optional(list(string))
|
|
398
|
+
allowedClients = optional(list(string))
|
|
399
|
+
})
|
|
400
|
+
default = null
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
variable "docker_image_tag" {
|
|
404
|
+
description = "Name of the docker image tag to use as the agent core runtime"
|
|
405
|
+
type = string
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
variable "env" {
|
|
409
|
+
description = "Environment variables to pass to the agent core runtime"
|
|
410
|
+
type = map(string)
|
|
411
|
+
default = {}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
variable "additional_iam_policy_statements" {
|
|
415
|
+
description = "Additional IAM policy statements to attach to the agent core runtime role"
|
|
416
|
+
type = list(object({
|
|
417
|
+
Effect = string
|
|
418
|
+
Action = list(string)
|
|
419
|
+
Resource = list(string)
|
|
420
|
+
}))
|
|
421
|
+
default = []
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
variable "tags" {
|
|
425
|
+
description = "Tags to apply to resources"
|
|
426
|
+
type = map(string)
|
|
427
|
+
default = {}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
# Data sources
|
|
431
|
+
data "aws_caller_identity" "current" {}
|
|
432
|
+
data "aws_region" "current" {}
|
|
433
|
+
|
|
434
|
+
locals {
|
|
435
|
+
aws_account_id = data.aws_caller_identity.current.account_id
|
|
436
|
+
aws_region = data.aws_region.current.name
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
# Random ID for bucket suffix to ensure uniqueness
|
|
440
|
+
resource "random_id" "unique_suffix" {
|
|
441
|
+
byte_length = 4
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
# ECR Repository
|
|
445
|
+
resource "aws_ecr_repository" "agent_core_repository" {
|
|
446
|
+
#checkov:skip=CKV_AWS_136:AES256 encryption is sufficient for ECR repositories
|
|
447
|
+
name = "\${lower(var.agent_runtime_name)}_repository_\${random_id.unique_suffix.hex}"
|
|
448
|
+
|
|
449
|
+
#checkov:skip=CKV_AWS_51:Image tag is reused for latest deployments
|
|
450
|
+
image_tag_mutability = "MUTABLE"
|
|
451
|
+
force_delete = true
|
|
452
|
+
|
|
453
|
+
image_scanning_configuration {
|
|
454
|
+
scan_on_push = true
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
tags = var.tags
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
# ECR Repository Policy
|
|
461
|
+
resource "aws_ecr_repository_policy" "agent_core_ecr_policy" {
|
|
462
|
+
repository = aws_ecr_repository.agent_core_repository.name
|
|
463
|
+
|
|
464
|
+
policy = jsonencode({
|
|
465
|
+
Version = "2012-10-17"
|
|
466
|
+
Statement = [
|
|
467
|
+
{
|
|
468
|
+
Sid = "AllowPushPull"
|
|
469
|
+
Effect = "Allow"
|
|
470
|
+
Principal = {
|
|
471
|
+
AWS = "arn:aws:iam::\${local.aws_account_id}:root"
|
|
472
|
+
}
|
|
473
|
+
Action = [
|
|
474
|
+
"ecr:GetDownloadUrlForLayer",
|
|
475
|
+
"ecr:BatchGetImage",
|
|
476
|
+
"ecr:BatchCheckLayerAvailability",
|
|
477
|
+
"ecr:PutImage",
|
|
478
|
+
"ecr:InitiateLayerUpload",
|
|
479
|
+
"ecr:UploadLayerPart",
|
|
480
|
+
"ecr:CompleteLayerUpload"
|
|
481
|
+
]
|
|
482
|
+
}
|
|
483
|
+
]
|
|
484
|
+
})
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
# IAM Role for Agent Core Runtime
|
|
488
|
+
resource "aws_iam_role" "agent_core_runtime_role" {
|
|
489
|
+
name = "\${var.agent_runtime_name}-AgentCoreRuntimeRole-\${random_id.unique_suffix.hex}"
|
|
490
|
+
|
|
491
|
+
assume_role_policy = jsonencode({
|
|
492
|
+
Version = "2012-10-17"
|
|
493
|
+
Statement = [
|
|
494
|
+
{
|
|
495
|
+
Sid = "AgentCoreAssumeRolePolicy"
|
|
496
|
+
Effect = "Allow"
|
|
497
|
+
Principal = {
|
|
498
|
+
Service = "bedrock-agentcore.amazonaws.com"
|
|
499
|
+
}
|
|
500
|
+
Action = "sts:AssumeRole"
|
|
501
|
+
Condition = {
|
|
502
|
+
StringEquals = {
|
|
503
|
+
"aws:SourceAccount" = local.aws_account_id
|
|
504
|
+
}
|
|
505
|
+
ArnLike = {
|
|
506
|
+
"aws:SourceArn" = "arn:aws:bedrock-agentcore:\${local.aws_region}:\${local.aws_account_id}:*"
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
]
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
tags = var.tags
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
# IAM Policy for Query Agent with restricted Athena permissions
|
|
517
|
+
resource "aws_iam_policy" "agent_core_runtime_policy" {
|
|
518
|
+
name = "\${var.agent_runtime_name}-QueryAgentPolicy-\${random_id.unique_suffix.hex}"
|
|
519
|
+
description = "Restricted policy for Agent"
|
|
520
|
+
|
|
521
|
+
policy = jsonencode({
|
|
522
|
+
Version = "2012-10-17"
|
|
523
|
+
Statement = concat([
|
|
524
|
+
{
|
|
525
|
+
Sid = "ECRImageAccess"
|
|
526
|
+
Effect = "Allow"
|
|
527
|
+
Action = [
|
|
528
|
+
"ecr:BatchGetImage",
|
|
529
|
+
"ecr:GetDownloadUrlForLayer"
|
|
530
|
+
]
|
|
531
|
+
Resource = [
|
|
532
|
+
"arn:aws:ecr:\${local.aws_region}:\${local.aws_account_id}:repository/*"
|
|
533
|
+
]
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
Sid = "ECRTokenAccess"
|
|
537
|
+
Effect = "Allow"
|
|
538
|
+
Action = [
|
|
539
|
+
"ecr:GetAuthorizationToken"
|
|
540
|
+
]
|
|
541
|
+
Resource = [
|
|
542
|
+
"*"
|
|
543
|
+
]
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
"Effect" : "Allow",
|
|
547
|
+
"Action" : [
|
|
548
|
+
"logs:DescribeLogStreams",
|
|
549
|
+
"logs:CreateLogGroup"
|
|
550
|
+
],
|
|
551
|
+
"Resource" : [
|
|
552
|
+
"arn:aws:logs:\${local.aws_region}:\${local.aws_account_id}:log-group:/aws/bedrock-agentcore/runtimes/*"
|
|
553
|
+
]
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"Effect" : "Allow",
|
|
557
|
+
"Action" : [
|
|
558
|
+
"logs:DescribeLogGroups"
|
|
559
|
+
],
|
|
560
|
+
"Resource" : [
|
|
561
|
+
"arn:aws:logs:\${local.aws_region}:\${local.aws_account_id}:log-group:*"
|
|
562
|
+
]
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
"Effect" : "Allow",
|
|
566
|
+
"Action" : [
|
|
567
|
+
"logs:CreateLogStream",
|
|
568
|
+
"logs:PutLogEvents"
|
|
569
|
+
],
|
|
570
|
+
"Resource" : [
|
|
571
|
+
"arn:aws:logs:\${local.aws_region}:\${local.aws_account_id}:log-group:/aws/bedrock-agentcore/runtimes/*:log-stream:*"
|
|
572
|
+
]
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
"Effect" : "Allow",
|
|
576
|
+
"Action" : [
|
|
577
|
+
"xray:PutTraceSegments",
|
|
578
|
+
"xray:PutTelemetryRecords",
|
|
579
|
+
"xray:GetSamplingRules",
|
|
580
|
+
"xray:GetSamplingTargets"
|
|
581
|
+
],
|
|
582
|
+
"Resource" : ["*"]
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
"Effect" : "Allow",
|
|
586
|
+
"Resource" : "*",
|
|
587
|
+
"Action" : "cloudwatch:PutMetricData",
|
|
588
|
+
"Condition" : {
|
|
589
|
+
"StringEquals" : {
|
|
590
|
+
"cloudwatch:namespace" : "bedrock-agentcore"
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
"Sid" : "GetAgentAccessToken",
|
|
596
|
+
"Effect" : "Allow",
|
|
597
|
+
"Action" : [
|
|
598
|
+
"bedrock-agentcore:GetWorkloadAccessToken",
|
|
599
|
+
"bedrock-agentcore:GetWorkloadAccessTokenForJWT",
|
|
600
|
+
"bedrock-agentcore:GetWorkloadAccessTokenForUserId"
|
|
601
|
+
],
|
|
602
|
+
"Resource" : [
|
|
603
|
+
"arn:aws:bedrock-agentcore:\${local.aws_region}:\${local.aws_account_id}:workload-identity-directory/default",
|
|
604
|
+
"arn:aws:bedrock-agentcore:\${local.aws_region}:\${local.aws_account_id}:workload-identity-directory/default/workload-identity/*"
|
|
605
|
+
]
|
|
606
|
+
},
|
|
607
|
+
{ "Sid" : "BedrockModelInvocation",
|
|
608
|
+
"Effect" : "Allow",
|
|
609
|
+
"Action" : [
|
|
610
|
+
"bedrock:InvokeModel",
|
|
611
|
+
"bedrock:InvokeModelWithResponseStream"
|
|
612
|
+
],
|
|
613
|
+
"Resource" : [
|
|
614
|
+
"arn:aws:bedrock:*::foundation-model/*",
|
|
615
|
+
"arn:aws:bedrock:\${local.aws_region}:\${local.aws_account_id}:*"
|
|
616
|
+
]
|
|
617
|
+
}
|
|
618
|
+
], var.additional_iam_policy_statements)
|
|
619
|
+
})
|
|
620
|
+
|
|
621
|
+
tags = var.tags
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
# Attach the restricted policy to the role
|
|
625
|
+
resource "aws_iam_role_policy_attachment" "agent_core_policy" {
|
|
626
|
+
role = aws_iam_role.agent_core_runtime_role.name
|
|
627
|
+
policy_arn = aws_iam_policy.agent_core_runtime_policy.arn
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
data "external" "docker_digest" {
|
|
631
|
+
program = ["sh", "-c", "echo '{\\"digest\\":\\"'$(docker inspect \${var.docker_image_tag} --format '{{.Descriptor.digest}}')'\\"}' "]
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
# Null resource for Docker publish
|
|
635
|
+
resource "null_resource" "docker_publish" {
|
|
636
|
+
triggers = {
|
|
637
|
+
# Trigger rebuild when the image changes
|
|
638
|
+
docker_digest = data.external.docker_digest.result.digest
|
|
639
|
+
|
|
640
|
+
repository_url = aws_ecr_repository.agent_core_repository.repository_url
|
|
641
|
+
docker_image_tag = var.docker_image_tag
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
provisioner "local-exec" {
|
|
645
|
+
command = <<-EOT
|
|
646
|
+
# Get ECR login token
|
|
647
|
+
aws ecr get-login-password --region \${local.aws_region} | docker login --username AWS --password-stdin \${self.triggers.repository_url}
|
|
648
|
+
|
|
649
|
+
# Tag the image
|
|
650
|
+
docker tag \${self.triggers.docker_image_tag} \${self.triggers.repository_url}:latest
|
|
651
|
+
|
|
652
|
+
# Push the image
|
|
653
|
+
docker push \${self.triggers.repository_url}:latest
|
|
654
|
+
EOT
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
depends_on = [aws_ecr_repository_policy.agent_core_ecr_policy]
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
# Null resource for agent core deployment with proper lifecycle management
|
|
661
|
+
resource "null_resource" "agent_core_runtime_deployment" {
|
|
662
|
+
triggers = {
|
|
663
|
+
container_uri = "\${aws_ecr_repository.agent_core_repository.repository_url}:latest"
|
|
664
|
+
role_arn = aws_iam_role.agent_core_runtime_role.arn
|
|
665
|
+
config_hash = md5(join("", [jsonencode(var.customJWTAuthorizer), var.server_protocol]))
|
|
666
|
+
env_hash = md5(jsonencode(var.env))
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
provisioner "local-exec" {
|
|
670
|
+
command = <<-EOT
|
|
671
|
+
uv run --with boto3 python -c '
|
|
672
|
+
import boto3
|
|
673
|
+
import json
|
|
674
|
+
import sys
|
|
675
|
+
|
|
676
|
+
# Create the client
|
|
677
|
+
client = boto3.client("bedrock-agentcore-control", region_name="\${local.aws_region}")
|
|
678
|
+
|
|
679
|
+
# Environment variables for QueryAgentConfig
|
|
680
|
+
environment_variables = json.loads("""\${jsonencode(var.env)}""")
|
|
681
|
+
agent_name = "\${var.agent_runtime_name}_\${random_id.unique_suffix.hex}"
|
|
682
|
+
authorization_config = json.loads("""{"customJWTAuthorizer": \${jsonencode(var.customJWTAuthorizer != null ? {
|
|
683
|
+
for k, v in var.customJWTAuthorizer : k => v if v != null
|
|
684
|
+
} : {})}}""")
|
|
685
|
+
|
|
686
|
+
try:
|
|
687
|
+
# First, check if an agent runtime with this name already exists
|
|
688
|
+
existing_agent_runtime_id = None
|
|
689
|
+
try:
|
|
690
|
+
list_response = client.list_agent_runtimes()
|
|
691
|
+
for runtime in list_response.get("agentRuntimes", []):
|
|
692
|
+
if runtime.get("agentRuntimeName") == agent_name:
|
|
693
|
+
existing_agent_runtime_id = runtime.get("agentRuntimeId")
|
|
694
|
+
print(f"Found existing agent runtime with ID: {existing_agent_runtime_id}")
|
|
695
|
+
break
|
|
696
|
+
except Exception as e:
|
|
697
|
+
print(f"Error listing agent runtimes: {e}")
|
|
698
|
+
|
|
699
|
+
if existing_agent_runtime_id:
|
|
700
|
+
# Update the existing agent runtime
|
|
701
|
+
try:
|
|
702
|
+
update_response = client.update_agent_runtime(
|
|
703
|
+
agentRuntimeId=existing_agent_runtime_id,
|
|
704
|
+
agentRuntimeArtifact={
|
|
705
|
+
"containerConfiguration": {
|
|
706
|
+
"containerUri": "\${aws_ecr_repository.agent_core_repository.repository_url}:latest"
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
environmentVariables=environment_variables,
|
|
710
|
+
networkConfiguration={"networkMode": "PUBLIC"},
|
|
711
|
+
protocolConfiguration={"serverProtocol": "\${var.server_protocol}"},
|
|
712
|
+
\${var.customJWTAuthorizer == null ? "" : "authorizerConfiguration=authorization_config,"}
|
|
713
|
+
roleArn="\${aws_iam_role.agent_core_runtime_role.arn}"
|
|
714
|
+
)
|
|
715
|
+
agent_runtime_id = existing_agent_runtime_id
|
|
716
|
+
print(f"Agent runtime updated successfully: {agent_runtime_id}")
|
|
717
|
+
except Exception as e:
|
|
718
|
+
print(f"Error updating agent runtime: {e}")
|
|
719
|
+
# If update fails, try to create a new one
|
|
720
|
+
existing_agent_runtime_id = None
|
|
721
|
+
|
|
722
|
+
if not existing_agent_runtime_id:
|
|
723
|
+
# Agent runtime doesn"t exist or update failed, create it
|
|
724
|
+
response = client.create_agent_runtime(
|
|
725
|
+
agentRuntimeName=agent_name,
|
|
726
|
+
agentRuntimeArtifact={
|
|
727
|
+
"containerConfiguration": {
|
|
728
|
+
"containerUri": "\${aws_ecr_repository.agent_core_repository.repository_url}:latest"
|
|
729
|
+
}
|
|
730
|
+
},
|
|
731
|
+
environmentVariables=environment_variables,
|
|
732
|
+
networkConfiguration={"networkMode": "PUBLIC"},
|
|
733
|
+
protocolConfiguration={"serverProtocol": "\${var.server_protocol}"},
|
|
734
|
+
\${var.customJWTAuthorizer == null ? "" : "authorizerConfiguration=authorization_config,"}
|
|
735
|
+
roleArn="\${aws_iam_role.agent_core_runtime_role.arn}"
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
agent_runtime_id = response.get("agentRuntimeId", "")
|
|
739
|
+
print(f"Agent runtime created successfully with ID: {agent_runtime_id}")
|
|
740
|
+
|
|
741
|
+
except Exception as e:
|
|
742
|
+
print(f"Error managing agent runtime: {str(e)}")
|
|
743
|
+
sys.exit(1)
|
|
744
|
+
'
|
|
745
|
+
EOT
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
depends_on = [
|
|
749
|
+
null_resource.docker_publish,
|
|
750
|
+
aws_iam_role_policy_attachment.agent_core_policy
|
|
751
|
+
]
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
# Null resource for cleanup/destroy
|
|
756
|
+
resource "null_resource" "agent_core_cleanup" {
|
|
757
|
+
triggers = {
|
|
758
|
+
aws_region = local.aws_region
|
|
759
|
+
agent_name = var.agent_runtime_name
|
|
760
|
+
unique_suffix = random_id.unique_suffix.hex
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
provisioner "local-exec" {
|
|
764
|
+
when = destroy
|
|
765
|
+
command = <<-EOT
|
|
766
|
+
uv run --with boto3 python -c "
|
|
767
|
+
import boto3
|
|
768
|
+
import json
|
|
769
|
+
import os
|
|
770
|
+
|
|
771
|
+
# Create the client
|
|
772
|
+
client = boto3.client('bedrock-agentcore-control', region_name='\${self.triggers.aws_region}')
|
|
773
|
+
|
|
774
|
+
agent_name = '\${self.triggers.agent_name}_\${self.triggers.unique_suffix}'
|
|
775
|
+
|
|
776
|
+
try:
|
|
777
|
+
# Find the agent runtime by name
|
|
778
|
+
agent_runtime_id = None
|
|
779
|
+
try:
|
|
780
|
+
list_response = client.list_agent_runtimes()
|
|
781
|
+
for runtime in list_response.get('agentRuntimes', []):
|
|
782
|
+
if runtime.get('agentRuntimeName') == agent_name:
|
|
783
|
+
agent_runtime_id = runtime.get('agentRuntimeId')
|
|
784
|
+
print(f'Found agent runtime to delete: {agent_name} (ID: {agent_runtime_id})')
|
|
785
|
+
break
|
|
786
|
+
except Exception as e:
|
|
787
|
+
print(f'Error listing agent runtimes: {e}')
|
|
788
|
+
|
|
789
|
+
if not agent_runtime_id:
|
|
790
|
+
print(f'No agent runtime found with name: {agent_name}')
|
|
791
|
+
exit(0)
|
|
792
|
+
|
|
793
|
+
# Delete the agent runtime using the found ID
|
|
794
|
+
response = client.delete_agent_runtime(
|
|
795
|
+
agentRuntimeId=agent_runtime_id
|
|
796
|
+
)
|
|
797
|
+
print(f'Agent runtime {agent_name} (ID: {agent_runtime_id}) deleted successfully:', json.dumps(response, indent=2, default=str))
|
|
798
|
+
|
|
799
|
+
except client.exceptions.ResourceNotFoundException:
|
|
800
|
+
print(f'Agent runtime {agent_name} not found, may have been already deleted')
|
|
801
|
+
except Exception as e:
|
|
802
|
+
print(f'Error deleting agent runtime {agent_name}:', str(e))
|
|
803
|
+
# Don't exit with error code during destroy to avoid blocking cleanup
|
|
804
|
+
"
|
|
805
|
+
EOT
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
depends_on = [null_resource.agent_core_runtime_deployment]
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
# Data source to find the agent runtime by name and get its ID
|
|
812
|
+
data "external" "agent_runtime_lookup" {
|
|
813
|
+
program = ["uv", "run", "--with", "boto3", "python", "-c", <<-EOT
|
|
814
|
+
import boto3
|
|
815
|
+
import json
|
|
816
|
+
import sys
|
|
817
|
+
|
|
818
|
+
# Create the client
|
|
819
|
+
client = boto3.client("bedrock-agentcore-control", region_name="\${local.aws_region}")
|
|
820
|
+
|
|
821
|
+
agent_name = "\${var.agent_runtime_name}_\${random_id.unique_suffix.hex}"
|
|
822
|
+
|
|
823
|
+
try:
|
|
824
|
+
# Find the agent runtime by name
|
|
825
|
+
list_response = client.list_agent_runtimes()
|
|
826
|
+
for runtime in list_response.get("agentRuntimes", []):
|
|
827
|
+
if runtime.get("agentRuntimeName") == agent_name:
|
|
828
|
+
agent_runtime_id = runtime.get("agentRuntimeId")
|
|
829
|
+
runtime_arn = f"arn:aws:bedrock-agentcore:\${local.aws_region}:\${local.aws_account_id}:runtime/{agent_runtime_id}"
|
|
830
|
+
|
|
831
|
+
result = {
|
|
832
|
+
"agent_runtime_id": agent_runtime_id,
|
|
833
|
+
"agent_runtime_arn": runtime_arn,
|
|
834
|
+
"agent_name": agent_name
|
|
835
|
+
}
|
|
836
|
+
print(json.dumps(result))
|
|
837
|
+
sys.exit(0)
|
|
838
|
+
|
|
839
|
+
# If not found, return empty values
|
|
840
|
+
result = {
|
|
841
|
+
"agent_runtime_id": "",
|
|
842
|
+
"agent_runtime_arn": "",
|
|
843
|
+
"agent_name": agent_name
|
|
844
|
+
}
|
|
845
|
+
print(json.dumps(result))
|
|
846
|
+
|
|
847
|
+
except Exception as e:
|
|
848
|
+
print(f"Error looking up agent runtime: {str(e)}", file=sys.stderr)
|
|
849
|
+
# Return empty values on error to avoid breaking Terraform
|
|
850
|
+
result = {
|
|
851
|
+
"agent_runtime_id": "",
|
|
852
|
+
"agent_runtime_arn": "",
|
|
853
|
+
"agent_name": agent_name
|
|
854
|
+
}
|
|
855
|
+
print(json.dumps(result))
|
|
856
|
+
EOT
|
|
857
|
+
]
|
|
858
|
+
|
|
859
|
+
depends_on = [null_resource.agent_core_runtime_deployment]
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
# Outputs
|
|
863
|
+
output "agent_core_runtime_role_arn" {
|
|
864
|
+
description = "ARN of the Agent Core Runtime IAM role"
|
|
865
|
+
value = aws_iam_role.agent_core_runtime_role.arn
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
output "agent_core_runtime_role_name" {
|
|
869
|
+
description = "Name of the Agent Core Runtime IAM role"
|
|
870
|
+
value = aws_iam_role.agent_core_runtime_role.name
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
output "agent_runtime_name" {
|
|
874
|
+
description = "Name of the deployed agent runtime"
|
|
875
|
+
value = "\${var.agent_runtime_name}-\${random_id.unique_suffix.hex}"
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
output "agent_core_runtime_arn" {
|
|
879
|
+
description = "ARN of the Bedrock Agent Core runtime"
|
|
880
|
+
value = data.external.agent_runtime_lookup.result.agent_runtime_arn
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
output "agent_runtime_id" {
|
|
884
|
+
description = "ID of the Bedrock Agent Core runtime"
|
|
885
|
+
value = data.external.agent_runtime_lookup.result.agent_runtime_id
|
|
886
|
+
}
|
|
887
|
+
"
|
|
888
|
+
`;
|
|
889
|
+
|
|
300
890
|
exports[`py#strands-agent generator > should match snapshot for generated files > strands-agent-__init__.py 1`] = `""`;
|
|
301
891
|
|
|
302
892
|
exports[`py#strands-agent generator > should match snapshot for generated files > strands-agent-agent.py 1`] = `
|
|
@@ -16,7 +16,6 @@ const agent_core_constructs_1 = require("../../utils/agent-core-constructs/agent
|
|
|
16
16
|
const bundle_1 = require("../../utils/bundle");
|
|
17
17
|
const npm_scope_1 = require("../../utils/npm-scope");
|
|
18
18
|
const shared_constructs_1 = require("../../utils/shared-constructs");
|
|
19
|
-
const shared_constructs_constants_1 = require("../../utils/shared-constructs-constants");
|
|
20
19
|
const logger_1 = require("@nxlv/python/src/executors/utils/logger");
|
|
21
20
|
const provider_1 = require("@nxlv/python/src/provider/uv/provider");
|
|
22
21
|
exports.PY_STRANDS_AGENT_GENERATOR_INFO = (0, nx_1.getGeneratorInfo)(__filename);
|
|
@@ -84,27 +83,14 @@ const pyStrandsAgentGenerator = (tree, options) => tslib_1.__awaiter(void 0, voi
|
|
|
84
83
|
'docker',
|
|
85
84
|
] });
|
|
86
85
|
// Add shared constructs
|
|
87
|
-
yield (0, shared_constructs_1.sharedConstructsGenerator)(tree);
|
|
88
|
-
// Ensure common constructs builds after our agent project
|
|
89
|
-
(0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR, 'project.json'), (config) => {
|
|
90
|
-
var _a;
|
|
91
|
-
if (!config.targets) {
|
|
92
|
-
config.targets = {};
|
|
93
|
-
}
|
|
94
|
-
if (!config.targets.build) {
|
|
95
|
-
config.targets.build = {};
|
|
96
|
-
}
|
|
97
|
-
config.targets.build.dependsOn = [
|
|
98
|
-
...((_a = config.targets.build.dependsOn) !== null && _a !== void 0 ? _a : []).filter((t) => t !== `${project.name}:build`),
|
|
99
|
-
`${project.name}:build`,
|
|
100
|
-
];
|
|
101
|
-
return config;
|
|
102
|
-
});
|
|
86
|
+
yield (0, shared_constructs_1.sharedConstructsGenerator)(tree, { iacProvider: options.iacProvider });
|
|
103
87
|
// Add the construct to deploy the agent
|
|
104
|
-
(0, agent_core_constructs_1.
|
|
88
|
+
(0, agent_core_constructs_1.addAgentInfra)(tree, {
|
|
105
89
|
agentNameKebabCase: name,
|
|
106
90
|
agentNameClassName,
|
|
107
91
|
dockerImageTag,
|
|
92
|
+
iacProvider: options.iacProvider,
|
|
93
|
+
projectName: project.name,
|
|
108
94
|
});
|
|
109
95
|
}
|
|
110
96
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/strands-agent/generator.ts"],"names":[],"mappings":";;;;AAAA;;;GAGG;AACH,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/strands-agent/generator.ts"],"names":[],"mappings":";;;;AAAA;;;GAGG;AACH,uCAQoB;AAEpB,uCAIwB;AACxB,iDAAsE;AACtE,+CAA0D;AAC1D,6CAAwE;AACxE,uCAAgE;AAChE,mGAAwF;AACxF,+CAA2D;AAC3D,qDAAoD;AACpD,qEAA0E;AAC1E,oEAAiE;AACjE,oEAAmE;AAEtD,QAAA,+BAA+B,GAC1C,IAAA,qBAAgB,EAAC,UAAU,CAAC,CAAC;AAExB,MAAM,uBAAuB,GAAG,CACrC,IAAU,EACV,OAAsC,EACV,EAAE;;IAC9B,MAAM,OAAO,GAAG,IAAA,wCAAmC,EAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3E,MAAM,aAAa,GAAG,IAAA,0BAAiB,EAAC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAExE,iDAAiD;IACjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,uBAAuB,OAAO,CAAC,OAAO,qDAAqD,CAC5F,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,gIAAgI,CACjI,CAAC;IACJ,CAAC;IAED,mDAAmD;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAG,IAAA,iBAAS,EACpB,MAAA,OAAO,CAAC,IAAI,mCAAI,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,CACpE,CAAC;IAEF,MAAM,kBAAkB,GAAG,IAAA,mBAAW,EAAC,MAAA,OAAO,CAAC,IAAI,mCAAI,OAAO,CAAC,CAAC;IAChE,MAAM,kBAAkB,GAAG,IAAA,mBAAW,EAAC,IAAI,CAAC,CAAC;IAE7C,MAAM,eAAe,GAAG,IAAA,0BAAiB,EACvC,OAAO,CAAC,UAAU,EAClB,kBAAkB,CACnB,CAAC;IACF,MAAM,OAAO,GAAG,IAAA,0BAAiB,EAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD,MAAM,WAAW,GAAG,MAAA,OAAO,CAAC,WAAW,mCAAI,yBAAyB,CAAC;IAErE,yBAAyB;IACzB,IAAA,sBAAa,EACX,IAAI,EACJ,IAAA,0BAAiB,EAAC,SAAS,EAAE,OAAO,CAAC,EACrC,eAAe,EACf;QACE,IAAI;QACJ,kBAAkB;QAClB,kBAAkB;QAClB,UAAU;QACV,OAAO;KACR,EACD,EAAE,iBAAiB,EAAE,0BAAiB,CAAC,YAAY,EAAE,CACtD,CAAC;IAEF,IAAA,mCAA8B,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;QACjD,0BAA0B;QAC1B,mBAAmB;QACnB,OAAO;QACP,KAAK;QACL,gBAAgB;QAChB,sBAAsB;KACvB,CAAC,CAAC;IAEH,IAAI,WAAW,KAAK,yBAAyB,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,GAAG,IAAA,uBAAW,EAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;QAE7D,oBAAoB;QACpB,IAAA,8BAAqB,EAAC,OAAO,EAAE;YAC7B,cAAc,EAAE,uBAAuB;SACxC,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAG,GAAG,IAAI,SAAS,CAAC;QAE1C,kDAAkD;QAClD,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG;YAClC,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,iBAAiB;YAC3B,OAAO,EAAE;gBACP,QAAQ,EAAE;oBACR,0CAA0C,cAAc,IAAI,eAAe,8BAA8B;iBAC1G;gBACD,QAAQ,EAAE,KAAK;aAChB;YACD,SAAS,EAAE,CAAC,QAAQ,CAAC;SACtB,CAAC;QAEF,OAAO,CAAC,OAAO,CAAC,MAAM,mCACjB,OAAO,CAAC,OAAO,CAAC,MAAM,KACzB,SAAS,EAAE;gBACT,GAAG,CAAC,MAAA,MAAA,OAAO,CAAC,OAAO,CAAC,MAAM,0CAAE,SAAS,mCAAI,EAAE,CAAC,CAAC,MAAM,CACjD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,gBAAgB,CAC9B;gBACD,gBAAgB;aACjB,GACF,CAAC;QAEF,OAAO,CAAC,OAAO,CAAC,KAAK,mCAChB,OAAO,CAAC,OAAO,CAAC,KAAK,KACxB,SAAS,EAAE;gBACT,GAAG,CAAC,MAAA,MAAA,OAAO,CAAC,OAAO,CAAC,KAAK,0CAAE,SAAS,mCAAI,EAAE,CAAC,CAAC,MAAM,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CACtB;gBACD,QAAQ;aACT,GACF,CAAC;QAEF,wBAAwB;QACxB,MAAM,IAAA,6CAAyB,EAAC,IAAI,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAE5E,wCAAwC;QACxC,IAAA,qCAAa,EAAC,IAAI,EAAE;YAClB,kBAAkB,EAAE,IAAI;YACxB,kBAAkB;YAClB,cAAc;YACd,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,IAAI;SAC1B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,4CAA4C;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAA,0BAAiB,EAAC,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,IAAA,mCAA0B,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,kCACxC,OAAO,KACV,OAAO,kCACF,OAAO,CAAC,OAAO;YAClB,uBAAuB;YACvB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,EAAE;gBAC1C,QAAQ,EAAE,iBAAiB;gBAC3B,OAAO,EAAE;oBACP,QAAQ,EAAE;wBACR,oBAAoB,UAAU,IAAI,kBAAkB,OAAO;qBAC5D;oBACD,GAAG,EAAE,eAAe;iBACrB;gBACD,UAAU,EAAE,IAAI;aACjB,OAEH,CAAC;IAEH,MAAM,IAAA,yCAA+B,EAAC,IAAI,EAAE;QAC1C,uCAA+B;KAChC,CAAC,CAAC;IAEH,MAAM,IAAA,6BAAoB,EAAC,IAAI,CAAC,CAAC;IACjC,OAAO,GAAS,EAAE;QAChB,IAAA,4BAAmB,EAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,IAAI,qBAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,eAAM,EAAE,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IAChE,CAAC,CAAA,CAAC;AACJ,CAAC,CAAA,CAAC;AAtJW,QAAA,uBAAuB,2BAsJlC;AAEF,kBAAe,+BAAuB,CAAC"}
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
"type": "string",
|
|
28
28
|
"description": "The name of your Strands Agent (default: agent)",
|
|
29
29
|
"x-prompt": "What would you like to call your Strands Agent? (default: agent)"
|
|
30
|
+
},
|
|
31
|
+
"iacProvider": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "The preferred IaC provider",
|
|
34
|
+
"enum": ["CDK", "Terraform"],
|
|
35
|
+
"x-priority": "important",
|
|
36
|
+
"default": "CDK",
|
|
37
|
+
"x-prompt": "Which provider would you like to manage your infrastructure? (default: CDK)"
|
|
30
38
|
}
|
|
31
39
|
},
|
|
32
40
|
"required": ["project"]
|