@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.
- package/migrations.json +6 -1
- package/package.json +1 -1
- package/src/internal/test-matrix/generator.js +28 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/migrations/latest/react-website-unique-dev-ports/metadata.json +3 -0
- package/src/migrations/latest/react-website-unique-dev-ports/migration.d.ts +6 -0
- package/src/migrations/latest/react-website-unique-dev-ports/migration.js +79 -0
- package/src/migrations/latest/react-website-unique-dev-ports/migration.js.map +1 -0
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +90 -115
- package/src/py/agent/files/package/main.py.template +13 -0
- package/src/py/agent/generator.d.ts +6 -1
- package/src/py/agent/generator.js +82 -45
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/schema.d.js.map +1 -1
- package/src/py/agent/schema.d.ts +2 -1
- package/src/py/agent/schema.json +2 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +64 -113
- package/src/py/mcp-server/files/package/main.py.template +13 -0
- package/src/py/mcp-server/generator.d.ts +6 -1
- package/src/py/mcp-server/generator.js +79 -43
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/mcp-server/schema.d.js.map +1 -1
- package/src/py/mcp-server/schema.d.ts +2 -1
- package/src/py/mcp-server/schema.json +2 -2
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +12 -59
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +77 -114
- package/src/ts/agent/generator.d.ts +26 -1
- package/src/ts/agent/generator.js +71 -45
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/schema.d.js.map +1 -1
- package/src/ts/agent/schema.d.ts +2 -1
- package/src/ts/agent/schema.json +2 -2
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +64 -113
- package/src/ts/mcp-server/generator.d.ts +26 -1
- package/src/ts/mcp-server/generator.js +66 -38
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.d.js.map +1 -1
- package/src/ts/mcp-server/schema.d.ts +2 -1
- package/src/ts/mcp-server/schema.json +2 -2
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +16 -110
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/ts/react-website/app/generator.js +16 -0
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/cognito-auth/generator.js +14 -2
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +25 -6
- package/src/utils/agent-core-constructs/agent-core-constructs.js +36 -7
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +20 -4
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +34 -1
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +51 -112
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core-code/runtime.tf.template +204 -0
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core-container/runtime.tf.template +235 -0
- package/src/utils/agent-core-packaging.d.ts +119 -0
- package/src/utils/agent-core-packaging.js +131 -0
- package/src/utils/agent-core-packaging.js.map +1 -0
- package/src/utils/agent-core-runtime-resolution.d.ts +35 -0
- package/src/utils/agent-core-runtime-resolution.js +68 -0
- package/src/utils/agent-core-runtime-resolution.js.map +1 -0
- package/src/utils/files/terraform/src/core/asset-ecr/asset-ecr.tf.template +137 -0
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +1 -1
- package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +1 -4
- package/src/utils/identity-constructs/identity-constructs.d.ts +22 -2
- package/src/utils/identity-constructs/identity-constructs.js +75 -5
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/port.d.ts +5 -0
- package/src/utils/port.js +1 -1
- package/src/utils/port.js.map +1 -1
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +12 -59
- package/src/utils/versions.d.ts +20 -0
- package/src/utils/versions.js +17 -0
- package/src/utils/versions.js.map +1 -1
- /package/src/ts/mcp-server/files/{http.ts.template → app/http.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{index.ts.template → app/index.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{resources → app/resources}/sample-guidance.ts.template +0 -0
- /package/src/ts/mcp-server/files/{server.ts.template → app/server.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{stdio.ts.template → app/stdio.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{tools → app/tools}/divide.ts.template +0 -0
- /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
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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":"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"}
|
|
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
|
-
'<%-
|
|
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
|
|
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
|
|
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 "
|
|
57
|
-
description = "
|
|
58
|
-
type
|
|
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
|
-
|
|
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
|
-
|
|
349
|
+
var.artifact_dependencies,
|
|
411
350
|
aws_iam_role_policy_attachment.agent_core_policy
|
|
412
351
|
]
|
|
413
352
|
}
|