@aws/nx-plugin 1.0.0-rc.83 → 1.0.0-rc.85
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/generators.json +7 -0
- package/migrations.json +31 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +51 -2
- package/src/agentcore-harness/__snapshots__/generator.spec.ts.snap +4 -5
- package/src/agentcore-harness/files/project/README.md.template +4 -5
- package/src/internal/test-matrix/generator.js +16 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/__snapshots__/migration.spec.ts.snap +79 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/metadata.json +3 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.d.ts +6 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.js +87 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.js.map +1 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/__snapshots__/migration.spec.ts.snap +54 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/metadata.json +3 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.d.ts +6 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.js +86 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.js.map +1 -0
- package/src/migrations/latest/terraform-declare-used-providers/metadata.json +3 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.js +147 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.js.map +1 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/__snapshots__/migration.spec.ts.snap +521 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/metadata.json +3 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.js +504 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.js.map +1 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/metadata.json +3 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js +146 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js.map +1 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/__snapshots__/migration.spec.ts.snap +286 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/metadata.json +3 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.d.ts +6 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.js +238 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.js.map +1 -0
- package/src/open-api/json-metadata/generator.d.ts +24 -0
- package/src/open-api/json-metadata/generator.js +37 -0
- package/src/open-api/json-metadata/generator.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.js +6 -0
- package/src/open-api/json-metadata/schema.d.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.ts +9 -0
- package/src/open-api/json-metadata/schema.json +20 -0
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +12 -0
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +1875 -623
- package/src/py/fast-api/generator.js +2 -1
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +31 -2
- package/src/sdk/open-api.d.ts +2 -0
- package/src/sdk/open-api.js +2 -1
- package/src/sdk/open-api.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1756 -457
- package/src/smithy/ts/api/generator.js +2 -1
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/terraform/project/files/application/bootstrap/providers.tf.template +11 -0
- package/src/terraform/project/files/application/scripts/bootstrap-destroy.ts.template +111 -0
- package/src/terraform/project/files/application/src/providers.tf.template +6 -0
- package/src/terraform/project/files/checkov/checkov.yml.template +8 -0
- package/src/terraform/project/files/library/src/main.tf.template +9 -0
- package/src/terraform/project/generator.js +47 -4
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +1848 -614
- package/src/trpc/backend/files-operations/scripts/generate-operations.ts.template +40 -0
- package/src/trpc/backend/generator.js +10 -0
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +62 -4
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +35 -8
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +4 -0
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-harness/__nameKebabCase__/__nameKebabCase__.ts.template +39 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +8 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +57 -2
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-harness/__nameKebabCase__/__nameKebabCase__.tf.template +258 -24
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +4 -0
- package/src/utils/api-constructs/api-constructs.js +11 -0
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +251 -3
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +437 -2
- package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +60 -7
- package/src/utils/api-constructs/open-api-metadata.d.ts +20 -3
- package/src/utils/api-constructs/open-api-metadata.js +64 -8
- package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
- package/src/utils/api-constructs/trpc-operations-metadata.d.ts +21 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js +55 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js.map +1 -0
- package/src/utils/dcr-proxy-constructs/files/terraform/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.tf.template +4 -0
- package/src/utils/files/terraform/src/metrics/providers.tf.template +12 -0
- package/src/utils/function-constructs/files/terraform/app/lambda-functions/__nameKebabCase__/__nameKebabCase__.tf.template +4 -0
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +33 -8
- package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +4 -0
- package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +51 -2
- package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +18 -0
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +15 -4
- package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +2 -2
- package/src/utils/rdb-constructs/rdb-constructs.d.ts +12 -0
- package/src/utils/rdb-constructs/rdb-constructs.js +24 -3
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +4 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { joinPathFragments } from "@nx/devkit";
|
|
5
|
+
import { applyGritQL, captureAllGritQL, GRIT_INSERT_PLACEHOLDER, insertViaGritQL, matchGritQL } from "../../../utils/ast.js";
|
|
6
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
7
|
+
import { PACKAGES_DIR, SHARED_TERRAFORM_DIR } from "../../../utils/shared-constructs-constants.js";
|
|
8
|
+
/**
|
|
9
|
+
* Bring each vended Terraform AgentCore Harness app module
|
|
10
|
+
* (`app/harnesses/<name>/<name>.tf`) up to the shape the generator now writes:
|
|
11
|
+
*
|
|
12
|
+
* - `enable_vpc` / `vpc_id` / `subnet_ids` with a security group and a 443-only
|
|
13
|
+
* egress rule, so the Harness can reach private resources.
|
|
14
|
+
* - `create_execution_role` / `execution_role_arn`, so an existing role can be
|
|
15
|
+
* supplied. The generated role and its baseline policy are then not created.
|
|
16
|
+
* - `allowed_tools`, `memory`, `environment_variables`, `max_iterations` and
|
|
17
|
+
* `timeout_seconds` as variables rather than HCL edits.
|
|
18
|
+
* - The managed-memory grant moved to its own policy, made conditional and
|
|
19
|
+
* re-scoped from a name-prefix guess to the ARN the service assigns.
|
|
20
|
+
*
|
|
21
|
+
* These files are generated with `KeepExisting`, so an upgraded workspace keeps
|
|
22
|
+
* the older module until this runs. Modules that have diverged from the
|
|
23
|
+
* generated shape are left untouched and reported via `nextSteps`.
|
|
24
|
+
*/ const TERRAFORM_HARNESS_APP_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/harnesses`;
|
|
25
|
+
const hcl = (pattern)=>`language hcl\n${pattern}`;
|
|
26
|
+
const divergedMessage = (filePath)=>`${filePath}: has diverged from the generated shape - left untouched. To pick up VPC support, a supplied execution role, the allowed_tools/memory/environment_variables/max_iterations/timeout_seconds variables and the corrected managed-memory grant, compare it against the agentcore-harness generator's Terraform template and apply the parts you want.`;
|
|
27
|
+
/**
|
|
28
|
+
* Variables added ahead of the existing `model_resource_arns` variable.
|
|
29
|
+
* `allowed_tools` is not among them: the earlier `agentcore-harness-no-tools-by-default`
|
|
30
|
+
* migration already declares it, and runs first.
|
|
31
|
+
*/ const NEW_VARIABLES_TEXT = `variable "memory" {
|
|
32
|
+
description = "Memory configuration for the Harness. Null leaves the service to provision managed memory with default strategies. Set exactly one field: managed_memory_configuration to tune that managed memory, agentcore_memory_configuration to use a memory resource you own, or disabled to turn memory off."
|
|
33
|
+
type = object({
|
|
34
|
+
managed_memory_configuration = optional(object({
|
|
35
|
+
strategies = optional(set(string))
|
|
36
|
+
event_expiry_duration = optional(number)
|
|
37
|
+
encryption_key_arn = optional(string)
|
|
38
|
+
}))
|
|
39
|
+
agentcore_memory_configuration = optional(object({
|
|
40
|
+
arn = string
|
|
41
|
+
actor_id = optional(string)
|
|
42
|
+
messages_count = optional(number)
|
|
43
|
+
}))
|
|
44
|
+
disabled = optional(bool, false)
|
|
45
|
+
})
|
|
46
|
+
default = null
|
|
47
|
+
|
|
48
|
+
validation {
|
|
49
|
+
condition = var.memory == null || length([
|
|
50
|
+
for configured in [
|
|
51
|
+
var.memory.managed_memory_configuration != null,
|
|
52
|
+
var.memory.agentcore_memory_configuration != null,
|
|
53
|
+
var.memory.disabled,
|
|
54
|
+
] : configured if configured
|
|
55
|
+
]) == 1
|
|
56
|
+
error_message = "Set exactly one of memory.managed_memory_configuration, memory.agentcore_memory_configuration or memory.disabled."
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
variable "environment_variables" {
|
|
61
|
+
description = "Environment variables available to the Harness."
|
|
62
|
+
type = map(string)
|
|
63
|
+
default = null
|
|
64
|
+
sensitive = true
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
variable "max_iterations" {
|
|
68
|
+
description = "Maximum agent loop iterations per invocation. Uses the service default when null."
|
|
69
|
+
type = number
|
|
70
|
+
default = null
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
variable "timeout_seconds" {
|
|
74
|
+
description = "Maximum seconds an invocation may run. Uses the service default when null."
|
|
75
|
+
type = number
|
|
76
|
+
default = null
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
variable "create_execution_role" {
|
|
80
|
+
description = "Create the execution role with the baseline permissions below. Set false alongside execution_role_arn to use a role you already have, which is then used as-is."
|
|
81
|
+
type = bool
|
|
82
|
+
default = true
|
|
83
|
+
|
|
84
|
+
validation {
|
|
85
|
+
condition = var.create_execution_role || var.execution_role_arn != null
|
|
86
|
+
error_message = "execution_role_arn must be set when create_execution_role is false."
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
validation {
|
|
90
|
+
condition = var.create_execution_role || (
|
|
91
|
+
var.model_resource_arns == null && length(var.additional_execution_role_policy_statements) == 0
|
|
92
|
+
)
|
|
93
|
+
error_message = "model_resource_arns and additional_execution_role_policy_statements configure the generated execution role, which is not created when create_execution_role is false. Grant those permissions on the supplied role instead."
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
variable "execution_role_arn" {
|
|
98
|
+
description = "ARN of an existing IAM role for the Harness to assume. Requires create_execution_role = false."
|
|
99
|
+
type = string
|
|
100
|
+
default = null
|
|
101
|
+
}`;
|
|
102
|
+
/** VPC and tag variables added after `additional_execution_role_policy_statements`. */ const VPC_VARIABLES_TEXT = `# VPC Configuration (optional)
|
|
103
|
+
variable "enable_vpc" {
|
|
104
|
+
description = "Run the Harness inside a VPC so it can reach private resources. Set alongside vpc_id/subnet_ids."
|
|
105
|
+
type = bool
|
|
106
|
+
default = false
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
variable "vpc_id" {
|
|
110
|
+
description = "VPC ID to run the Harness in. Required when enable_vpc is true."
|
|
111
|
+
type = string
|
|
112
|
+
default = null
|
|
113
|
+
|
|
114
|
+
validation {
|
|
115
|
+
condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
|
|
116
|
+
error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
variable "subnet_ids" {
|
|
121
|
+
description = "Subnet IDs to run the Harness in. Required when enable_vpc is true."
|
|
122
|
+
type = list(string)
|
|
123
|
+
default = null
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
variable "tags" {
|
|
127
|
+
description = "Tags to apply to resources"
|
|
128
|
+
type = map(string)
|
|
129
|
+
default = {}
|
|
130
|
+
}`;
|
|
131
|
+
/** Locals added to the module's existing `locals` block. */ const NEW_LOCALS_TEXT = ` execution_role_arn = var.create_execution_role ? aws_iam_role.execution_role[0].arn : var.execution_role_arn
|
|
132
|
+
|
|
133
|
+
# The service provisions managed memory unless var.memory redirects it
|
|
134
|
+
# elsewhere or turns it off.
|
|
135
|
+
has_managed_memory = var.memory == null || var.memory.managed_memory_configuration != null`;
|
|
136
|
+
/** Security group and egress rule, added before the Harness resource. */ const SECURITY_GROUP_TEXT = `# Security group for the Harness, used when running inside a VPC
|
|
137
|
+
resource "aws_security_group" "harness" {
|
|
138
|
+
count = var.enable_vpc ? 1 : 0
|
|
139
|
+
|
|
140
|
+
#checkov:skip=CKV2_AWS_5:Attached to the Harness via its network configuration; Checkov cannot resolve this reference
|
|
141
|
+
name_prefix = "\${local.harness_name_prefix}-harness-"
|
|
142
|
+
description = "Security group for the \${local.harness_name_prefix} Harness"
|
|
143
|
+
vpc_id = var.vpc_id
|
|
144
|
+
tags = var.tags
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
resource "aws_vpc_security_group_egress_rule" "harness_https" {
|
|
148
|
+
count = var.enable_vpc ? 1 : 0
|
|
149
|
+
|
|
150
|
+
security_group_id = aws_security_group.harness[0].id
|
|
151
|
+
cidr_ipv4 = "0.0.0.0/0"
|
|
152
|
+
from_port = 443
|
|
153
|
+
to_port = 443
|
|
154
|
+
ip_protocol = "tcp"
|
|
155
|
+
description = "Allow outbound HTTPS to AWS service endpoints"
|
|
156
|
+
}`;
|
|
157
|
+
/**
|
|
158
|
+
* Native fields added to the Harness resource. `allowed_tools` is re-emitted
|
|
159
|
+
* here, aligned with the rest, replacing the line the earlier
|
|
160
|
+
* no-tools-by-default migration added.
|
|
161
|
+
*/ const HARNESS_FIELDS_TEXT = ` allowed_tools = var.allowed_tools
|
|
162
|
+
environment_variables = var.environment_variables
|
|
163
|
+
max_iterations = var.max_iterations
|
|
164
|
+
timeout_seconds = var.timeout_seconds`;
|
|
165
|
+
const HARNESS_BLOCKS_TEXT = ` dynamic "memory" {
|
|
166
|
+
for_each = var.memory != null ? [var.memory] : []
|
|
167
|
+
content {
|
|
168
|
+
dynamic "managed_memory_configuration" {
|
|
169
|
+
for_each = memory.value.managed_memory_configuration != null ? [memory.value.managed_memory_configuration] : []
|
|
170
|
+
content {
|
|
171
|
+
strategies = managed_memory_configuration.value.strategies
|
|
172
|
+
event_expiry_duration = managed_memory_configuration.value.event_expiry_duration
|
|
173
|
+
encryption_key_arn = managed_memory_configuration.value.encryption_key_arn
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
dynamic "agentcore_memory_configuration" {
|
|
178
|
+
for_each = memory.value.agentcore_memory_configuration != null ? [memory.value.agentcore_memory_configuration] : []
|
|
179
|
+
content {
|
|
180
|
+
arn = agentcore_memory_configuration.value.arn
|
|
181
|
+
actor_id = agentcore_memory_configuration.value.actor_id
|
|
182
|
+
messages_count = agentcore_memory_configuration.value.messages_count
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
dynamic "disabled" {
|
|
187
|
+
for_each = memory.value.disabled ? [1] : []
|
|
188
|
+
content {}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
dynamic "environment" {
|
|
194
|
+
for_each = var.enable_vpc ? [1] : []
|
|
195
|
+
content {
|
|
196
|
+
agentcore_runtime_environment {
|
|
197
|
+
network_configuration {
|
|
198
|
+
network_mode = "VPC"
|
|
199
|
+
network_mode_config {
|
|
200
|
+
security_groups = [aws_security_group.harness[0].id]
|
|
201
|
+
subnets = var.subnet_ids
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
tags = var.tags`;
|
|
209
|
+
/** The managed-memory grant, as its own policy scoped to the assigned ARN. */ const MANAGED_MEMORY_POLICY_TEXT = `# Scoped to the memory ARN the service assigns, which is only readable after the
|
|
210
|
+
# Harness exists, so this is a policy of its own rather than a baseline
|
|
211
|
+
# statement. Skipped when the Harness uses a role or memory the module did not
|
|
212
|
+
# create.
|
|
213
|
+
resource "aws_iam_role_policy" "managed_memory" {
|
|
214
|
+
count = var.create_execution_role && local.has_managed_memory ? 1 : 0
|
|
215
|
+
|
|
216
|
+
name = "\${local.harness_name_prefix}-HarnessManagedMemoryPolicy"
|
|
217
|
+
role = aws_iam_role.execution_role[0].id
|
|
218
|
+
|
|
219
|
+
policy = jsonencode({
|
|
220
|
+
Version = "2012-10-17"
|
|
221
|
+
Statement = [{
|
|
222
|
+
Sid = "AgentCoreManagedMemory"
|
|
223
|
+
Effect = "Allow"
|
|
224
|
+
Action = [
|
|
225
|
+
"bedrock-agentcore:CreateEvent",
|
|
226
|
+
"bedrock-agentcore:DeleteEvent",
|
|
227
|
+
"bedrock-agentcore:GetEvent",
|
|
228
|
+
"bedrock-agentcore:ListEvents",
|
|
229
|
+
"bedrock-agentcore:RetrieveMemoryRecords",
|
|
230
|
+
]
|
|
231
|
+
Resource = [
|
|
232
|
+
aws_bedrockagentcore_harness.this.memory_actual[0].managed_memory_configuration[0].arn,
|
|
233
|
+
]
|
|
234
|
+
}]
|
|
235
|
+
})
|
|
236
|
+
}`;
|
|
237
|
+
const SECURITY_GROUP_OUTPUT_TEXT = `output "security_group_id" {
|
|
238
|
+
description = "Security group ID of the Harness, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
|
|
239
|
+
value = var.enable_vpc ? aws_security_group.harness[0].id : null
|
|
240
|
+
}`;
|
|
241
|
+
/**
|
|
242
|
+
* The baseline policy, replaced whole: the managed-memory statement leaves it
|
|
243
|
+
* for a policy of its own, and the resource gains a `count`. Rewriting the
|
|
244
|
+
* statement list in place would strand the comment and comma around the
|
|
245
|
+
* statement being removed.
|
|
246
|
+
*/ const BASELINE_POLICY_TEXT = `resource "aws_iam_role_policy" "execution_role" {
|
|
247
|
+
count = var.create_execution_role ? 1 : 0
|
|
248
|
+
|
|
249
|
+
name = "\${local.harness_name_prefix}-HarnessPolicy"
|
|
250
|
+
role = aws_iam_role.execution_role[0].id
|
|
251
|
+
|
|
252
|
+
policy = jsonencode({
|
|
253
|
+
Version = "2012-10-17"
|
|
254
|
+
Statement = concat([
|
|
255
|
+
{
|
|
256
|
+
Sid = "BedrockModelInvocation"
|
|
257
|
+
Effect = "Allow"
|
|
258
|
+
Action = [
|
|
259
|
+
"bedrock:InvokeModel",
|
|
260
|
+
"bedrock:InvokeModelWithResponseStream",
|
|
261
|
+
]
|
|
262
|
+
Resource = local.model_resource_arns
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
#checkov:skip=CKV_AWS_355:EcrPublicTokenAccess requires a wildcard resource; ecr-public:GetAuthorizationToken has no resource-level permission
|
|
266
|
+
Sid = "EcrPublicTokenAccess"
|
|
267
|
+
Effect = "Allow"
|
|
268
|
+
Action = ["ecr-public:GetAuthorizationToken"]
|
|
269
|
+
Resource = ["*"]
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
#checkov:skip=CKV_AWS_355:StsForEcrPublicPull requires a wildcard resource; sts:GetServiceBearerToken has no resource-level permission
|
|
273
|
+
Sid = "StsForEcrPublicPull"
|
|
274
|
+
Effect = "Allow"
|
|
275
|
+
Action = ["sts:GetServiceBearerToken"]
|
|
276
|
+
Resource = ["*"]
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
#checkov:skip=CKV_AWS_355:XRayTracingAccess requires a wildcard resource; the X-Ray segment and sampling APIs have no resource-level permission
|
|
280
|
+
#checkov:skip=CKV_AWS_290:XRayTracingAccess requires a wildcard resource; the X-Ray segment and sampling APIs have no resource-level permission
|
|
281
|
+
Sid = "XRayTracingAccess"
|
|
282
|
+
Effect = "Allow"
|
|
283
|
+
Action = [
|
|
284
|
+
"xray:PutTraceSegments",
|
|
285
|
+
"xray:PutTelemetryRecords",
|
|
286
|
+
"xray:GetSamplingRules",
|
|
287
|
+
"xray:GetSamplingTargets",
|
|
288
|
+
]
|
|
289
|
+
Resource = ["*"]
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
Sid = "CloudWatchLogsGroup"
|
|
293
|
+
Effect = "Allow"
|
|
294
|
+
Action = [
|
|
295
|
+
"logs:CreateLogGroup",
|
|
296
|
+
"logs:DescribeLogStreams",
|
|
297
|
+
]
|
|
298
|
+
Resource = [
|
|
299
|
+
"arn:\${local.partition}:logs:\${local.region}:\${local.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*",
|
|
300
|
+
]
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
Sid = "CloudWatchLogsDescribeGroups"
|
|
304
|
+
Effect = "Allow"
|
|
305
|
+
Action = ["logs:DescribeLogGroups"]
|
|
306
|
+
Resource = ["arn:\${local.partition}:logs:\${local.region}:\${local.account_id}:log-group:*"]
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
Sid = "CloudWatchLogsStream"
|
|
310
|
+
Effect = "Allow"
|
|
311
|
+
Action = [
|
|
312
|
+
"logs:CreateLogStream",
|
|
313
|
+
"logs:PutLogEvents",
|
|
314
|
+
]
|
|
315
|
+
Resource = [
|
|
316
|
+
"arn:\${local.partition}:logs:\${local.region}:\${local.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*:log-stream:*",
|
|
317
|
+
]
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
#checkov:skip=CKV_AWS_355:CloudWatchMetricsPublish requires a wildcard resource; cloudwatch:PutMetricData is scoped by the namespace condition instead
|
|
321
|
+
#checkov:skip=CKV_AWS_290:CloudWatchMetricsPublish requires a wildcard resource; cloudwatch:PutMetricData is scoped by the namespace condition instead
|
|
322
|
+
Sid = "CloudWatchMetricsPublish"
|
|
323
|
+
Effect = "Allow"
|
|
324
|
+
Action = ["cloudwatch:PutMetricData"]
|
|
325
|
+
Resource = ["*"]
|
|
326
|
+
Condition = {
|
|
327
|
+
StringEquals = {
|
|
328
|
+
"cloudwatch:namespace" = "bedrock-agentcore"
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
Sid = "AgentCoreWorkloadIdentity"
|
|
334
|
+
Effect = "Allow"
|
|
335
|
+
Action = [
|
|
336
|
+
"bedrock-agentcore:GetWorkloadAccessToken",
|
|
337
|
+
"bedrock-agentcore:GetWorkloadAccessTokenForJWT",
|
|
338
|
+
]
|
|
339
|
+
Resource = [
|
|
340
|
+
"arn:\${local.partition}:bedrock-agentcore:\${local.region}:\${local.account_id}:workload-identity-directory/default",
|
|
341
|
+
"arn:\${local.partition}:bedrock-agentcore:\${local.region}:\${local.account_id}:workload-identity-directory/default/workload-identity/harness_\${local.harness_name}-*",
|
|
342
|
+
]
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
Sid = "AgentCoreBrowserDefault"
|
|
346
|
+
Effect = "Allow"
|
|
347
|
+
Action = [
|
|
348
|
+
"bedrock-agentcore:StartBrowserSession",
|
|
349
|
+
"bedrock-agentcore:StopBrowserSession",
|
|
350
|
+
"bedrock-agentcore:GetBrowserSession",
|
|
351
|
+
"bedrock-agentcore:ListBrowserSessions",
|
|
352
|
+
"bedrock-agentcore:UpdateBrowserStream",
|
|
353
|
+
"bedrock-agentcore:ConnectBrowserAutomationStream",
|
|
354
|
+
"bedrock-agentcore:ConnectBrowserLiveViewStream",
|
|
355
|
+
]
|
|
356
|
+
Resource = [
|
|
357
|
+
"arn:\${local.partition}:bedrock-agentcore:\${local.region}:aws:browser/*",
|
|
358
|
+
]
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
Sid = "AgentCoreCodeInterpreterDefault"
|
|
362
|
+
Effect = "Allow"
|
|
363
|
+
Action = [
|
|
364
|
+
"bedrock-agentcore:StartCodeInterpreterSession",
|
|
365
|
+
"bedrock-agentcore:StopCodeInterpreterSession",
|
|
366
|
+
"bedrock-agentcore:GetCodeInterpreterSession",
|
|
367
|
+
"bedrock-agentcore:ListCodeInterpreterSessions",
|
|
368
|
+
"bedrock-agentcore:InvokeCodeInterpreter",
|
|
369
|
+
]
|
|
370
|
+
Resource = [
|
|
371
|
+
"arn:\${local.partition}:bedrock-agentcore:\${local.region}:aws:code-interpreter/*",
|
|
372
|
+
]
|
|
373
|
+
},
|
|
374
|
+
],
|
|
375
|
+
# In VPC mode the Harness pulls its managed container from a private ECR
|
|
376
|
+
# repository in the region rather than ECR Public, so it needs pull
|
|
377
|
+
# permissions on it. The repository is service-owned, hence the wildcard
|
|
378
|
+
# account.
|
|
379
|
+
var.enable_vpc ? [
|
|
380
|
+
{
|
|
381
|
+
Sid = "EcrManagedImagePull"
|
|
382
|
+
Effect = "Allow"
|
|
383
|
+
Action = [
|
|
384
|
+
"ecr:BatchGetImage",
|
|
385
|
+
"ecr:GetDownloadUrlForLayer",
|
|
386
|
+
"ecr:BatchCheckLayerAvailability",
|
|
387
|
+
]
|
|
388
|
+
Resource = ["arn:\${local.partition}:ecr:\${local.region}:*:repository/harness-*"]
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
#checkov:skip=CKV_AWS_355:EcrManagedImageToken requires a wildcard resource; ecr:GetAuthorizationToken has no resource-level permission
|
|
392
|
+
Sid = "EcrManagedImageToken"
|
|
393
|
+
Effect = "Allow"
|
|
394
|
+
Action = ["ecr:GetAuthorizationToken"]
|
|
395
|
+
Resource = ["*"]
|
|
396
|
+
},
|
|
397
|
+
] : [],
|
|
398
|
+
[
|
|
399
|
+
# Null Sid/Condition fields are dropped from the rendered policy.
|
|
400
|
+
for statement in var.additional_execution_role_policy_statements :
|
|
401
|
+
{ for key, value in statement : key => value if value != null }
|
|
402
|
+
])
|
|
403
|
+
})
|
|
404
|
+
}`;
|
|
405
|
+
/**
|
|
406
|
+
* Every shape the migration rewrites, so a module missing any of them is
|
|
407
|
+
* reported rather than half-migrated.
|
|
408
|
+
*/ const REQUIRED_SHAPES = [
|
|
409
|
+
'`variable "model_resource_arns" { $_ }`',
|
|
410
|
+
'`variable "additional_execution_role_policy_statements" { $_ }`',
|
|
411
|
+
'`locals { $_ }`',
|
|
412
|
+
'`resource "aws_iam_role" "execution_role" { $_ }`',
|
|
413
|
+
'`resource "aws_iam_role_policy" "execution_role" { $_ }`',
|
|
414
|
+
'`resource "aws_bedrockagentcore_harness" "this" { $_ }`',
|
|
415
|
+
'`output "execution_role_arn" { $_ }`',
|
|
416
|
+
// The no-tools-by-default migration runs first, so its assignment is present
|
|
417
|
+
// and is what the native fields below are anchored on.
|
|
418
|
+
'`allowed_tools = var.allowed_tools`'
|
|
419
|
+
];
|
|
420
|
+
/**
|
|
421
|
+
* The baseline policy is replaced whole, so it is only safe to touch when it
|
|
422
|
+
* still carries exactly the statements the generator wrote. Any addition,
|
|
423
|
+
* removal or reordering means the user has edited it, and the replacement would
|
|
424
|
+
* discard that.
|
|
425
|
+
*/ const BASELINE_SIDS = [
|
|
426
|
+
'BedrockModelInvocation',
|
|
427
|
+
'EcrPublicTokenAccess',
|
|
428
|
+
'StsForEcrPublicPull',
|
|
429
|
+
'XRayTracingAccess',
|
|
430
|
+
'CloudWatchLogsGroup',
|
|
431
|
+
'CloudWatchLogsDescribeGroups',
|
|
432
|
+
'CloudWatchLogsStream',
|
|
433
|
+
'CloudWatchMetricsPublish',
|
|
434
|
+
'AgentCoreWorkloadIdentity',
|
|
435
|
+
'AgentCoreManagedMemory',
|
|
436
|
+
'AgentCoreBrowserDefault',
|
|
437
|
+
'AgentCoreCodeInterpreterDefault'
|
|
438
|
+
];
|
|
439
|
+
/**
|
|
440
|
+
* Whether the module's baseline policy still carries exactly the generated
|
|
441
|
+
* statements, in order. Sids are read from the whole file: the only other `Sid`
|
|
442
|
+
* is the `optional(string)` field of the additional-statements variable, which
|
|
443
|
+
* carries no string literal and so is filtered out.
|
|
444
|
+
*/ const hasUneditedBaselinePolicy = async (tree, filePath)=>{
|
|
445
|
+
const sids = (await captureAllGritQL(tree, filePath, hcl('`Sid = $sid`'))).map((text)=>/=\s*"([^"]+)"/.exec(text)?.[1]).filter((sid)=>sid !== undefined);
|
|
446
|
+
return sids.length === BASELINE_SIDS.length && sids.every((sid, index)=>sid === BASELINE_SIDS[index]);
|
|
447
|
+
};
|
|
448
|
+
export default async function migration(tree) {
|
|
449
|
+
const nextSteps = [];
|
|
450
|
+
if (!tree.exists(TERRAFORM_HARNESS_APP_DIR)) {
|
|
451
|
+
return {
|
|
452
|
+
nextSteps
|
|
453
|
+
}; // This workspace has no Terraform harness modules.
|
|
454
|
+
}
|
|
455
|
+
for (const dirName of tree.children(TERRAFORM_HARNESS_APP_DIR)){
|
|
456
|
+
const filePath = joinPathFragments(TERRAFORM_HARNESS_APP_DIR, dirName, `${dirName}.tf`);
|
|
457
|
+
if (!tree.exists(filePath)) {
|
|
458
|
+
continue; // Not a harness app module directory.
|
|
459
|
+
}
|
|
460
|
+
if (await matchGritQL(tree, filePath, hcl('`variable "enable_vpc" { $_ }`'))) {
|
|
461
|
+
continue; // Already migrated.
|
|
462
|
+
}
|
|
463
|
+
const shapeChecks = await Promise.all(REQUIRED_SHAPES.map((shape)=>matchGritQL(tree, filePath, hcl(shape))));
|
|
464
|
+
if (shapeChecks.includes(false) || !await hasUneditedBaselinePolicy(tree, filePath)) {
|
|
465
|
+
nextSteps.push(divergedMessage(filePath));
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
// Variables, ahead of the model/role variables they sit beside in the
|
|
469
|
+
// template.
|
|
470
|
+
await insertViaGritQL(tree, filePath, hcl(`\`variable "model_resource_arns" { $body }\` => \`${GRIT_INSERT_PLACEHOLDER}\n\nvariable "model_resource_arns" {\n $body\n}\``), NEW_VARIABLES_TEXT);
|
|
471
|
+
await insertViaGritQL(tree, filePath, hcl(`\`variable "additional_execution_role_policy_statements" { $body }\` => \`variable "additional_execution_role_policy_statements" {\n $body\n}\n\n${GRIT_INSERT_PLACEHOLDER}\``), VPC_VARIABLES_TEXT);
|
|
472
|
+
// Locals resolving the role ARN and whether managed memory applies.
|
|
473
|
+
await insertViaGritQL(tree, filePath, hcl(`\`locals { $body }\` => \`locals {\n $body\n\n${GRIT_INSERT_PLACEHOLDER}\n}\``), NEW_LOCALS_TEXT);
|
|
474
|
+
// The role becomes conditional on none being supplied, so it is indexed
|
|
475
|
+
// wherever it is referenced, and gains the shared tags.
|
|
476
|
+
await applyGritQL(tree, filePath, hcl('`resource "aws_iam_role" "execution_role" { $body }` => `resource "aws_iam_role" "execution_role" {\n count = var.create_execution_role ? 1 : 0\n\n $body\n\n tags = var.tags\n}`'));
|
|
477
|
+
// The baseline policy is replaced whole, dropping the managed-memory
|
|
478
|
+
// statement, which becomes a policy of its own scoped to the assigned ARN.
|
|
479
|
+
await insertViaGritQL(tree, filePath, hcl(`\`resource "aws_iam_role_policy" "execution_role" { $_ }\` => \`${GRIT_INSERT_PLACEHOLDER}\``), BASELINE_POLICY_TEXT);
|
|
480
|
+
// The role ARN follows whichever role is in use, and the `allowed_tools`
|
|
481
|
+
// line the no-tools-by-default migration added is re-aligned with the
|
|
482
|
+
// native fields that now sit beside it.
|
|
483
|
+
await applyGritQL(tree, filePath, hcl('`allowed_tools = var.allowed_tools` => ``'));
|
|
484
|
+
await insertViaGritQL(tree, filePath, hcl(`\`execution_role_arn = aws_iam_role.execution_role.arn\` => \`execution_role_arn = local.execution_role_arn\n\n${GRIT_INSERT_PLACEHOLDER}\``), HARNESS_FIELDS_TEXT);
|
|
485
|
+
// Ahead of `depends_on`, which the resource ends with.
|
|
486
|
+
await insertViaGritQL(tree, filePath, hcl(`\`depends_on = [aws_iam_role_policy.execution_role]\` => \`${GRIT_INSERT_PLACEHOLDER}\n\n depends_on = [aws_iam_role_policy.execution_role]\``), // The placeholder already sits at the block's indentation.
|
|
487
|
+
HARNESS_BLOCKS_TEXT.replace(/^ {2}/, ''));
|
|
488
|
+
// Security group ahead of the Harness resource, and the managed-memory
|
|
489
|
+
// policy after it, since it reads an attribute of the deployed Harness.
|
|
490
|
+
// Anchored on the comment introducing the resource so it stays attached.
|
|
491
|
+
await insertViaGritQL(tree, filePath, hcl(`\`# Omitting authorizer_configuration uses IAM inbound authorization; add a\` => \`${GRIT_INSERT_PLACEHOLDER}\n\n# Omitting authorizer_configuration uses IAM inbound authorization; add a\``), SECURITY_GROUP_TEXT);
|
|
492
|
+
await insertViaGritQL(tree, filePath, hcl(`\`resource "aws_bedrockagentcore_harness" "this" { $body }\` => \`resource "aws_bedrockagentcore_harness" "this" {\n $body\n}\n\n${GRIT_INSERT_PLACEHOLDER}\``), MANAGED_MEMORY_POLICY_TEXT);
|
|
493
|
+
// The role ARN output follows whichever role is in use, and the security
|
|
494
|
+
// group is exposed for ingress rules on resources the Harness reaches.
|
|
495
|
+
await applyGritQL(tree, filePath, hcl('`output "execution_role_arn" { $_ }` => `output "execution_role_arn" {\n description = "ARN of the IAM role assumed by the Harness, whether generated or supplied via var.execution_role_arn"\n value = local.execution_role_arn\n}`'));
|
|
496
|
+
await insertViaGritQL(tree, filePath, hcl(`\`output "execution_role_arn" { $body }\` => \`output "execution_role_arn" {\n $body\n}\n\n${GRIT_INSERT_PLACEHOLDER}\``), SECURITY_GROUP_OUTPUT_TEXT);
|
|
497
|
+
}
|
|
498
|
+
await formatFilesInSubtree(tree);
|
|
499
|
+
return {
|
|
500
|
+
nextSteps
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport {\n applyGritQL,\n captureAllGritQL,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Bring each vended Terraform AgentCore Harness app module\n * (`app/harnesses/<name>/<name>.tf`) up to the shape the generator now writes:\n *\n * - `enable_vpc` / `vpc_id` / `subnet_ids` with a security group and a 443-only\n * egress rule, so the Harness can reach private resources.\n * - `create_execution_role` / `execution_role_arn`, so an existing role can be\n * supplied. The generated role and its baseline policy are then not created.\n * - `allowed_tools`, `memory`, `environment_variables`, `max_iterations` and\n * `timeout_seconds` as variables rather than HCL edits.\n * - The managed-memory grant moved to its own policy, made conditional and\n * re-scoped from a name-prefix guess to the ARN the service assigns.\n *\n * These files are generated with `KeepExisting`, so an upgraded workspace keeps\n * the older module until this runs. Modules that have diverged from the\n * generated shape are left untouched and reported via `nextSteps`.\n */\n\nconst TERRAFORM_HARNESS_APP_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/harnesses`;\n\nconst hcl = (pattern: string) => `language hcl\\n${pattern}`;\n\nconst divergedMessage = (filePath: string) =>\n `${filePath}: has diverged from the generated shape - left untouched. To pick up VPC support, a supplied execution role, the allowed_tools/memory/environment_variables/max_iterations/timeout_seconds variables and the corrected managed-memory grant, compare it against the agentcore-harness generator's Terraform template and apply the parts you want.`;\n\n/**\n * Variables added ahead of the existing `model_resource_arns` variable.\n * `allowed_tools` is not among them: the earlier `agentcore-harness-no-tools-by-default`\n * migration already declares it, and runs first.\n */\nconst NEW_VARIABLES_TEXT = `variable \"memory\" {\n description = \"Memory configuration for the Harness. Null leaves the service to provision managed memory with default strategies. Set exactly one field: managed_memory_configuration to tune that managed memory, agentcore_memory_configuration to use a memory resource you own, or disabled to turn memory off.\"\n type = object({\n managed_memory_configuration = optional(object({\n strategies = optional(set(string))\n event_expiry_duration = optional(number)\n encryption_key_arn = optional(string)\n }))\n agentcore_memory_configuration = optional(object({\n arn = string\n actor_id = optional(string)\n messages_count = optional(number)\n }))\n disabled = optional(bool, false)\n })\n default = null\n\n validation {\n condition = var.memory == null || length([\n for configured in [\n var.memory.managed_memory_configuration != null,\n var.memory.agentcore_memory_configuration != null,\n var.memory.disabled,\n ] : configured if configured\n ]) == 1\n error_message = \"Set exactly one of memory.managed_memory_configuration, memory.agentcore_memory_configuration or memory.disabled.\"\n }\n}\n\nvariable \"environment_variables\" {\n description = \"Environment variables available to the Harness.\"\n type = map(string)\n default = null\n sensitive = true\n}\n\nvariable \"max_iterations\" {\n description = \"Maximum agent loop iterations per invocation. Uses the service default when null.\"\n type = number\n default = null\n}\n\nvariable \"timeout_seconds\" {\n description = \"Maximum seconds an invocation may run. Uses the service default when null.\"\n type = number\n default = null\n}\n\nvariable \"create_execution_role\" {\n description = \"Create the execution role with the baseline permissions below. Set false alongside execution_role_arn to use a role you already have, which is then used as-is.\"\n type = bool\n default = true\n\n validation {\n condition = var.create_execution_role || var.execution_role_arn != null\n error_message = \"execution_role_arn must be set when create_execution_role is false.\"\n }\n\n validation {\n condition = var.create_execution_role || (\n var.model_resource_arns == null && length(var.additional_execution_role_policy_statements) == 0\n )\n error_message = \"model_resource_arns and additional_execution_role_policy_statements configure the generated execution role, which is not created when create_execution_role is false. Grant those permissions on the supplied role instead.\"\n }\n}\n\nvariable \"execution_role_arn\" {\n description = \"ARN of an existing IAM role for the Harness to assume. Requires create_execution_role = false.\"\n type = string\n default = null\n}`;\n\n/** VPC and tag variables added after `additional_execution_role_policy_statements`. */\nconst VPC_VARIABLES_TEXT = `# VPC Configuration (optional)\nvariable \"enable_vpc\" {\n description = \"Run the Harness inside a VPC so it can reach private resources. Set alongside vpc_id/subnet_ids.\"\n type = bool\n default = false\n}\n\nvariable \"vpc_id\" {\n description = \"VPC ID to run the Harness in. Required when enable_vpc is true.\"\n type = string\n default = null\n\n validation {\n condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)\n error_message = \"vpc_id and subnet_ids must be set when enable_vpc is true.\"\n }\n}\n\nvariable \"subnet_ids\" {\n description = \"Subnet IDs to run the Harness in. Required when enable_vpc is true.\"\n type = list(string)\n default = null\n}\n\nvariable \"tags\" {\n description = \"Tags to apply to resources\"\n type = map(string)\n default = {}\n}`;\n\n/** Locals added to the module's existing `locals` block. */\nconst NEW_LOCALS_TEXT = ` execution_role_arn = var.create_execution_role ? aws_iam_role.execution_role[0].arn : var.execution_role_arn\n\n # The service provisions managed memory unless var.memory redirects it\n # elsewhere or turns it off.\n has_managed_memory = var.memory == null || var.memory.managed_memory_configuration != null`;\n\n/** Security group and egress rule, added before the Harness resource. */\nconst SECURITY_GROUP_TEXT = `# Security group for the Harness, used when running inside a VPC\nresource \"aws_security_group\" \"harness\" {\n count = var.enable_vpc ? 1 : 0\n\n #checkov:skip=CKV2_AWS_5:Attached to the Harness via its network configuration; Checkov cannot resolve this reference\n name_prefix = \"\\${local.harness_name_prefix}-harness-\"\n description = \"Security group for the \\${local.harness_name_prefix} Harness\"\n vpc_id = var.vpc_id\n tags = var.tags\n}\n\nresource \"aws_vpc_security_group_egress_rule\" \"harness_https\" {\n count = var.enable_vpc ? 1 : 0\n\n security_group_id = aws_security_group.harness[0].id\n cidr_ipv4 = \"0.0.0.0/0\"\n from_port = 443\n to_port = 443\n ip_protocol = \"tcp\"\n description = \"Allow outbound HTTPS to AWS service endpoints\"\n}`;\n\n/**\n * Native fields added to the Harness resource. `allowed_tools` is re-emitted\n * here, aligned with the rest, replacing the line the earlier\n * no-tools-by-default migration added.\n */\nconst HARNESS_FIELDS_TEXT = ` allowed_tools = var.allowed_tools\n environment_variables = var.environment_variables\n max_iterations = var.max_iterations\n timeout_seconds = var.timeout_seconds`;\n\nconst HARNESS_BLOCKS_TEXT = ` dynamic \"memory\" {\n for_each = var.memory != null ? [var.memory] : []\n content {\n dynamic \"managed_memory_configuration\" {\n for_each = memory.value.managed_memory_configuration != null ? [memory.value.managed_memory_configuration] : []\n content {\n strategies = managed_memory_configuration.value.strategies\n event_expiry_duration = managed_memory_configuration.value.event_expiry_duration\n encryption_key_arn = managed_memory_configuration.value.encryption_key_arn\n }\n }\n\n dynamic \"agentcore_memory_configuration\" {\n for_each = memory.value.agentcore_memory_configuration != null ? [memory.value.agentcore_memory_configuration] : []\n content {\n arn = agentcore_memory_configuration.value.arn\n actor_id = agentcore_memory_configuration.value.actor_id\n messages_count = agentcore_memory_configuration.value.messages_count\n }\n }\n\n dynamic \"disabled\" {\n for_each = memory.value.disabled ? [1] : []\n content {}\n }\n }\n }\n\n dynamic \"environment\" {\n for_each = var.enable_vpc ? [1] : []\n content {\n agentcore_runtime_environment {\n network_configuration {\n network_mode = \"VPC\"\n network_mode_config {\n security_groups = [aws_security_group.harness[0].id]\n subnets = var.subnet_ids\n }\n }\n }\n }\n }\n\n tags = var.tags`;\n\n/** The managed-memory grant, as its own policy scoped to the assigned ARN. */\nconst MANAGED_MEMORY_POLICY_TEXT = `# Scoped to the memory ARN the service assigns, which is only readable after the\n# Harness exists, so this is a policy of its own rather than a baseline\n# statement. Skipped when the Harness uses a role or memory the module did not\n# create.\nresource \"aws_iam_role_policy\" \"managed_memory\" {\n count = var.create_execution_role && local.has_managed_memory ? 1 : 0\n\n name = \"\\${local.harness_name_prefix}-HarnessManagedMemoryPolicy\"\n role = aws_iam_role.execution_role[0].id\n\n policy = jsonencode({\n Version = \"2012-10-17\"\n Statement = [{\n Sid = \"AgentCoreManagedMemory\"\n Effect = \"Allow\"\n Action = [\n \"bedrock-agentcore:CreateEvent\",\n \"bedrock-agentcore:DeleteEvent\",\n \"bedrock-agentcore:GetEvent\",\n \"bedrock-agentcore:ListEvents\",\n \"bedrock-agentcore:RetrieveMemoryRecords\",\n ]\n Resource = [\n aws_bedrockagentcore_harness.this.memory_actual[0].managed_memory_configuration[0].arn,\n ]\n }]\n })\n}`;\n\nconst SECURITY_GROUP_OUTPUT_TEXT = `output \"security_group_id\" {\n description = \"Security group ID of the Harness, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true.\"\n value = var.enable_vpc ? aws_security_group.harness[0].id : null\n}`;\n\n/**\n * The baseline policy, replaced whole: the managed-memory statement leaves it\n * for a policy of its own, and the resource gains a `count`. Rewriting the\n * statement list in place would strand the comment and comma around the\n * statement being removed.\n */\nconst BASELINE_POLICY_TEXT = `resource \"aws_iam_role_policy\" \"execution_role\" {\n count = var.create_execution_role ? 1 : 0\n\n name = \"\\${local.harness_name_prefix}-HarnessPolicy\"\n role = aws_iam_role.execution_role[0].id\n\n policy = jsonencode({\n Version = \"2012-10-17\"\n Statement = concat([\n {\n Sid = \"BedrockModelInvocation\"\n Effect = \"Allow\"\n Action = [\n \"bedrock:InvokeModel\",\n \"bedrock:InvokeModelWithResponseStream\",\n ]\n Resource = local.model_resource_arns\n },\n {\n #checkov:skip=CKV_AWS_355:EcrPublicTokenAccess requires a wildcard resource; ecr-public:GetAuthorizationToken has no resource-level permission\n Sid = \"EcrPublicTokenAccess\"\n Effect = \"Allow\"\n Action = [\"ecr-public:GetAuthorizationToken\"]\n Resource = [\"*\"]\n },\n {\n #checkov:skip=CKV_AWS_355:StsForEcrPublicPull requires a wildcard resource; sts:GetServiceBearerToken has no resource-level permission\n Sid = \"StsForEcrPublicPull\"\n Effect = \"Allow\"\n Action = [\"sts:GetServiceBearerToken\"]\n Resource = [\"*\"]\n },\n {\n #checkov:skip=CKV_AWS_355:XRayTracingAccess requires a wildcard resource; the X-Ray segment and sampling APIs have no resource-level permission\n #checkov:skip=CKV_AWS_290:XRayTracingAccess requires a wildcard resource; the X-Ray segment and sampling APIs have no resource-level permission\n Sid = \"XRayTracingAccess\"\n Effect = \"Allow\"\n Action = [\n \"xray:PutTraceSegments\",\n \"xray:PutTelemetryRecords\",\n \"xray:GetSamplingRules\",\n \"xray:GetSamplingTargets\",\n ]\n Resource = [\"*\"]\n },\n {\n Sid = \"CloudWatchLogsGroup\"\n Effect = \"Allow\"\n Action = [\n \"logs:CreateLogGroup\",\n \"logs:DescribeLogStreams\",\n ]\n Resource = [\n \"arn:\\${local.partition}:logs:\\${local.region}:\\${local.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*\",\n ]\n },\n {\n Sid = \"CloudWatchLogsDescribeGroups\"\n Effect = \"Allow\"\n Action = [\"logs:DescribeLogGroups\"]\n Resource = [\"arn:\\${local.partition}:logs:\\${local.region}:\\${local.account_id}:log-group:*\"]\n },\n {\n Sid = \"CloudWatchLogsStream\"\n Effect = \"Allow\"\n Action = [\n \"logs:CreateLogStream\",\n \"logs:PutLogEvents\",\n ]\n Resource = [\n \"arn:\\${local.partition}:logs:\\${local.region}:\\${local.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*:log-stream:*\",\n ]\n },\n {\n #checkov:skip=CKV_AWS_355:CloudWatchMetricsPublish requires a wildcard resource; cloudwatch:PutMetricData is scoped by the namespace condition instead\n #checkov:skip=CKV_AWS_290:CloudWatchMetricsPublish requires a wildcard resource; cloudwatch:PutMetricData is scoped by the namespace condition instead\n Sid = \"CloudWatchMetricsPublish\"\n Effect = \"Allow\"\n Action = [\"cloudwatch:PutMetricData\"]\n Resource = [\"*\"]\n Condition = {\n StringEquals = {\n \"cloudwatch:namespace\" = \"bedrock-agentcore\"\n }\n }\n },\n {\n Sid = \"AgentCoreWorkloadIdentity\"\n Effect = \"Allow\"\n Action = [\n \"bedrock-agentcore:GetWorkloadAccessToken\",\n \"bedrock-agentcore:GetWorkloadAccessTokenForJWT\",\n ]\n Resource = [\n \"arn:\\${local.partition}:bedrock-agentcore:\\${local.region}:\\${local.account_id}:workload-identity-directory/default\",\n \"arn:\\${local.partition}:bedrock-agentcore:\\${local.region}:\\${local.account_id}:workload-identity-directory/default/workload-identity/harness_\\${local.harness_name}-*\",\n ]\n },\n {\n Sid = \"AgentCoreBrowserDefault\"\n Effect = \"Allow\"\n Action = [\n \"bedrock-agentcore:StartBrowserSession\",\n \"bedrock-agentcore:StopBrowserSession\",\n \"bedrock-agentcore:GetBrowserSession\",\n \"bedrock-agentcore:ListBrowserSessions\",\n \"bedrock-agentcore:UpdateBrowserStream\",\n \"bedrock-agentcore:ConnectBrowserAutomationStream\",\n \"bedrock-agentcore:ConnectBrowserLiveViewStream\",\n ]\n Resource = [\n \"arn:\\${local.partition}:bedrock-agentcore:\\${local.region}:aws:browser/*\",\n ]\n },\n {\n Sid = \"AgentCoreCodeInterpreterDefault\"\n Effect = \"Allow\"\n Action = [\n \"bedrock-agentcore:StartCodeInterpreterSession\",\n \"bedrock-agentcore:StopCodeInterpreterSession\",\n \"bedrock-agentcore:GetCodeInterpreterSession\",\n \"bedrock-agentcore:ListCodeInterpreterSessions\",\n \"bedrock-agentcore:InvokeCodeInterpreter\",\n ]\n Resource = [\n \"arn:\\${local.partition}:bedrock-agentcore:\\${local.region}:aws:code-interpreter/*\",\n ]\n },\n ],\n # In VPC mode the Harness pulls its managed container from a private ECR\n # repository in the region rather than ECR Public, so it needs pull\n # permissions on it. The repository is service-owned, hence the wildcard\n # account.\n var.enable_vpc ? [\n {\n Sid = \"EcrManagedImagePull\"\n Effect = \"Allow\"\n Action = [\n \"ecr:BatchGetImage\",\n \"ecr:GetDownloadUrlForLayer\",\n \"ecr:BatchCheckLayerAvailability\",\n ]\n Resource = [\"arn:\\${local.partition}:ecr:\\${local.region}:*:repository/harness-*\"]\n },\n {\n #checkov:skip=CKV_AWS_355:EcrManagedImageToken requires a wildcard resource; ecr:GetAuthorizationToken has no resource-level permission\n Sid = \"EcrManagedImageToken\"\n Effect = \"Allow\"\n Action = [\"ecr:GetAuthorizationToken\"]\n Resource = [\"*\"]\n },\n ] : [],\n [\n # Null Sid/Condition fields are dropped from the rendered policy.\n for statement in var.additional_execution_role_policy_statements :\n { for key, value in statement : key => value if value != null }\n ])\n })\n}`;\n\n/**\n * Every shape the migration rewrites, so a module missing any of them is\n * reported rather than half-migrated.\n */\nconst REQUIRED_SHAPES = [\n '`variable \"model_resource_arns\" { $_ }`',\n '`variable \"additional_execution_role_policy_statements\" { $_ }`',\n '`locals { $_ }`',\n '`resource \"aws_iam_role\" \"execution_role\" { $_ }`',\n '`resource \"aws_iam_role_policy\" \"execution_role\" { $_ }`',\n '`resource \"aws_bedrockagentcore_harness\" \"this\" { $_ }`',\n '`output \"execution_role_arn\" { $_ }`',\n // The no-tools-by-default migration runs first, so its assignment is present\n // and is what the native fields below are anchored on.\n '`allowed_tools = var.allowed_tools`',\n];\n\n/**\n * The baseline policy is replaced whole, so it is only safe to touch when it\n * still carries exactly the statements the generator wrote. Any addition,\n * removal or reordering means the user has edited it, and the replacement would\n * discard that.\n */\nconst BASELINE_SIDS = [\n 'BedrockModelInvocation',\n 'EcrPublicTokenAccess',\n 'StsForEcrPublicPull',\n 'XRayTracingAccess',\n 'CloudWatchLogsGroup',\n 'CloudWatchLogsDescribeGroups',\n 'CloudWatchLogsStream',\n 'CloudWatchMetricsPublish',\n 'AgentCoreWorkloadIdentity',\n 'AgentCoreManagedMemory',\n 'AgentCoreBrowserDefault',\n 'AgentCoreCodeInterpreterDefault',\n];\n\n/**\n * Whether the module's baseline policy still carries exactly the generated\n * statements, in order. Sids are read from the whole file: the only other `Sid`\n * is the `optional(string)` field of the additional-statements variable, which\n * carries no string literal and so is filtered out.\n */\nconst hasUneditedBaselinePolicy = async (\n tree: Tree,\n filePath: string,\n): Promise<boolean> => {\n const sids = (await captureAllGritQL(tree, filePath, hcl('`Sid = $sid`')))\n .map((text) => /=\\s*\"([^\"]+)\"/.exec(text)?.[1])\n .filter((sid): sid is string => sid !== undefined);\n return (\n sids.length === BASELINE_SIDS.length &&\n sids.every((sid, index) => sid === BASELINE_SIDS[index])\n );\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(TERRAFORM_HARNESS_APP_DIR)) {\n return { nextSteps }; // This workspace has no Terraform harness modules.\n }\n\n for (const dirName of tree.children(TERRAFORM_HARNESS_APP_DIR)) {\n const filePath = joinPathFragments(\n TERRAFORM_HARNESS_APP_DIR,\n dirName,\n `${dirName}.tf`,\n );\n if (!tree.exists(filePath)) {\n continue; // Not a harness app module directory.\n }\n\n if (\n await matchGritQL(tree, filePath, hcl('`variable \"enable_vpc\" { $_ }`'))\n ) {\n continue; // Already migrated.\n }\n\n const shapeChecks = await Promise.all(\n REQUIRED_SHAPES.map((shape) => matchGritQL(tree, filePath, hcl(shape))),\n );\n if (\n shapeChecks.includes(false) ||\n !(await hasUneditedBaselinePolicy(tree, filePath))\n ) {\n nextSteps.push(divergedMessage(filePath));\n continue;\n }\n\n // Variables, ahead of the model/role variables they sit beside in the\n // template.\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`variable \"model_resource_arns\" { $body }\\` => \\`${GRIT_INSERT_PLACEHOLDER}\\n\\nvariable \"model_resource_arns\" {\\n $body\\n}\\``,\n ),\n NEW_VARIABLES_TEXT,\n );\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`variable \"additional_execution_role_policy_statements\" { $body }\\` => \\`variable \"additional_execution_role_policy_statements\" {\\n $body\\n}\\n\\n${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n VPC_VARIABLES_TEXT,\n );\n\n // Locals resolving the role ARN and whether managed memory applies.\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`locals { $body }\\` => \\`locals {\\n $body\\n\\n${GRIT_INSERT_PLACEHOLDER}\\n}\\``,\n ),\n NEW_LOCALS_TEXT,\n );\n\n // The role becomes conditional on none being supplied, so it is indexed\n // wherever it is referenced, and gains the shared tags.\n await applyGritQL(\n tree,\n filePath,\n hcl(\n '`resource \"aws_iam_role\" \"execution_role\" { $body }` => `resource \"aws_iam_role\" \"execution_role\" {\\n count = var.create_execution_role ? 1 : 0\\n\\n $body\\n\\n tags = var.tags\\n}`',\n ),\n );\n\n // The baseline policy is replaced whole, dropping the managed-memory\n // statement, which becomes a policy of its own scoped to the assigned ARN.\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`resource \"aws_iam_role_policy\" \"execution_role\" { $_ }\\` => \\`${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n BASELINE_POLICY_TEXT,\n );\n\n // The role ARN follows whichever role is in use, and the `allowed_tools`\n // line the no-tools-by-default migration added is re-aligned with the\n // native fields that now sit beside it.\n await applyGritQL(\n tree,\n filePath,\n hcl('`allowed_tools = var.allowed_tools` => ``'),\n );\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`execution_role_arn = aws_iam_role.execution_role.arn\\` => \\`execution_role_arn = local.execution_role_arn\\n\\n${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n HARNESS_FIELDS_TEXT,\n );\n // Ahead of `depends_on`, which the resource ends with.\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`depends_on = [aws_iam_role_policy.execution_role]\\` => \\`${GRIT_INSERT_PLACEHOLDER}\\n\\n depends_on = [aws_iam_role_policy.execution_role]\\``,\n ),\n // The placeholder already sits at the block's indentation.\n HARNESS_BLOCKS_TEXT.replace(/^ {2}/, ''),\n );\n\n // Security group ahead of the Harness resource, and the managed-memory\n // policy after it, since it reads an attribute of the deployed Harness.\n // Anchored on the comment introducing the resource so it stays attached.\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`# Omitting authorizer_configuration uses IAM inbound authorization; add a\\` => \\`${GRIT_INSERT_PLACEHOLDER}\\n\\n# Omitting authorizer_configuration uses IAM inbound authorization; add a\\``,\n ),\n SECURITY_GROUP_TEXT,\n );\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`resource \"aws_bedrockagentcore_harness\" \"this\" { $body }\\` => \\`resource \"aws_bedrockagentcore_harness\" \"this\" {\\n $body\\n}\\n\\n${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n MANAGED_MEMORY_POLICY_TEXT,\n );\n\n // The role ARN output follows whichever role is in use, and the security\n // group is exposed for ingress rules on resources the Harness reaches.\n await applyGritQL(\n tree,\n filePath,\n hcl(\n '`output \"execution_role_arn\" { $_ }` => `output \"execution_role_arn\" {\\n description = \"ARN of the IAM role assumed by the Harness, whether generated or supplied via var.execution_role_arn\"\\n value = local.execution_role_arn\\n}`',\n ),\n );\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`output \"execution_role_arn\" { $body }\\` => \\`output \"execution_role_arn\" {\\n $body\\n}\\n\\n${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n SECURITY_GROUP_OUTPUT_TEXT,\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","applyGritQL","captureAllGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_TERRAFORM_DIR","TERRAFORM_HARNESS_APP_DIR","hcl","pattern","divergedMessage","filePath","NEW_VARIABLES_TEXT","VPC_VARIABLES_TEXT","NEW_LOCALS_TEXT","SECURITY_GROUP_TEXT","HARNESS_FIELDS_TEXT","HARNESS_BLOCKS_TEXT","MANAGED_MEMORY_POLICY_TEXT","SECURITY_GROUP_OUTPUT_TEXT","BASELINE_POLICY_TEXT","REQUIRED_SHAPES","BASELINE_SIDS","hasUneditedBaselinePolicy","tree","sids","map","text","exec","filter","sid","undefined","length","every","index","migration","nextSteps","exists","dirName","children","shapeChecks","Promise","all","shape","includes","push","replace"],"mappings":"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"}
|
package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type MigrationReturnObject, type Tree } from '@nx/devkit';
|
|
6
|
+
export default function migration(tree: Tree): Promise<MigrationReturnObject>;
|