@aws/nx-plugin 1.0.0-rc.91 → 1.0.0-rc.92

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 (79) hide show
  1. package/migrations.json +6 -1
  2. package/package.json +1 -1
  3. package/src/internal/test-matrix/generator.js +28 -0
  4. package/src/internal/test-matrix/generator.js.map +1 -1
  5. package/src/migrations/latest/react-website-unique-dev-ports/metadata.json +3 -0
  6. package/src/migrations/latest/react-website-unique-dev-ports/migration.d.ts +6 -0
  7. package/src/migrations/latest/react-website-unique-dev-ports/migration.js +79 -0
  8. package/src/migrations/latest/react-website-unique-dev-ports/migration.js.map +1 -0
  9. package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +90 -115
  10. package/src/py/agent/files/package/main.py.template +13 -0
  11. package/src/py/agent/generator.d.ts +6 -1
  12. package/src/py/agent/generator.js +82 -45
  13. package/src/py/agent/generator.js.map +1 -1
  14. package/src/py/agent/schema.d.js.map +1 -1
  15. package/src/py/agent/schema.d.ts +2 -1
  16. package/src/py/agent/schema.json +2 -2
  17. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +64 -113
  18. package/src/py/mcp-server/files/package/main.py.template +13 -0
  19. package/src/py/mcp-server/generator.d.ts +6 -1
  20. package/src/py/mcp-server/generator.js +79 -43
  21. package/src/py/mcp-server/generator.js.map +1 -1
  22. package/src/py/mcp-server/schema.d.js.map +1 -1
  23. package/src/py/mcp-server/schema.d.ts +2 -1
  24. package/src/py/mcp-server/schema.json +2 -2
  25. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +12 -59
  26. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +77 -114
  27. package/src/ts/agent/generator.d.ts +26 -1
  28. package/src/ts/agent/generator.js +71 -45
  29. package/src/ts/agent/generator.js.map +1 -1
  30. package/src/ts/agent/schema.d.js.map +1 -1
  31. package/src/ts/agent/schema.d.ts +2 -1
  32. package/src/ts/agent/schema.json +2 -2
  33. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +64 -113
  34. package/src/ts/mcp-server/generator.d.ts +26 -1
  35. package/src/ts/mcp-server/generator.js +66 -38
  36. package/src/ts/mcp-server/generator.js.map +1 -1
  37. package/src/ts/mcp-server/schema.d.js.map +1 -1
  38. package/src/ts/mcp-server/schema.d.ts +2 -1
  39. package/src/ts/mcp-server/schema.json +2 -2
  40. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +16 -110
  41. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +2 -0
  42. package/src/ts/react-website/app/generator.js +16 -0
  43. package/src/ts/react-website/app/generator.js.map +1 -1
  44. package/src/ts/react-website/cognito-auth/generator.js +14 -2
  45. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  46. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +25 -6
  47. package/src/utils/agent-core-constructs/agent-core-constructs.js +36 -7
  48. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  49. package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +20 -4
  50. package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +34 -1
  51. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +51 -112
  52. package/src/utils/agent-core-constructs/files/terraform/core/agent-core-code/runtime.tf.template +204 -0
  53. package/src/utils/agent-core-constructs/files/terraform/core/agent-core-container/runtime.tf.template +235 -0
  54. package/src/utils/agent-core-packaging.d.ts +119 -0
  55. package/src/utils/agent-core-packaging.js +131 -0
  56. package/src/utils/agent-core-packaging.js.map +1 -0
  57. package/src/utils/agent-core-runtime-resolution.d.ts +35 -0
  58. package/src/utils/agent-core-runtime-resolution.js +68 -0
  59. package/src/utils/agent-core-runtime-resolution.js.map +1 -0
  60. package/src/utils/files/terraform/src/core/asset-ecr/asset-ecr.tf.template +137 -0
  61. package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +1 -1
  62. package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +1 -4
  63. package/src/utils/identity-constructs/identity-constructs.d.ts +22 -2
  64. package/src/utils/identity-constructs/identity-constructs.js +75 -5
  65. package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
  66. package/src/utils/port.d.ts +5 -0
  67. package/src/utils/port.js +1 -1
  68. package/src/utils/port.js.map +1 -1
  69. package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +12 -59
  70. package/src/utils/versions.d.ts +20 -0
  71. package/src/utils/versions.js +17 -0
  72. package/src/utils/versions.js.map +1 -1
  73. /package/src/ts/mcp-server/files/{http.ts.template → app/http.ts.template} +0 -0
  74. /package/src/ts/mcp-server/files/{index.ts.template → app/index.ts.template} +0 -0
  75. /package/src/ts/mcp-server/files/{resources → app/resources}/sample-guidance.ts.template +0 -0
  76. /package/src/ts/mcp-server/files/{server.ts.template → app/server.ts.template} +0 -0
  77. /package/src/ts/mcp-server/files/{stdio.ts.template → app/stdio.ts.template} +0 -0
  78. /package/src/ts/mcp-server/files/{tools → app/tools}/divide.ts.template +0 -0
  79. /package/src/ts/mcp-server/files/{Dockerfile.template → deploy/Dockerfile.template} +0 -0
@@ -57,6 +57,25 @@ import { cdkLambdaRuntimeVars, PY_VERSIONS, terraformProviderVersions, withVersi
57
57
  when: generatedTerraform
58
58
  }
59
59
  ];
60
+ /**
61
+ * The Terraform packaging module a given artifact uses, under `core/`.
62
+ *
63
+ * Each packaging module owns only its own artifact plumbing — an ECR repository
64
+ * and image push, or a code archive staged in the shared asset bucket — and
65
+ * delegates the runtime itself to the generic `core/agent-core` module. A
66
+ * workspace mixing both packagings therefore vends one copy of the runtime.
67
+ */ const terraformPackagingModule = (artifact)=>artifact.type === 'container' ? 'agent-core-container' : 'agent-core-code';
68
+ /**
69
+ * Template substitution variables describing the runtime artifact, shared by
70
+ * the CDK and Terraform branches so both read the same fields.
71
+ */ const artifactTemplateVars = (artifact)=>({
72
+ container: artifact.type === 'container',
73
+ artifactOutputDir: artifact.outputDir,
74
+ terraformPackagingModule: terraformPackagingModule(artifact),
75
+ dockerImageTag: artifact.type === 'container' ? artifact.dockerImageTag : undefined,
76
+ codeRuntime: artifact.type === 'code' ? artifact.runtime : undefined,
77
+ codeEntryPoint: artifact.type === 'code' ? artifact.entryPoint : undefined
78
+ });
60
79
  const addAgentCoreInfra = async (tree, options)=>{
61
80
  switch(options.iac){
62
81
  case 'cdk':
@@ -76,6 +95,7 @@ const addAgentCoreCDKInfra = async (tree, options)=>{
76
95
  // Generate app specific CDK construct
77
96
  generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'agent-core'), joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'app', options.appDirectory), {
78
97
  ...options,
98
+ ...artifactTemplateVars(options.artifact),
79
99
  ...esmVars(tree)
80
100
  }, {
81
101
  overwriteStrategy: OverwriteStrategy.KeepExisting
@@ -85,17 +105,28 @@ const addAgentCoreCDKInfra = async (tree, options)=>{
85
105
  await addStarExport(tree, joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'app', 'index.ts'), `./${options.appDirectory}/index.js`);
86
106
  };
87
107
  const addAgentCoreTerraformInfra = (tree, options)=>{
88
- // Add the AgentCore shared module
89
- generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'terraform', 'core', 'agent-core'), joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'core', 'agent-core'), {
108
+ const terraformCoreDir = joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'core');
109
+ const sharedModuleContext = {
90
110
  containers: options.containers,
91
111
  boto3Version: PY_VERSIONS.boto3,
112
+ ...artifactTemplateVars(options.artifact),
92
113
  ...terraformProviderVersions()
93
- }, {
114
+ };
115
+ // The generic runtime module, shared by both packagings.
116
+ generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'terraform', 'core', 'agent-core'), joinPathFragments(terraformCoreDir, 'agent-core'), sharedModuleContext, {
117
+ overwriteStrategy: OverwriteStrategy.KeepExisting
118
+ });
119
+ // The packaging module wrapping it, which owns this artifact's plumbing. Only
120
+ // the packaging in use is vended, so a code-only workspace carries no ECR
121
+ // resources and a container-only one carries no archive/upload.
122
+ const packagingModule = terraformPackagingModule(options.artifact);
123
+ generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'terraform', 'core', packagingModule), joinPathFragments(terraformCoreDir, packagingModule), sharedModuleContext, {
94
124
  overwriteStrategy: OverwriteStrategy.KeepExisting
95
125
  });
96
126
  // Generate app specific agent core configuration
97
127
  generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'terraform', 'app', 'agent-core'), joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'app', options.appDirectory), {
98
128
  ...options,
129
+ ...artifactTemplateVars(options.artifact),
99
130
  ...terraformProviderVersions()
100
131
  }, {
101
132
  overwriteStrategy: OverwriteStrategy.KeepExisting
@@ -107,8 +138,7 @@ const addAgentCoreTerraformInfra = (tree, options)=>{
107
138
  await addAgentCoreInfra(tree, {
108
139
  nameClassName: options.mcpServerNameClassName,
109
140
  nameKebabCase: options.mcpServerNameKebabCase,
110
- dockerImageTag: options.dockerImageTag,
111
- dockerOutputDir: options.dockerOutputDir,
141
+ artifact: options.artifact,
112
142
  projectName: options.projectName,
113
143
  appDirectory: 'mcp-servers',
114
144
  serverProtocol: 'mcp',
@@ -126,8 +156,7 @@ const addAgentCoreTerraformInfra = (tree, options)=>{
126
156
  nameClassName: options.agentNameClassName,
127
157
  nameKebabCase: options.agentNameKebabCase,
128
158
  projectName: options.projectName,
129
- dockerImageTag: options.dockerImageTag,
130
- dockerOutputDir: options.dockerOutputDir,
159
+ artifact: options.artifact,
131
160
  appDirectory: 'agents',
132
161
  session: options.session,
133
162
  serverProtocol: options.serverProtocol ?? 'http',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/agent-core-constructs/agent-core-constructs.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast.js';\nimport type { Containers } from '../containers.js';\nimport {\n type DeclaredPyDependency,\n type DeclaredTsDependency,\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from '../declared-dependencies.js';\nimport { addDependenciesToPackageJson } from '../dependencies.js';\nimport type { Iac } from '../iac.js';\nimport { esmVars } from '../module-format.js';\nimport { addArtifactProjectToTargets } from '../nx.js';\nimport {\n generatedCdk,\n generatedTerraform,\n type IacMetadata,\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants.js';\nimport {\n cdkLambdaRuntimeVars,\n type IPyDepVersion,\n type ITsDepVersion,\n PY_VERSIONS,\n terraformProviderVersions,\n withVersions,\n} from '../versions.js';\n\ntype IACProvider = { iac: Iac };\n\n/**\n * Dependencies a caller must declare to add an AgentCore Gateway construct.\n *\n * Both providers render Cedar policies with `ejs`, each from a different\n * manifest: the CDK construct imports it from the shared constructs project,\n * while Terraform's `render-cedar.cjs` resolves it from the workspace root,\n * since the shared terraform project it runs in has no `package.json`.\n */\nexport const AGENT_CORE_CONSTRUCTS_DEPENDENCIES = [\n { name: 'ejs', when: generatedCdk },\n { name: '@aws-sdk/client-bedrock-agentcore', when: generatedCdk },\n { name: '@types/ejs', when: generatedCdk },\n { name: 'ejs', when: generatedTerraform, dev: true, root: true },\n] as const satisfies readonly DeclaredTsDependency<\n ITsDepVersion,\n IacMetadata\n>[];\n\n/**\n * Python versions the generated Terraform pins in an inline `uv run --with`\n * script, rather than in any `pyproject.toml`.\n *\n * Spread through `ownedElsewhere` because nothing installs them into the\n * workspace — the pin is owned so the version sync keeps it current, and gated on\n * Terraform since the CDK branch writes no such script.\n */\nexport const AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES = [\n { name: 'boto3', when: generatedTerraform },\n { name: 'httpx', when: generatedTerraform },\n { name: 'mcp', when: generatedTerraform },\n] as const satisfies readonly DeclaredPyDependency<\n IPyDepVersion,\n IacMetadata\n>[];\n\nexport type AgentCoreAuth = 'iam' | 'cognito';\n\nexport type AgentCoreSession = 's3' | 'dynamodb-s3' | 'in-memory';\n\nexport interface AddAgentCoreInfraProps {\n nameClassName: string;\n nameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n appDirectory: string;\n serverProtocol: 'mcp' | 'http' | 'a2a';\n auth: AgentCoreAuth;\n /** How this runtime's session should be persisted. MCP servers have no session, so pass 'in-memory'. */\n session: AgentCoreSession;\n containers: Containers;\n}\n\nconst addAgentCoreInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps & { iac: Iac },\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreCDKInfra(tree, options);\n break;\n case 'terraform':\n addAgentCoreTerraformInfra(tree, options);\n break;\n }\n\n // Update shared constructs/terraform project configuration to depend on this project\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addArtifactProjectToTargets(config, options.projectName);\n return config;\n },\n );\n};\n\nconst addAgentCoreCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n // Generate app specific CDK construct\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'agent-core'),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n { ...options, ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export app specific CDK construct\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n 'index.ts',\n ),\n `./${options.nameKebabCase}/${options.nameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n `./${options.appDirectory}/index.js`,\n );\n};\n\nconst addAgentCoreTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n // Add the AgentCore shared module\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agent-core',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n 'agent-core',\n ),\n {\n containers: options.containers,\n boto3Version: PY_VERSIONS.boto3,\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Generate app specific agent core configuration\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agent-core',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n { ...options, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n\nexport interface AddMcpServerInfraProps {\n mcpServerNameClassName: string;\n mcpServerNameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n auth: AgentCoreAuth;\n containers: Containers;\n}\n\n/**\n * Add an MCP server CDK construct\n */\nexport const addMcpServerInfra = async (\n tree: Tree,\n options: AddMcpServerInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.mcpServerNameClassName,\n nameKebabCase: options.mcpServerNameKebabCase,\n dockerImageTag: options.dockerImageTag,\n dockerOutputDir: options.dockerOutputDir,\n projectName: options.projectName,\n appDirectory: 'mcp-servers',\n serverProtocol: 'mcp',\n iac: options.iac,\n auth: options.auth,\n // MCP servers are stateless (no conversation session to persist).\n session: 'in-memory',\n containers: options.containers,\n });\n};\n\nexport interface AddAgentInfraProps {\n agentNameClassName: string;\n agentNameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n auth: AgentCoreAuth;\n session: AgentCoreSession;\n serverProtocol?: 'http' | 'a2a';\n containers: Containers;\n}\n\n/**\n * Add an agent CDK construct\n */\nexport const addAgentInfra = async (\n tree: Tree,\n options: AddAgentInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.agentNameClassName,\n nameKebabCase: options.agentNameKebabCase,\n projectName: options.projectName,\n dockerImageTag: options.dockerImageTag,\n dockerOutputDir: options.dockerOutputDir,\n appDirectory: 'agents',\n session: options.session,\n serverProtocol: options.serverProtocol ?? 'http',\n iac: options.iac,\n auth: options.auth,\n containers: options.containers,\n });\n};\n\nexport interface AddAgentCoreGatewayInfraProps {\n gatewayNameClassName: string;\n gatewayNameKebabCase: string;\n projectName: string;\n projectDirectory: string;\n cedarPolicy: boolean;\n auth: AgentCoreAuth;\n /**\n * The gateway's protocol: mcp aggregates MCP server targets, http proxies\n * agent runtime targets via path-based routing.\n */\n protocol: 'mcp' | 'http';\n}\n\nexport const addAgentCoreGatewayInfra = async <\n const D extends DependencyDeclaration,\n>(\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps & IACProvider,\n declaration: D & MustDeclare<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES, D>,\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreGatewayCDKInfra(tree, options, declaration);\n break;\n case 'terraform':\n addAgentCoreGatewayTerraformInfra(tree, options, declaration);\n break;\n }\n\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addArtifactProjectToTargets(config, options.projectName);\n return config;\n },\n );\n};\n\nconst addAgentCoreGatewayCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n declaration: DependencyDeclaration,\n) => {\n // Generic gateway construct (readiness probe, policy engine, Cedar policy\n // loading) shared by all gateways\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...esmVars(tree), ...cdkLambdaRuntimeVars() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n protocol: options.protocol,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'index.ts',\n ),\n './agentcore-gateway/agentcore-gateway.js',\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n 'index.ts',\n ),\n `./${options.gatewayNameKebabCase}/${options.gatewayNameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './gateways/index.js',\n );\n\n // The gateway construct renders Cedar policies with ejs and its readiness\n // probe uses the AgentCore SDK client; declare both so the lint passes.\n addDependenciesToPackageJson(\n tree,\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['ejs', '@aws-sdk/client-bedrock-agentcore'],\n ),\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['@types/ejs'],\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'package.json'),\n );\n};\n\nconst addAgentCoreGatewayTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n declaration: DependencyDeclaration,\n) => {\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n protocol: options.protocol,\n boto3Version: PY_VERSIONS.boto3,\n httpxVersion: PY_VERSIONS.httpx,\n mcpVersion: PY_VERSIONS.mcp,\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // The Cedar render script is only needed when policies are enabled\n if (!options.cedarPolicy) {\n const renderScript = joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n options.gatewayNameKebabCase,\n 'render-cedar.cjs',\n );\n if (tree.exists(renderScript)) {\n tree.delete(renderScript);\n }\n return;\n }\n\n // render-cedar.cjs resolves ejs from the workspace root, since the shared\n // terraform project it runs in has no package.json.\n addDependenciesToPackageJson(\n tree,\n {},\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['ejs'],\n ),\n );\n};\n\nexport interface AddAgentCoreHarnessInfraProps {\n harnessNameClassName: string;\n harnessNameKebabCase: string;\n /**\n * Workspace-root-relative harness project root, eg `packages/my-harness`.\n * The `src/PROMPT.md` path both templates read is derived from it.\n */\n projectRoot: string;\n /** Leading-letter-guaranteed, 31-char-truncated resource name prefix. */\n harnessNamePrefix: string;\n}\n\n/**\n * Template substitution context shared by the CDK and Terraform harness\n * branches. Both prompt path fields carry the same workspace-root-relative\n * path, named per provider so each template's usage reads on its own.\n */\ninterface HarnessTemplateContext {\n nameClassName: string;\n nameKebabCase: string;\n harnessNamePrefix: string;\n /** Joined onto `findWorkspaceRoot()` in the CDK construct. */\n promptPathFromCdk: string;\n /** Appended to the `path.module` walk to the workspace root in Terraform. */\n promptPathFromTerraform: string;\n}\n\n/**\n * Add AgentCore Harness infrastructure for the selected IaC provider.\n *\n * Renders the provider-specific Harness infrastructure (a CDK construct or\n * a Terraform module) into the Shared Infrastructure Project with\n * `KeepExisting`, so existing files become user-owned and are never\n * rewritten by reruns.\n *\n * Unlike agents, MCP servers and gateways, no build dependency is added\n * from the shared infrastructure project to the Harness Project: generated\n * Harness infrastructure does not import Harness Project source, so a\n * dependency would only create false rebuild coupling.\n */\nexport const addAgentCoreHarnessInfra = async (\n tree: Tree,\n options: AddAgentCoreHarnessInfraProps & IACProvider,\n): Promise<void> => {\n // One resolved template context, built once and passed to both provider\n // branches. The prompt path is derived from the same projectRoot the\n // Harness Project is written to, so explicit placement needs no extra logic.\n const promptPath = joinPathFragments(options.projectRoot, 'src', 'PROMPT.md');\n const templateContext: HarnessTemplateContext = {\n nameClassName: options.harnessNameClassName,\n nameKebabCase: options.harnessNameKebabCase,\n harnessNamePrefix: options.harnessNamePrefix,\n promptPathFromCdk: promptPath,\n promptPathFromTerraform: promptPath,\n };\n\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreHarnessCDKInfra(tree, templateContext);\n break;\n case 'terraform':\n addAgentCoreHarnessTerraformInfra(tree, templateContext);\n break;\n }\n};\n\nconst addAgentCoreHarnessCDKInfra = async (\n tree: Tree,\n templateContext: HarnessTemplateContext,\n) => {\n // Generate the app specific CDK construct under\n // src/app/harnesses/<kebab-case-name>/\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'agentcore-harness',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'harnesses',\n ),\n { ...templateContext, ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export the construct through the harnesses app index and the shared\n // app index. addStarExport creates a missing index file and semantically\n // deduplicates equivalent exports on reruns.\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'harnesses',\n 'index.ts',\n ),\n `./${templateContext.nameKebabCase}/${templateContext.nameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './harnesses/index.js',\n );\n};\n\nconst addAgentCoreHarnessTerraformInfra = (\n tree: Tree,\n templateContext: HarnessTemplateContext,\n) => {\n // Generate the app specific Terraform module under\n // src/app/harnesses/<kebab-case-name>/. No CDK files or exports are\n // created on this path.\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agentcore-harness',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'harnesses',\n ),\n { ...templateContext, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateJson","addStarExport","forDependencies","addDependenciesToPackageJson","esmVars","addArtifactProjectToTargets","generatedCdk","generatedTerraform","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","cdkLambdaRuntimeVars","PY_VERSIONS","terraformProviderVersions","withVersions","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","name","when","dev","root","AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES","addAgentCoreInfra","tree","options","iac","addAgentCoreCDKInfra","addAgentCoreTerraformInfra","config","projectName","dirname","appDirectory","overwriteStrategy","KeepExisting","nameKebabCase","containers","boto3Version","boto3","addMcpServerInfra","nameClassName","mcpServerNameClassName","mcpServerNameKebabCase","dockerImageTag","dockerOutputDir","serverProtocol","auth","session","addAgentInfra","agentNameClassName","agentNameKebabCase","addAgentCoreGatewayInfra","declaration","addAgentCoreGatewayCDKInfra","addAgentCoreGatewayTerraformInfra","gatewayNameClassName","gatewayNameKebabCase","projectDirectory","cedarPolicy","protocol","httpxVersion","httpx","mcpVersion","mcp","renderScript","exists","delete","addAgentCoreHarnessInfra","promptPath","projectRoot","templateContext","harnessNameClassName","harnessNameKebabCase","harnessNamePrefix","promptPathFromCdk","promptPathFromTerraform","addAgentCoreHarnessCDKInfra","addAgentCoreHarnessTerraformInfra"],"mappings":"AAAA;;;CAGC,GACD,SACEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EAGjBC,UAAU,QACL,aAAa;AACpB,SAASC,aAAa,QAAQ,YAAY;AAE1C,SAIEC,eAAe,QAEV,8BAA8B;AACrC,SAASC,4BAA4B,QAAQ,qBAAqB;AAElE,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,2BAA2B,QAAQ,WAAW;AACvD,SACEC,YAAY,EACZC,kBAAkB,EAElBC,YAAY,EACZC,qBAAqB,EACrBC,oBAAoB,QACf,oCAAoC;AAC3C,SACEC,oBAAoB,EAGpBC,WAAW,EACXC,yBAAyB,EACzBC,YAAY,QACP,iBAAiB;AAIxB;;;;;;;CAOC,GACD,OAAO,MAAMC,qCAAqC;IAChD;QAAEC,MAAM;QAAOC,MAAMX;IAAa;IAClC;QAAEU,MAAM;QAAqCC,MAAMX;IAAa;IAChE;QAAEU,MAAM;QAAcC,MAAMX;IAAa;IACzC;QAAEU,MAAM;QAAOC,MAAMV;QAAoBW,KAAK;QAAMC,MAAM;IAAK;CAChE,CAGG;AAEJ;;;;;;;CAOC,GACD,OAAO,MAAMC,wCAAwC;IACnD;QAAEJ,MAAM;QAASC,MAAMV;IAAmB;IAC1C;QAAES,MAAM;QAASC,MAAMV;IAAmB;IAC1C;QAAES,MAAM;QAAOC,MAAMV;IAAmB;CACzC,CAGG;AAoBJ,MAAMc,oBAAoB,OACxBC,MACAC;IAEA,OAAQA,QAAQC,GAAG;QACjB,KAAK;YACH,MAAMC,qBAAqBH,MAAMC;YACjC;QACF,KAAK;YACHG,2BAA2BJ,MAAMC;YACjC;IACJ;IAEA,qFAAqF;IACrFvB,WACEsB,MACAxB,kBACEU,cACAe,QAAQC,GAAG,KAAK,QAAQf,wBAAwBC,sBAChD,iBAEF,CAACiB;QACCtB,4BAA4BsB,QAAQJ,QAAQK,WAAW;QACvD,OAAOD;IACT;AAEJ;AAEA,MAAMF,uBAAuB,OAC3BH,MACAC;IAEA,sCAAsC;IACtC1B,cACEyB,MACAxB,kBAAkB,YAAY+B,OAAO,EAAE,SAAS,OAAO,OAAO,eAC9D/B,kBACEU,cACAC,uBACA,OACA,OACAc,QAAQO,YAAY,GAEtB;QAAE,GAAGP,OAAO;QAAE,GAAGnB,QAAQkB,KAAK;IAAC,GAC/B;QACES,mBAAmBhC,kBAAkBiC,YAAY;IACnD;IAGF,oCAAoC;IACpC,MAAM/B,cACJqB,MACAxB,kBACEU,cACAC,uBACA,OACA,OACAc,QAAQO,YAAY,EACpB,aAEF,CAAC,EAAE,EAAEP,QAAQU,aAAa,CAAC,CAAC,EAAEV,QAAQU,aAAa,CAAC,GAAG,CAAC;IAE1D,MAAMhC,cACJqB,MACAxB,kBACEU,cACAC,uBACA,OACA,OACA,aAEF,CAAC,EAAE,EAAEc,QAAQO,YAAY,CAAC,SAAS,CAAC;AAExC;AAEA,MAAMJ,6BAA6B,CACjCJ,MACAC;IAEA,kCAAkC;IAClC1B,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,aACA,QACA,eAEF/B,kBACEU,cACAE,sBACA,OACA,QACA,eAEF;QACEwB,YAAYX,QAAQW,UAAU;QAC9BC,cAAcvB,YAAYwB,KAAK;QAC/B,GAAGvB,2BAA2B;IAChC,GACA;QACEkB,mBAAmBhC,kBAAkBiC,YAAY;IACnD;IAGF,iDAAiD;IACjDnC,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,aACA,OACA,eAEF/B,kBACEU,cACAE,sBACA,OACA,OACAa,QAAQO,YAAY,GAEtB;QAAE,GAAGP,OAAO;QAAE,GAAGV,2BAA2B;IAAC,GAC7C;QACEkB,mBAAmBhC,kBAAkBiC,YAAY;IACnD;AAEJ;AAYA;;CAEC,GACD,OAAO,MAAMK,oBAAoB,OAC/Bf,MACAC;IAEA,MAAMF,kBAAkBC,MAAM;QAC5BgB,eAAef,QAAQgB,sBAAsB;QAC7CN,eAAeV,QAAQiB,sBAAsB;QAC7CC,gBAAgBlB,QAAQkB,cAAc;QACtCC,iBAAiBnB,QAAQmB,eAAe;QACxCd,aAAaL,QAAQK,WAAW;QAChCE,cAAc;QACda,gBAAgB;QAChBnB,KAAKD,QAAQC,GAAG;QAChBoB,MAAMrB,QAAQqB,IAAI;QAClB,kEAAkE;QAClEC,SAAS;QACTX,YAAYX,QAAQW,UAAU;IAChC;AACF,EAAE;AAcF;;CAEC,GACD,OAAO,MAAMY,gBAAgB,OAC3BxB,MACAC;IAEA,MAAMF,kBAAkBC,MAAM;QAC5BgB,eAAef,QAAQwB,kBAAkB;QACzCd,eAAeV,QAAQyB,kBAAkB;QACzCpB,aAAaL,QAAQK,WAAW;QAChCa,gBAAgBlB,QAAQkB,cAAc;QACtCC,iBAAiBnB,QAAQmB,eAAe;QACxCZ,cAAc;QACde,SAAStB,QAAQsB,OAAO;QACxBF,gBAAgBpB,QAAQoB,cAAc,IAAI;QAC1CnB,KAAKD,QAAQC,GAAG;QAChBoB,MAAMrB,QAAQqB,IAAI;QAClBV,YAAYX,QAAQW,UAAU;IAChC;AACF,EAAE;AAgBF,OAAO,MAAMe,2BAA2B,OAGtC3B,MACAC,SACA2B;IAEA,OAAQ3B,QAAQC,GAAG;QACjB,KAAK;YACH,MAAM2B,4BAA4B7B,MAAMC,SAAS2B;YACjD;QACF,KAAK;YACHE,kCAAkC9B,MAAMC,SAAS2B;YACjD;IACJ;IAEAlD,WACEsB,MACAxB,kBACEU,cACAe,QAAQC,GAAG,KAAK,QAAQf,wBAAwBC,sBAChD,iBAEF,CAACiB;QACCtB,4BAA4BsB,QAAQJ,QAAQK,WAAW;QACvD,OAAOD;IACT;AAEJ,EAAE;AAEF,MAAMwB,8BAA8B,OAClC7B,MACAC,SACA2B;IAEA,0EAA0E;IAC1E,kCAAkC;IAClCrD,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,OACA,QACA,sBAEF/B,kBACEU,cACAC,uBACA,OACA,QACA,sBAEF;QAAE,GAAGL,QAAQkB,KAAK;QAAE,GAAGX,sBAAsB;IAAC,GAC9C;QACEoB,mBAAmBhC,kBAAkBiC,YAAY;IACnD;IAGFnC,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,OACA,OACA,sBAEF/B,kBACEU,cACAC,uBACA,OACA,OACA,aAEF;QACE6B,eAAef,QAAQ8B,oBAAoB;QAC3CpB,eAAeV,QAAQ+B,oBAAoB;QAC3CC,kBAAkBhC,QAAQgC,gBAAgB;QAC1CC,aAAajC,QAAQiC,WAAW;QAChCZ,MAAMrB,QAAQqB,IAAI;QAClBa,UAAUlC,QAAQkC,QAAQ;QAC1B,GAAGrD,QAAQkB,KAAK;IAClB,GACA;QACES,mBAAmBhC,kBAAkBiC,YAAY;IACnD;IAGF,MAAM/B,cACJqB,MACAxB,kBACEU,cACAC,uBACA,OACA,QACA,aAEF;IAEF,MAAMR,cACJqB,MACAxB,kBACEU,cACAC,uBACA,OACA,OACA,YACA,aAEF,CAAC,EAAE,EAAEc,QAAQ+B,oBAAoB,CAAC,CAAC,EAAE/B,QAAQ+B,oBAAoB,CAAC,GAAG,CAAC;IAExE,MAAMrD,cACJqB,MACAxB,kBACEU,cACAC,uBACA,OACA,OACA,aAEF;IAGF,0EAA0E;IAC1E,wEAAwE;IACxEN,6BACEmB,MACAR,aACEZ,gBAA2DgD,cAC3D;QAAC;QAAO;KAAoC,GAE9CpC,aACEZ,gBAA2DgD,cAC3D;QAAC;KAAa,GAEhBpD,kBAAkBU,cAAcC,uBAAuB;AAE3D;AAEA,MAAM2C,oCAAoC,CACxC9B,MACAC,SACA2B;IAEArD,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,aACA,QACA,sBAEF/B,kBACEU,cACAE,sBACA,OACA,QACA,sBAEF;QAAE,GAAGG,2BAA2B;IAAC,GACjC;QACEkB,mBAAmBhC,kBAAkBiC,YAAY;IACnD;IAGFnC,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,aACA,OACA,sBAEF/B,kBACEU,cACAE,sBACA,OACA,OACA,aAEF;QACE4B,eAAef,QAAQ8B,oBAAoB;QAC3CpB,eAAeV,QAAQ+B,oBAAoB;QAC3CC,kBAAkBhC,QAAQgC,gBAAgB;QAC1CC,aAAajC,QAAQiC,WAAW;QAChCZ,MAAMrB,QAAQqB,IAAI;QAClBa,UAAUlC,QAAQkC,QAAQ;QAC1BtB,cAAcvB,YAAYwB,KAAK;QAC/BsB,cAAc9C,YAAY+C,KAAK;QAC/BC,YAAYhD,YAAYiD,GAAG;QAC3B,GAAGhD,2BAA2B;IAChC,GACA;QACEkB,mBAAmBhC,kBAAkBiC,YAAY;IACnD;IAGF,mEAAmE;IACnE,IAAI,CAACT,QAAQiC,WAAW,EAAE;QACxB,MAAMM,eAAehE,kBACnBU,cACAE,sBACA,OACA,OACA,YACAa,QAAQ+B,oBAAoB,EAC5B;QAEF,IAAIhC,KAAKyC,MAAM,CAACD,eAAe;YAC7BxC,KAAK0C,MAAM,CAACF;QACd;QACA;IACF;IAEA,0EAA0E;IAC1E,oDAAoD;IACpD3D,6BACEmB,MACA,CAAC,GACDR,aACEZ,gBAA2DgD,cAC3D;QAAC;KAAM;AAGb;AA6BA;;;;;;;;;;;;CAYC,GACD,OAAO,MAAMe,2BAA2B,OACtC3C,MACAC;IAEA,wEAAwE;IACxE,qEAAqE;IACrE,6EAA6E;IAC7E,MAAM2C,aAAapE,kBAAkByB,QAAQ4C,WAAW,EAAE,OAAO;IACjE,MAAMC,kBAA0C;QAC9C9B,eAAef,QAAQ8C,oBAAoB;QAC3CpC,eAAeV,QAAQ+C,oBAAoB;QAC3CC,mBAAmBhD,QAAQgD,iBAAiB;QAC5CC,mBAAmBN;QACnBO,yBAAyBP;IAC3B;IAEA,OAAQ3C,QAAQC,GAAG;QACjB,KAAK;YACH,MAAMkD,4BAA4BpD,MAAM8C;YACxC;QACF,KAAK;YACHO,kCAAkCrD,MAAM8C;YACxC;IACJ;AACF,EAAE;AAEF,MAAMM,8BAA8B,OAClCpD,MACA8C;IAEA,gDAAgD;IAChD,uCAAuC;IACvCvE,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,OACA,OACA,sBAEF/B,kBACEU,cACAC,uBACA,OACA,OACA,cAEF;QAAE,GAAG2D,eAAe;QAAE,GAAGhE,QAAQkB,KAAK;IAAC,GACvC;QACES,mBAAmBhC,kBAAkBiC,YAAY;IACnD;IAGF,sEAAsE;IACtE,yEAAyE;IACzE,6CAA6C;IAC7C,MAAM/B,cACJqB,MACAxB,kBACEU,cACAC,uBACA,OACA,OACA,aACA,aAEF,CAAC,EAAE,EAAE2D,gBAAgBnC,aAAa,CAAC,CAAC,EAAEmC,gBAAgBnC,aAAa,CAAC,GAAG,CAAC;IAE1E,MAAMhC,cACJqB,MACAxB,kBACEU,cACAC,uBACA,OACA,OACA,aAEF;AAEJ;AAEA,MAAMkE,oCAAoC,CACxCrD,MACA8C;IAEA,mDAAmD;IACnD,oEAAoE;IACpE,wBAAwB;IACxBvE,cACEyB,MACAxB,kBACE,YAAY+B,OAAO,EACnB,SACA,aACA,OACA,sBAEF/B,kBACEU,cACAE,sBACA,OACA,OACA,cAEF;QAAE,GAAG0D,eAAe;QAAE,GAAGvD,2BAA2B;IAAC,GACrD;QACEkB,mBAAmBhC,kBAAkBiC,YAAY;IACnD;AAEJ"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/agent-core-constructs/agent-core-constructs.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast.js';\nimport type { Containers } from '../containers.js';\nimport {\n type DeclaredPyDependency,\n type DeclaredTsDependency,\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from '../declared-dependencies.js';\nimport { addDependenciesToPackageJson } from '../dependencies.js';\nimport type { Iac } from '../iac.js';\nimport { esmVars } from '../module-format.js';\nimport { addArtifactProjectToTargets } from '../nx.js';\nimport {\n generatedCdk,\n generatedTerraform,\n type IacMetadata,\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants.js';\nimport {\n cdkLambdaRuntimeVars,\n type IPyDepVersion,\n type ITsDepVersion,\n PY_VERSIONS,\n terraformProviderVersions,\n withVersions,\n} from '../versions.js';\n\ntype IACProvider = { iac: Iac };\n\n/**\n * Dependencies a caller must declare to add an AgentCore Gateway construct.\n *\n * Both providers render Cedar policies with `ejs`, each from a different\n * manifest: the CDK construct imports it from the shared constructs project,\n * while Terraform's `render-cedar.cjs` resolves it from the workspace root,\n * since the shared terraform project it runs in has no `package.json`.\n */\nexport const AGENT_CORE_CONSTRUCTS_DEPENDENCIES = [\n { name: 'ejs', when: generatedCdk },\n { name: '@aws-sdk/client-bedrock-agentcore', when: generatedCdk },\n { name: '@types/ejs', when: generatedCdk },\n { name: 'ejs', when: generatedTerraform, dev: true, root: true },\n] as const satisfies readonly DeclaredTsDependency<\n ITsDepVersion,\n IacMetadata\n>[];\n\n/**\n * Python versions the generated Terraform pins in an inline `uv run --with`\n * script, rather than in any `pyproject.toml`.\n *\n * Spread through `ownedElsewhere` because nothing installs them into the\n * workspace — the pin is owned so the version sync keeps it current, and gated on\n * Terraform since the CDK branch writes no such script.\n */\nexport const AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES = [\n { name: 'boto3', when: generatedTerraform },\n { name: 'httpx', when: generatedTerraform },\n { name: 'mcp', when: generatedTerraform },\n] as const satisfies readonly DeclaredPyDependency<\n IPyDepVersion,\n IacMetadata\n>[];\n\nexport type AgentCoreAuth = 'iam' | 'cognito';\n\nexport type AgentCoreSession = 's3' | 'dynamodb-s3' | 'in-memory';\n\n/**\n * How the runtime's artifact is packaged, and the details each packaging needs.\n *\n * `container` builds an arm64 image from a Dockerfile and hosts it from ECR.\n * `code` uploads a zip of the built code to S3 and runs it on an AgentCore\n * managed language runtime.\n */\nexport type AgentCoreArtifact =\n | {\n readonly type: 'container';\n /** Local image tag the build produces, published to ECR by Terraform. */\n readonly dockerImageTag: string;\n /** Build context directory, holding the Dockerfile and built artifacts. */\n readonly outputDir: string;\n }\n | {\n readonly type: 'code';\n /** Packaged code directory, archived and uploaded as the artifact. */\n readonly outputDir: string;\n /** Managed language runtime, e.g. `NODE_22` or `PYTHON_3_14`. */\n readonly runtime: string;\n /** Entry point file within the package, run by the managed runtime. */\n readonly entryPoint: string;\n };\n\nexport interface AddAgentCoreInfraProps {\n nameClassName: string;\n nameKebabCase: string;\n projectName: string;\n artifact: AgentCoreArtifact;\n appDirectory: string;\n serverProtocol: 'mcp' | 'http' | 'a2a';\n auth: AgentCoreAuth;\n /** How this runtime's session should be persisted. MCP servers have no session, so pass 'in-memory'. */\n session: AgentCoreSession;\n containers: Containers;\n}\n\n/**\n * The Terraform packaging module a given artifact uses, under `core/`.\n *\n * Each packaging module owns only its own artifact plumbing — an ECR repository\n * and image push, or a code archive staged in the shared asset bucket — and\n * delegates the runtime itself to the generic `core/agent-core` module. A\n * workspace mixing both packagings therefore vends one copy of the runtime.\n */\nconst terraformPackagingModule = (artifact: AgentCoreArtifact): string =>\n artifact.type === 'container' ? 'agent-core-container' : 'agent-core-code';\n\n/**\n * Template substitution variables describing the runtime artifact, shared by\n * the CDK and Terraform branches so both read the same fields.\n */\nconst artifactTemplateVars = (artifact: AgentCoreArtifact) => ({\n container: artifact.type === 'container',\n artifactOutputDir: artifact.outputDir,\n terraformPackagingModule: terraformPackagingModule(artifact),\n dockerImageTag:\n artifact.type === 'container' ? artifact.dockerImageTag : undefined,\n codeRuntime: artifact.type === 'code' ? artifact.runtime : undefined,\n codeEntryPoint: artifact.type === 'code' ? artifact.entryPoint : undefined,\n});\n\nconst addAgentCoreInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps & { iac: Iac },\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreCDKInfra(tree, options);\n break;\n case 'terraform':\n addAgentCoreTerraformInfra(tree, options);\n break;\n }\n\n // Update shared constructs/terraform project configuration to depend on this project\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addArtifactProjectToTargets(config, options.projectName);\n return config;\n },\n );\n};\n\nconst addAgentCoreCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n // Generate app specific CDK construct\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'agent-core'),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n {\n ...options,\n ...artifactTemplateVars(options.artifact),\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export app specific CDK construct\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n 'index.ts',\n ),\n `./${options.nameKebabCase}/${options.nameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n `./${options.appDirectory}/index.js`,\n );\n};\n\nconst addAgentCoreTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n const terraformCoreDir = joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n );\n const sharedModuleContext = {\n containers: options.containers,\n boto3Version: PY_VERSIONS.boto3,\n ...artifactTemplateVars(options.artifact),\n ...terraformProviderVersions(),\n };\n\n // The generic runtime module, shared by both packagings.\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agent-core',\n ),\n joinPathFragments(terraformCoreDir, 'agent-core'),\n sharedModuleContext,\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // The packaging module wrapping it, which owns this artifact's plumbing. Only\n // the packaging in use is vended, so a code-only workspace carries no ECR\n // resources and a container-only one carries no archive/upload.\n const packagingModule = terraformPackagingModule(options.artifact);\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n packagingModule,\n ),\n joinPathFragments(terraformCoreDir, packagingModule),\n sharedModuleContext,\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Generate app specific agent core configuration\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agent-core',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n {\n ...options,\n ...artifactTemplateVars(options.artifact),\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n\nexport interface AddMcpServerInfraProps {\n mcpServerNameClassName: string;\n mcpServerNameKebabCase: string;\n projectName: string;\n artifact: AgentCoreArtifact;\n auth: AgentCoreAuth;\n containers: Containers;\n}\n\n/**\n * Add an MCP server CDK construct\n */\nexport const addMcpServerInfra = async (\n tree: Tree,\n options: AddMcpServerInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.mcpServerNameClassName,\n nameKebabCase: options.mcpServerNameKebabCase,\n artifact: options.artifact,\n projectName: options.projectName,\n appDirectory: 'mcp-servers',\n serverProtocol: 'mcp',\n iac: options.iac,\n auth: options.auth,\n // MCP servers are stateless (no conversation session to persist).\n session: 'in-memory',\n containers: options.containers,\n });\n};\n\nexport interface AddAgentInfraProps {\n agentNameClassName: string;\n agentNameKebabCase: string;\n projectName: string;\n artifact: AgentCoreArtifact;\n auth: AgentCoreAuth;\n session: AgentCoreSession;\n serverProtocol?: 'http' | 'a2a';\n containers: Containers;\n}\n\n/**\n * Add an agent CDK construct\n */\nexport const addAgentInfra = async (\n tree: Tree,\n options: AddAgentInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.agentNameClassName,\n nameKebabCase: options.agentNameKebabCase,\n projectName: options.projectName,\n artifact: options.artifact,\n appDirectory: 'agents',\n session: options.session,\n serverProtocol: options.serverProtocol ?? 'http',\n iac: options.iac,\n auth: options.auth,\n containers: options.containers,\n });\n};\n\nexport interface AddAgentCoreGatewayInfraProps {\n gatewayNameClassName: string;\n gatewayNameKebabCase: string;\n projectName: string;\n projectDirectory: string;\n cedarPolicy: boolean;\n auth: AgentCoreAuth;\n /**\n * The gateway's protocol: mcp aggregates MCP server targets, http proxies\n * agent runtime targets via path-based routing.\n */\n protocol: 'mcp' | 'http';\n}\n\nexport const addAgentCoreGatewayInfra = async <\n const D extends DependencyDeclaration,\n>(\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps & IACProvider,\n declaration: D & MustDeclare<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES, D>,\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreGatewayCDKInfra(tree, options, declaration);\n break;\n case 'terraform':\n addAgentCoreGatewayTerraformInfra(tree, options, declaration);\n break;\n }\n\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addArtifactProjectToTargets(config, options.projectName);\n return config;\n },\n );\n};\n\nconst addAgentCoreGatewayCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n declaration: DependencyDeclaration,\n) => {\n // Generic gateway construct (readiness probe, policy engine, Cedar policy\n // loading) shared by all gateways\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...esmVars(tree), ...cdkLambdaRuntimeVars() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n protocol: options.protocol,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'index.ts',\n ),\n './agentcore-gateway/agentcore-gateway.js',\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n 'index.ts',\n ),\n `./${options.gatewayNameKebabCase}/${options.gatewayNameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './gateways/index.js',\n );\n\n // The gateway construct renders Cedar policies with ejs and its readiness\n // probe uses the AgentCore SDK client; declare both so the lint passes.\n addDependenciesToPackageJson(\n tree,\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['ejs', '@aws-sdk/client-bedrock-agentcore'],\n ),\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['@types/ejs'],\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'package.json'),\n );\n};\n\nconst addAgentCoreGatewayTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n declaration: DependencyDeclaration,\n) => {\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n protocol: options.protocol,\n boto3Version: PY_VERSIONS.boto3,\n httpxVersion: PY_VERSIONS.httpx,\n mcpVersion: PY_VERSIONS.mcp,\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // The Cedar render script is only needed when policies are enabled\n if (!options.cedarPolicy) {\n const renderScript = joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n options.gatewayNameKebabCase,\n 'render-cedar.cjs',\n );\n if (tree.exists(renderScript)) {\n tree.delete(renderScript);\n }\n return;\n }\n\n // render-cedar.cjs resolves ejs from the workspace root, since the shared\n // terraform project it runs in has no package.json.\n addDependenciesToPackageJson(\n tree,\n {},\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['ejs'],\n ),\n );\n};\n\nexport interface AddAgentCoreHarnessInfraProps {\n harnessNameClassName: string;\n harnessNameKebabCase: string;\n /**\n * Workspace-root-relative harness project root, eg `packages/my-harness`.\n * The `src/PROMPT.md` path both templates read is derived from it.\n */\n projectRoot: string;\n /** Leading-letter-guaranteed, 31-char-truncated resource name prefix. */\n harnessNamePrefix: string;\n}\n\n/**\n * Template substitution context shared by the CDK and Terraform harness\n * branches. Both prompt path fields carry the same workspace-root-relative\n * path, named per provider so each template's usage reads on its own.\n */\ninterface HarnessTemplateContext {\n nameClassName: string;\n nameKebabCase: string;\n harnessNamePrefix: string;\n /** Joined onto `findWorkspaceRoot()` in the CDK construct. */\n promptPathFromCdk: string;\n /** Appended to the `path.module` walk to the workspace root in Terraform. */\n promptPathFromTerraform: string;\n}\n\n/**\n * Add AgentCore Harness infrastructure for the selected IaC provider.\n *\n * Renders the provider-specific Harness infrastructure (a CDK construct or\n * a Terraform module) into the Shared Infrastructure Project with\n * `KeepExisting`, so existing files become user-owned and are never\n * rewritten by reruns.\n *\n * Unlike agents, MCP servers and gateways, no build dependency is added\n * from the shared infrastructure project to the Harness Project: generated\n * Harness infrastructure does not import Harness Project source, so a\n * dependency would only create false rebuild coupling.\n */\nexport const addAgentCoreHarnessInfra = async (\n tree: Tree,\n options: AddAgentCoreHarnessInfraProps & IACProvider,\n): Promise<void> => {\n // One resolved template context, built once and passed to both provider\n // branches. The prompt path is derived from the same projectRoot the\n // Harness Project is written to, so explicit placement needs no extra logic.\n const promptPath = joinPathFragments(options.projectRoot, 'src', 'PROMPT.md');\n const templateContext: HarnessTemplateContext = {\n nameClassName: options.harnessNameClassName,\n nameKebabCase: options.harnessNameKebabCase,\n harnessNamePrefix: options.harnessNamePrefix,\n promptPathFromCdk: promptPath,\n promptPathFromTerraform: promptPath,\n };\n\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreHarnessCDKInfra(tree, templateContext);\n break;\n case 'terraform':\n addAgentCoreHarnessTerraformInfra(tree, templateContext);\n break;\n }\n};\n\nconst addAgentCoreHarnessCDKInfra = async (\n tree: Tree,\n templateContext: HarnessTemplateContext,\n) => {\n // Generate the app specific CDK construct under\n // src/app/harnesses/<kebab-case-name>/\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'agentcore-harness',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'harnesses',\n ),\n { ...templateContext, ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export the construct through the harnesses app index and the shared\n // app index. addStarExport creates a missing index file and semantically\n // deduplicates equivalent exports on reruns.\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'harnesses',\n 'index.ts',\n ),\n `./${templateContext.nameKebabCase}/${templateContext.nameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './harnesses/index.js',\n );\n};\n\nconst addAgentCoreHarnessTerraformInfra = (\n tree: Tree,\n templateContext: HarnessTemplateContext,\n) => {\n // Generate the app specific Terraform module under\n // src/app/harnesses/<kebab-case-name>/. No CDK files or exports are\n // created on this path.\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agentcore-harness',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'harnesses',\n ),\n { ...templateContext, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateJson","addStarExport","forDependencies","addDependenciesToPackageJson","esmVars","addArtifactProjectToTargets","generatedCdk","generatedTerraform","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","cdkLambdaRuntimeVars","PY_VERSIONS","terraformProviderVersions","withVersions","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","name","when","dev","root","AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES","terraformPackagingModule","artifact","type","artifactTemplateVars","container","artifactOutputDir","outputDir","dockerImageTag","undefined","codeRuntime","runtime","codeEntryPoint","entryPoint","addAgentCoreInfra","tree","options","iac","addAgentCoreCDKInfra","addAgentCoreTerraformInfra","config","projectName","dirname","appDirectory","overwriteStrategy","KeepExisting","nameKebabCase","terraformCoreDir","sharedModuleContext","containers","boto3Version","boto3","packagingModule","addMcpServerInfra","nameClassName","mcpServerNameClassName","mcpServerNameKebabCase","serverProtocol","auth","session","addAgentInfra","agentNameClassName","agentNameKebabCase","addAgentCoreGatewayInfra","declaration","addAgentCoreGatewayCDKInfra","addAgentCoreGatewayTerraformInfra","gatewayNameClassName","gatewayNameKebabCase","projectDirectory","cedarPolicy","protocol","httpxVersion","httpx","mcpVersion","mcp","renderScript","exists","delete","addAgentCoreHarnessInfra","promptPath","projectRoot","templateContext","harnessNameClassName","harnessNameKebabCase","harnessNamePrefix","promptPathFromCdk","promptPathFromTerraform","addAgentCoreHarnessCDKInfra","addAgentCoreHarnessTerraformInfra"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  <%_ const hasSessionBucket = session === 's3' || session === 'dynamodb-s3'; _%>
2
2
  import { Fn, Lazy, Names<%_ if (hasSessionBucket) { _%>, RemovalPolicy<%_ } _%>, Stack } from 'aws-cdk-lib';
3
+ <%_ if (container) { _%>
3
4
  import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
5
+ <%_ } _%>
4
6
  import { Connections, IConnectable } from 'aws-cdk-lib/aws-ec2';
5
7
  <%_ if (hasSessionBucket) { _%>
6
8
  import { BlockPublicAccess, Bucket, BucketEncryption } from 'aws-cdk-lib/aws-s3';
@@ -25,6 +27,9 @@ import { Construct } from 'constructs';
25
27
  import * as path from 'path';
26
28
  import * as url from 'url';
27
29
  import {
30
+ <%_ if (!container) { _%>
31
+ AgentCoreRuntime,
32
+ <%_ } _%>
28
33
  AgentRuntimeArtifact,
29
34
  ProtocolType,
30
35
  Runtime,
@@ -123,7 +128,7 @@ export type <%- nameClassName %>Props = Omit<
123
128
  <%_ } _%>
124
129
 
125
130
  export class <%- nameClassName %> extends Construct implements IGrantable, IConnectable {
126
- public readonly dockerImage: AgentRuntimeArtifact;
131
+ public readonly <%- container ? 'dockerImage' : 'code' %>: AgentRuntimeArtifact;
127
132
  public readonly agentCoreRuntime: Runtime;
128
133
  <%_ if (serverProtocol === 'mcp') { _%>
129
134
  /** Default Gateway target name for this MCP server. */
@@ -140,15 +145,26 @@ export class <%- nameClassName %> extends Construct implements IGrantable, IConn
140
145
 
141
146
  const rc = RuntimeConfig.ensure(this);
142
147
 
143
- // Resolve the bundle output directory containing the Dockerfile and built artifacts
148
+ // Resolve the <%- container ? 'bundle output directory containing the Dockerfile and built artifacts' : 'packaged code directory, uploaded as a zip asset' %>
144
149
  const bundleDir = path.join(
145
150
  findWorkspaceRoot(url.fileURLToPath(new URL(<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>))),
146
- '<%- dockerOutputDir %>',
151
+ '<%- artifactOutputDir %>',
147
152
  );
148
153
 
154
+ <%_ if (container) { _%>
149
155
  this.dockerImage = AgentRuntimeArtifact.fromAsset(bundleDir, {
150
156
  platform: Platform.LINUX_ARM64,
151
157
  });
158
+ <%_ } else { _%>
159
+ // The `opentelemetry-instrument` prefix auto-instruments with the AWS Distro
160
+ // for OpenTelemetry packaged alongside the code.
161
+ // https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-configure.html
162
+ this.code = AgentRuntimeArtifact.fromCodeAsset({
163
+ path: bundleDir,
164
+ runtime: AgentCoreRuntime.<%- codeRuntime %>,
165
+ entrypoint: ['opentelemetry-instrument', '<%- codeEntryPoint %>'],
166
+ });
167
+ <%_ } _%>
152
168
 
153
169
  <%_ if (auth === 'cognito' || hasSessionBucket) { _%>
154
170
  const {
@@ -293,7 +309,7 @@ export class <%- nameClassName %> extends Construct implements IGrantable, IConn
293
309
  Names.uniqueResourceName(this.agentCoreRuntime, { maxLength: 40 }),
294
310
  }),
295
311
  protocolConfiguration: ProtocolType.<%- serverProtocol.toUpperCase() %>,
296
- agentRuntimeArtifact: this.dockerImage,
312
+ agentRuntimeArtifact: this.<%- container ? 'dockerImage' : 'code' %>,
297
313
  <%_ if (auth === 'cognito') { _%>
298
314
  authorizerConfiguration: RuntimeAuthorizerConfiguration.usingCognito(
299
315
  identity.userPool,
@@ -63,6 +63,28 @@ variable "appconfig_application_id" {
63
63
  type = string
64
64
  }
65
65
 
66
+ <%_ if (container) { _%>
67
+ variable "asset_ecr_repository_url" {
68
+ description = "URL of the shared asset ECR repository the agent's image is published to. Instantiate the `core/asset-ecr` module once per deployment and pass its `repository_url` output here."
69
+ type = string
70
+ }
71
+
72
+ variable "asset_ecr_repository_arn" {
73
+ description = "ARN of the shared asset ECR repository (from `core/asset-ecr.repository_arn`), used to scope the runtime's image pull grant to it."
74
+ type = string
75
+ }
76
+ <%_ } else { _%>
77
+ variable "asset_bucket_name" {
78
+ description = "Name of the shared asset S3 bucket used to stage the agent code zip. Instantiate the `core/asset-bucket` module once per deployment and pass its `bucket_name` output here."
79
+ type = string
80
+ }
81
+
82
+ variable "asset_bucket_arn" {
83
+ description = "ARN of the shared asset S3 bucket (from `core/asset-bucket.bucket_arn`), used to scope the runtime's read grant to the staged object."
84
+ type = string
85
+ }
86
+ <%_ } _%>
87
+
66
88
  <%_ if (hasSessionBucket) { _%>
67
89
  variable "session_force_destroy" {
68
90
  description = "Whether to allow the session bucket to be destroyed even if it still contains objects."
@@ -288,9 +310,20 @@ resource "aws_dynamodb_table" "session" {
288
310
 
289
311
  <%_ } _%>
290
312
  module "agent_core_runtime" {
291
- source = "../../../core/agent-core"
313
+ source = "../../../core/<%= terraformPackagingModule %>"
292
314
  agent_runtime_name = "<%= nameClassName %>"
315
+ <%_ if (container) { _%>
293
316
  docker_image_tag = "<%= dockerImageTag %>"
317
+ asset_ecr_repository_url = var.asset_ecr_repository_url
318
+ asset_ecr_repository_arn = var.asset_ecr_repository_arn
319
+ <%_ } else { _%>
320
+ # The walk up from path.module reaches the workspace root.
321
+ code_dir = "${path.module}/../../../../../../../<%= artifactOutputDir %>"
322
+ code_runtime = "<%= codeRuntime %>"
323
+ code_entry_point = "<%= codeEntryPoint %>"
324
+ asset_bucket_name = var.asset_bucket_name
325
+ asset_bucket_arn = var.asset_bucket_arn
326
+ <%_ } _%>
294
327
  server_protocol = "<%= serverProtocol.toUpperCase() %>"
295
328
  enable_vpc = var.enable_vpc
296
329
  vpc_id = var.vpc_id
@@ -6,10 +6,6 @@ terraform {
6
6
  source = "hashicorp/aws"
7
7
  version = "<%- awsProviderVersion %>"
8
8
  }
9
- external = {
10
- source = "hashicorp/external"
11
- version = "<%- externalProviderVersion %>"
12
- }
13
9
  null = {
14
10
  source = "hashicorp/null"
15
11
  version = "<%- nullProviderVersion %>"
@@ -53,9 +49,36 @@ variable "authorizer_configuration" {
53
49
  default = null
54
50
  }
55
51
 
56
- variable "docker_image_tag" {
57
- description = "Name of the docker image tag to use as the agent core runtime"
58
- type = string
52
+ variable "container_configuration" {
53
+ description = "Container artifact for this runtime. Set exactly one of this or `code_configuration`; the `agent-core-container` module renders it."
54
+ type = object({
55
+ container_uri = string
56
+ })
57
+ default = null
58
+ }
59
+
60
+ variable "code_configuration" {
61
+ description = "Code artifact for this runtime. Set exactly one of this or `container_configuration`; the `agent-core-code` module renders it."
62
+ type = object({
63
+ entry_point = list(string)
64
+ runtime = string
65
+ s3_bucket = string
66
+ s3_key = string
67
+ })
68
+ default = null
69
+
70
+ validation {
71
+ # Evaluated at plan time, since Terraform defers validation that reads
72
+ # another variable.
73
+ condition = (var.code_configuration == null) != (var.container_configuration == null)
74
+ error_message = "Set exactly one of code_configuration or container_configuration."
75
+ }
76
+ }
77
+
78
+ variable "artifact_dependencies" {
79
+ description = "Resources the artifact is produced by (an image push or a code upload), so the runtime is created only once they exist."
80
+ type = list(any)
81
+ default = []
59
82
  }
60
83
 
61
84
  variable "env" {
@@ -118,47 +141,6 @@ resource "random_id" "unique_suffix" {
118
141
  byte_length = 4
119
142
  }
120
143
 
121
- # ECR Repository
122
- resource "aws_ecr_repository" "agent_core_repository" {
123
- #checkov:skip=CKV_AWS_136:AES256 encryption is sufficient for ECR repositories
124
- name = "${lower(var.agent_runtime_name)}_repository_${random_id.unique_suffix.hex}"
125
-
126
- image_tag_mutability = "IMMUTABLE"
127
- force_delete = true
128
-
129
- image_scanning_configuration {
130
- scan_on_push = true
131
- }
132
-
133
- tags = var.tags
134
- }
135
-
136
- # ECR Repository Policy
137
- resource "aws_ecr_repository_policy" "agent_core_ecr_policy" {
138
- repository = aws_ecr_repository.agent_core_repository.name
139
-
140
- policy = jsonencode({
141
- Version = "2012-10-17"
142
- Statement = [
143
- {
144
- Sid = "AllowPushPull"
145
- Effect = "Allow"
146
- Principal = {
147
- AWS = "arn:aws:iam::${local.aws_account_id}:root"
148
- }
149
- Action = [
150
- "ecr:GetDownloadUrlForLayer",
151
- "ecr:BatchGetImage",
152
- "ecr:BatchCheckLayerAvailability",
153
- "ecr:PutImage",
154
- "ecr:InitiateLayerUpload",
155
- "ecr:UploadLayerPart",
156
- "ecr:CompleteLayerUpload"
157
- ]
158
- }
159
- ]
160
- })
161
- }
162
144
 
163
145
  # IAM Role for Agent Core Runtime
164
146
  resource "aws_iam_role" "agent_core_runtime_role" {
@@ -197,27 +179,6 @@ resource "aws_iam_policy" "agent_core_runtime_policy" {
197
179
  policy = jsonencode({
198
180
  Version = "2012-10-17"
199
181
  Statement = concat([
200
- {
201
- Sid = "ECRImageAccess"
202
- Effect = "Allow"
203
- Action = [
204
- "ecr:BatchGetImage",
205
- "ecr:GetDownloadUrlForLayer"
206
- ]
207
- Resource = [
208
- aws_ecr_repository.agent_core_repository.arn
209
- ]
210
- },
211
- {
212
- Sid = "ECRTokenAccess"
213
- Effect = "Allow"
214
- Action = [
215
- "ecr:GetAuthorizationToken"
216
- ]
217
- Resource = [
218
- "*"
219
- ]
220
- },
221
182
  {
222
183
  "Effect" : "Allow",
223
184
  "Action" : [
@@ -292,46 +253,6 @@ resource "aws_iam_role_policy_attachment" "agent_core_policy" {
292
253
  policy_arn = aws_iam_policy.agent_core_runtime_policy.arn
293
254
  }
294
255
 
295
- # Data source to get container image digest
296
- data "external" "docker_digest" {
297
- program = ["sh", "-c", "echo '{\"digest\":\"'$(<%= containers %> inspect ${var.docker_image_tag} --format '{{.Id}}')'\"}' "]
298
- }
299
-
300
- locals {
301
- # Content-based, immutable image tag derived from the local image digest
302
- image_tag = replace(data.external.docker_digest.result.digest, "sha256:", "")
303
- }
304
-
305
- # Null resource for container image publish
306
- resource "null_resource" "docker_publish" {
307
- triggers = {
308
- docker_digest = data.external.docker_digest.result.digest
309
- repository_url = aws_ecr_repository.agent_core_repository.repository_url
310
- docker_image_tag = var.docker_image_tag
311
- image_tag = local.image_tag
312
- }
313
-
314
- provisioner "local-exec" {
315
- command = <<-EOT
316
- # Get ECR login token
317
- aws ecr get-login-password --region "$AWS_REGION" | <%= containers %> login --username AWS --password-stdin "$REPOSITORY_URL"
318
-
319
- # Tag the image with the immutable content-based tag
320
- <%= containers %> tag "$DOCKER_IMAGE_TAG" "$REPOSITORY_URL:$IMAGE_TAG"
321
-
322
- # Push the image
323
- <%= containers %> push "$REPOSITORY_URL:$IMAGE_TAG"
324
- EOT
325
- environment = {
326
- AWS_REGION = local.aws_region
327
- REPOSITORY_URL = self.triggers.repository_url
328
- DOCKER_IMAGE_TAG = self.triggers.docker_image_tag
329
- IMAGE_TAG = self.triggers.image_tag
330
- }
331
- }
332
-
333
- depends_on = [aws_ecr_repository_policy.agent_core_ecr_policy]
334
- }
335
256
 
336
257
  # Security group for the agent core runtime, used when running inside a VPC
337
258
  resource "aws_security_group" "agent_core_runtime" {
@@ -362,8 +283,26 @@ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
362
283
  role_arn = aws_iam_role.agent_core_runtime_role.arn
363
284
 
364
285
  agent_runtime_artifact {
365
- container_configuration {
366
- container_uri = "${aws_ecr_repository.agent_core_repository.repository_url}:${local.image_tag}"
286
+ dynamic "container_configuration" {
287
+ for_each = var.container_configuration != null ? [var.container_configuration] : []
288
+ content {
289
+ container_uri = container_configuration.value.container_uri
290
+ }
291
+ }
292
+
293
+ dynamic "code_configuration" {
294
+ for_each = var.code_configuration != null ? [var.code_configuration] : []
295
+ content {
296
+ entry_point = code_configuration.value.entry_point
297
+ runtime = code_configuration.value.runtime
298
+
299
+ code {
300
+ s3 {
301
+ bucket = code_configuration.value.s3_bucket
302
+ prefix = code_configuration.value.s3_key
303
+ }
304
+ }
305
+ }
367
306
  }
368
307
  }
369
308
 
@@ -407,7 +346,7 @@ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
407
346
  tags = var.tags
408
347
 
409
348
  depends_on = [
410
- null_resource.docker_publish,
349
+ var.artifact_dependencies,
411
350
  aws_iam_role_policy_attachment.agent_core_policy
412
351
  ]
413
352
  }