@aws/nx-plugin-mcp 1.0.0-rc.82 → 1.0.0-rc.84
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/docs/guides/agentcore-harness.mdx +66 -29
- package/docs/guides/connection/py-agent-dynamodb.mdx +30 -31
- package/docs/guides/connection/py-mcp-server-dynamodb.mdx +30 -31
- package/docs/guides/connection/ts-agent-dynamodb.mdx +30 -31
- package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +30 -31
- package/docs/snippets/connection/lambda-dynamodb-access.mdx +1 -1
- package/docs/snippets/dynamodb/deploying-table.mdx +33 -4
- package/docs/snippets/rdb/deletion-protection.mdx +33 -3
- package/docs/snippets/rdb/performance-insights.mdx +2 -0
- package/docs/snippets/rdb/serverless-capacity.mdx +1 -1
- package/package.json +1 -1
|
@@ -94,7 +94,7 @@ const harness = new MyHarness(this, 'MyHarness', {
|
|
|
94
94
|
|
|
95
95
|
The construct also accepts:
|
|
96
96
|
|
|
97
|
-
- `allowedTools` — the tools the Harness may use.
|
|
97
|
+
- `allowedTools` — the tools the Harness may use. Defaults to none, see <a href="#configuring-tools">Configuring tools</a>.
|
|
98
98
|
- `executionRole` — an existing IAM role to use instead of the generated role. A supplied role is used as-is: the baseline permissions are not added to it, and its ARN always feeds the Harness (the raw `executionRoleArn` string cannot be overridden).
|
|
99
99
|
- `modelResourceArns` — the Bedrock model and inference-profile ARNs the generated execution role may invoke, replacing the default list.
|
|
100
100
|
- `vpc`, `vpcSubnets` and `securityGroups` — run the Harness in a VPC so it can reach private resources, see <a href="#running-in-a-vpc">Running in a VPC</a>.
|
|
@@ -112,15 +112,21 @@ module "my_harness" {
|
|
|
112
112
|
}
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
-
The module exposes
|
|
115
|
+
The module exposes the following variables:
|
|
116
116
|
|
|
117
117
|
- `model_id` — the Bedrock model or inference profile the Harness uses by default.
|
|
118
|
-
- `
|
|
119
|
-
- `
|
|
118
|
+
- `allowed_tools` — the tools the Harness may use. Defaults to none, see <a href="#configuring-tools">Configuring tools</a>.
|
|
119
|
+
- `memory` — the Harness memory configuration, see <a href="#configuring-memory">Configuring memory</a>.
|
|
120
|
+
- `environment_variables`, `max_iterations`, `timeout_seconds` — the corresponding native Harness fields.
|
|
121
|
+
- `execution_role_arn` — an existing IAM role to use instead of the generated role. A supplied role is used as-is: neither the role nor its baseline policy is created, so `model_resource_arns` and `additional_execution_role_policy_statements` cannot be combined with it.
|
|
122
|
+
- `model_resource_arns` — the Bedrock model and inference-profile ARNs the generated execution role may invoke, replacing the default list.
|
|
123
|
+
- `additional_execution_role_policy_statements` — a list of IAM statement objects (`Effect`, `Action`, `Resource`, optional `Sid` and `Condition`) appended to the generated execution role policy.
|
|
124
|
+
- `enable_vpc`, `vpc_id`, `subnet_ids` — run the Harness in a VPC so it can reach private resources, see <a href="#running-in-a-vpc">Running in a VPC</a>.
|
|
125
|
+
- `tags` — tags applied to the resources the module creates.
|
|
120
126
|
|
|
121
|
-
|
|
127
|
+
Other provider-native fields are configured by editing the generated `aws_bedrockagentcore_harness` resource in the module itself, see <a href="#customizing-your-harness">Customizing your Harness</a>.
|
|
122
128
|
|
|
123
|
-
The module outputs `harness_id`, `harness_arn`, and `
|
|
129
|
+
The module outputs `harness_id`, `harness_arn`, `execution_role_arn` and `security_group_id`.
|
|
124
130
|
|
|
125
131
|
Deploy with your Terraform project's plan/apply workflow as usual — see the <Link path="guides/terraform-project">Terraform project guide</Link>.
|
|
126
132
|
</Fragment>
|
|
@@ -196,7 +202,7 @@ With neither set, the script fails with an error naming both options.
|
|
|
196
202
|
Every native Harness property of the pinned `aws-cdk-lib/aws-bedrockagentcore` module is available through the construct's props — alternate model providers, tool definitions, memory, skills, environment configuration, truncation, custom JWT authorization, and execution limits — and explicit props take precedence over the generated defaults. Alternatively, edit the generated construct in `packages/common/constructs/src/app/harnesses/<name>/<name>.ts`.
|
|
197
203
|
</Fragment>
|
|
198
204
|
<Fragment slot="terraform">
|
|
199
|
-
The
|
|
205
|
+
The module's variables cover the fields most deployments configure — `model_id`, `allowed_tools`, `memory`, `environment_variables`, `max_iterations`, `timeout_seconds` — plus the execution role and VPC placement. Terraform has no equivalent of the CDK construct's prop spread, so the remaining provider-native fields are configured by editing the `aws_bedrockagentcore_harness` resource in `packages/common/terraform/src/app/harnesses/<name>/<name>.tf`: alternate model providers (`gemini_model_config`, `openai_model_config`), `tool` blocks, `skill` blocks, `environment_artifact`, filesystem and lifecycle configuration under `environment`, `truncation`, and `authorizer_configuration` with a `custom_jwt_authorizer`.
|
|
200
206
|
</Fragment>
|
|
201
207
|
</Infrastructure>
|
|
202
208
|
|
|
@@ -213,19 +219,47 @@ new MyHarness(this, 'Harness', { allowedTools: ['@builtin'] });
|
|
|
213
219
|
```
|
|
214
220
|
</Fragment>
|
|
215
221
|
<Fragment slot="terraform">
|
|
216
|
-
```hcl title="packages/
|
|
217
|
-
|
|
218
|
-
|
|
222
|
+
```hcl title="packages/infra/src/main.tf"
|
|
223
|
+
module "my_harness" {
|
|
224
|
+
source = "../../common/terraform/src/app/harnesses/my-harness"
|
|
219
225
|
allowed_tools = ["@builtin"]
|
|
220
226
|
}
|
|
221
227
|
```
|
|
222
|
-
|
|
223
|
-
Add an `allowed_tools` variable to the module if you would rather set it as a module argument where you reference the module.
|
|
224
228
|
</Fragment>
|
|
225
229
|
</Infrastructure>
|
|
226
230
|
|
|
227
231
|
Narrow `@builtin` to specific patterns such as `@builtin/file_operations` to restrict what the agent loop can do. See [Harness tools](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/harness-tools.html) for the built-in tools you can add.
|
|
228
232
|
|
|
233
|
+
### Configuring memory
|
|
234
|
+
|
|
235
|
+
The service provisions managed memory for the Harness by default, and the generated execution role is granted access to it — scoped to the memory ARN the service assigns, and only granted while the Harness uses managed memory the infrastructure created. Configure memory explicitly to tune that managed memory, point the Harness at a memory resource you own, or turn memory off:
|
|
236
|
+
|
|
237
|
+
<Infrastructure>
|
|
238
|
+
<Fragment slot="cdk">
|
|
239
|
+
```ts
|
|
240
|
+
new MyHarness(this, 'MyHarness', {
|
|
241
|
+
memory: { managedMemoryConfiguration: { strategies: ['SUMMARIZATION'] } },
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Supplying `memory` at all replaces the default managed memory, so the construct leaves the memory grant off the execution role: add whatever the configuration needs with `addToRolePolicy`.
|
|
246
|
+
</Fragment>
|
|
247
|
+
<Fragment slot="terraform">
|
|
248
|
+
```hcl
|
|
249
|
+
module "my_harness" {
|
|
250
|
+
source = "../../common/terraform/src/app/harnesses/my-harness"
|
|
251
|
+
memory = {
|
|
252
|
+
managed_memory_configuration = {
|
|
253
|
+
strategies = ["SUMMARIZATION"]
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Set exactly one of `managed_memory_configuration` (tune the service's managed memory), `agentcore_memory_configuration` (use a memory resource you own, by ARN) or `disabled` (no memory). Choosing `agentcore_memory_configuration` or `disabled` drops the managed-memory grant from the execution role; for your own memory resource, grant access through `additional_execution_role_policy_statements`.
|
|
260
|
+
</Fragment>
|
|
261
|
+
</Infrastructure>
|
|
262
|
+
|
|
229
263
|
### Running in a VPC
|
|
230
264
|
|
|
231
265
|
<Infrastructure>
|
|
@@ -241,28 +275,31 @@ database.connections.allowDefaultPortFrom(harness, 'Harness to database');
|
|
|
241
275
|
The Harness is placed in the VPC's private subnets with egress, in a security group created for it. Override either with `vpcSubnets` and `securityGroups`. Both require `vpc`, and `connections` is only available when the Harness runs in a VPC.
|
|
242
276
|
</Fragment>
|
|
243
277
|
<Fragment slot="terraform">
|
|
244
|
-
|
|
278
|
+
Set `enable_vpc` alongside `vpc_id` and `subnet_ids` to run the Harness inside a VPC, so it can reach private resources such as a database:
|
|
245
279
|
|
|
246
|
-
```hcl
|
|
247
|
-
|
|
248
|
-
|
|
280
|
+
```hcl
|
|
281
|
+
module "my_harness" {
|
|
282
|
+
source = "../../common/terraform/src/app/harnesses/my-harness"
|
|
283
|
+
enable_vpc = true
|
|
284
|
+
vpc_id = var.vpc_id
|
|
285
|
+
subnet_ids = var.private_subnet_ids
|
|
249
286
|
}
|
|
287
|
+
```
|
|
250
288
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
289
|
+
The module creates a security group for the Harness, allowing outbound HTTPS only. Its `security_group_id` output is what resources the Harness must reach reference in their own ingress rules:
|
|
290
|
+
|
|
291
|
+
```hcl
|
|
292
|
+
resource "aws_vpc_security_group_ingress_rule" "harness_to_database" {
|
|
293
|
+
security_group_id = aws_security_group.database.id
|
|
294
|
+
referenced_security_group_id = module.my_harness.security_group_id
|
|
295
|
+
from_port = 5432
|
|
296
|
+
to_port = 5432
|
|
297
|
+
ip_protocol = "tcp"
|
|
298
|
+
description = "Harness to database"
|
|
264
299
|
}
|
|
265
300
|
```
|
|
301
|
+
|
|
302
|
+
`security_group_id` is null unless `enable_vpc` is true, and `vpc_id` and `subnet_ids` are both required when it is.
|
|
266
303
|
</Fragment>
|
|
267
304
|
</Infrastructure>
|
|
268
305
|
|
|
@@ -70,42 +70,41 @@ table.grantReadWriteData(myAgent);
|
|
|
70
70
|
</Fragment>
|
|
71
71
|
<Fragment slot="terraform">
|
|
72
72
|
|
|
73
|
+
Grant the agent's runtime role access to the table and its KMS encryption key via `additional_iam_policy_statements`:
|
|
74
|
+
|
|
73
75
|
```hcl title="packages/infra/src/main.tf"
|
|
74
76
|
module "my_table" {
|
|
75
77
|
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
]
|
|
108
|
-
})
|
|
80
|
+
module "my_agent" {
|
|
81
|
+
source = "../../common/terraform/src/app/agents/my-agent"
|
|
82
|
+
|
|
83
|
+
additional_iam_policy_statements = [
|
|
84
|
+
{
|
|
85
|
+
Effect = "Allow"
|
|
86
|
+
Action = [
|
|
87
|
+
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
|
|
88
|
+
"dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan",
|
|
89
|
+
"dynamodb:BatchGetItem", "dynamodb:BatchWriteItem",
|
|
90
|
+
]
|
|
91
|
+
Resource = [
|
|
92
|
+
module.my_table.table_arn,
|
|
93
|
+
"${module.my_table.table_arn}/index/*",
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
Effect = "Allow"
|
|
98
|
+
Action = [
|
|
99
|
+
"kms:Encrypt",
|
|
100
|
+
"kms:Decrypt",
|
|
101
|
+
"kms:ReEncrypt*",
|
|
102
|
+
"kms:GenerateDataKey*",
|
|
103
|
+
"kms:DescribeKey",
|
|
104
|
+
]
|
|
105
|
+
Resource = [module.my_table.kms_key_arn]
|
|
106
|
+
},
|
|
107
|
+
]
|
|
109
108
|
}
|
|
110
109
|
```
|
|
111
110
|
</Fragment>
|
|
@@ -70,42 +70,41 @@ table.grantReadWriteData(myMcpServer);
|
|
|
70
70
|
</Fragment>
|
|
71
71
|
<Fragment slot="terraform">
|
|
72
72
|
|
|
73
|
+
Grant the MCP server's runtime role access to the table and its KMS encryption key via `additional_iam_policy_statements`:
|
|
74
|
+
|
|
73
75
|
```hcl title="packages/infra/src/main.tf"
|
|
74
76
|
module "my_table" {
|
|
75
77
|
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
]
|
|
108
|
-
})
|
|
80
|
+
module "my_mcp_server" {
|
|
81
|
+
source = "../../common/terraform/src/app/mcp-servers/my-mcp-server"
|
|
82
|
+
|
|
83
|
+
additional_iam_policy_statements = [
|
|
84
|
+
{
|
|
85
|
+
Effect = "Allow"
|
|
86
|
+
Action = [
|
|
87
|
+
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
|
|
88
|
+
"dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan",
|
|
89
|
+
"dynamodb:BatchGetItem", "dynamodb:BatchWriteItem",
|
|
90
|
+
]
|
|
91
|
+
Resource = [
|
|
92
|
+
module.my_table.table_arn,
|
|
93
|
+
"${module.my_table.table_arn}/index/*",
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
Effect = "Allow"
|
|
98
|
+
Action = [
|
|
99
|
+
"kms:Encrypt",
|
|
100
|
+
"kms:Decrypt",
|
|
101
|
+
"kms:ReEncrypt*",
|
|
102
|
+
"kms:GenerateDataKey*",
|
|
103
|
+
"kms:DescribeKey",
|
|
104
|
+
]
|
|
105
|
+
Resource = [module.my_table.kms_key_arn]
|
|
106
|
+
},
|
|
107
|
+
]
|
|
109
108
|
}
|
|
110
109
|
```
|
|
111
110
|
</Fragment>
|
|
@@ -82,42 +82,41 @@ table.grantReadWriteData(myAgent);
|
|
|
82
82
|
</Fragment>
|
|
83
83
|
<Fragment slot="terraform">
|
|
84
84
|
|
|
85
|
+
Grant the agent's runtime role access to the table and its KMS encryption key via `additional_iam_policy_statements`:
|
|
86
|
+
|
|
85
87
|
```hcl title="packages/infra/src/main.tf"
|
|
86
88
|
module "my_table" {
|
|
87
89
|
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
},
|
|
119
|
-
]
|
|
120
|
-
})
|
|
92
|
+
module "my_agent" {
|
|
93
|
+
source = "../../common/terraform/src/app/agents/my-agent"
|
|
94
|
+
|
|
95
|
+
additional_iam_policy_statements = [
|
|
96
|
+
{
|
|
97
|
+
Effect = "Allow"
|
|
98
|
+
Action = [
|
|
99
|
+
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
|
|
100
|
+
"dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan",
|
|
101
|
+
"dynamodb:BatchGetItem", "dynamodb:BatchWriteItem",
|
|
102
|
+
]
|
|
103
|
+
Resource = [
|
|
104
|
+
module.my_table.table_arn,
|
|
105
|
+
"${module.my_table.table_arn}/index/*",
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
Effect = "Allow"
|
|
110
|
+
Action = [
|
|
111
|
+
"kms:Encrypt",
|
|
112
|
+
"kms:Decrypt",
|
|
113
|
+
"kms:ReEncrypt*",
|
|
114
|
+
"kms:GenerateDataKey*",
|
|
115
|
+
"kms:DescribeKey",
|
|
116
|
+
]
|
|
117
|
+
Resource = [module.my_table.kms_key_arn]
|
|
118
|
+
},
|
|
119
|
+
]
|
|
121
120
|
}
|
|
122
121
|
```
|
|
123
122
|
</Fragment>
|
|
@@ -79,42 +79,41 @@ table.grantReadWriteData(myMcpServer);
|
|
|
79
79
|
</Fragment>
|
|
80
80
|
<Fragment slot="terraform">
|
|
81
81
|
|
|
82
|
+
Grant the MCP server's runtime role access to the table and its KMS encryption key via `additional_iam_policy_statements`:
|
|
83
|
+
|
|
82
84
|
```hcl title="packages/infra/src/main.tf"
|
|
83
85
|
module "my_table" {
|
|
84
86
|
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
},
|
|
116
|
-
]
|
|
117
|
-
})
|
|
89
|
+
module "my_mcp_server" {
|
|
90
|
+
source = "../../common/terraform/src/app/mcp-servers/my-mcp-server"
|
|
91
|
+
|
|
92
|
+
additional_iam_policy_statements = [
|
|
93
|
+
{
|
|
94
|
+
Effect = "Allow"
|
|
95
|
+
Action = [
|
|
96
|
+
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
|
|
97
|
+
"dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan",
|
|
98
|
+
"dynamodb:BatchGetItem", "dynamodb:BatchWriteItem",
|
|
99
|
+
]
|
|
100
|
+
Resource = [
|
|
101
|
+
module.my_table.table_arn,
|
|
102
|
+
"${module.my_table.table_arn}/index/*",
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
Effect = "Allow"
|
|
107
|
+
Action = [
|
|
108
|
+
"kms:Encrypt",
|
|
109
|
+
"kms:Decrypt",
|
|
110
|
+
"kms:ReEncrypt*",
|
|
111
|
+
"kms:GenerateDataKey*",
|
|
112
|
+
"kms:DescribeKey",
|
|
113
|
+
]
|
|
114
|
+
Resource = [module.my_table.kms_key_arn]
|
|
115
|
+
},
|
|
116
|
+
]
|
|
118
117
|
}
|
|
119
118
|
```
|
|
120
119
|
</Fragment>
|
|
@@ -46,7 +46,7 @@ This provisions a DynamoDB table with:
|
|
|
46
46
|
- On-demand (`PAY_PER_REQUEST`) billing
|
|
47
47
|
- Customer-managed KMS encryption with automatic key rotation
|
|
48
48
|
- Point-in-time recovery enabled
|
|
49
|
-
- Deletion protection enabled
|
|
49
|
+
- Deletion protection enabled, plus a `prevent_destroy` lifecycle guard
|
|
50
50
|
- Table name registered in Runtime Config under the `dynamodb` namespace in AWS AppConfig
|
|
51
51
|
|
|
52
52
|
The `core/runtime-config/appconfig` module exposes the `dynamodb` namespace by default, so the table name is deployed without further configuration. If you pass `namespaces` to that module explicitly, keep `dynamodb` in the list — otherwise no configuration profile is created for it and the generated table client cannot resolve the table name.
|
|
@@ -55,20 +55,33 @@ The `core/runtime-config/appconfig` module exposes the `dynamodb` namespace by d
|
|
|
55
55
|
|
|
56
56
|
### Deletion Protection
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
The table is protected by two independent guards, so that turning off either one alone cannot delete your data:
|
|
59
|
+
|
|
60
|
+
<Infrastructure>
|
|
61
|
+
<Fragment slot="cdk">
|
|
62
|
+
- `deletionProtection`, enforced by DynamoDB.
|
|
63
|
+
- `RemovalPolicy.RETAIN`, enforced by CloudFormation, which leaves the table in place when it is removed from the stack.
|
|
64
|
+
</Fragment>
|
|
65
|
+
<Fragment slot="terraform">
|
|
66
|
+
- `deletion_protection_enabled`, enforced by DynamoDB.
|
|
67
|
+
- `lifecycle { prevent_destroy = true }` on the table in `common/terraform/src/core/dynamodb/dynamodb.tf`, enforced by Terraform, which fails any plan that would destroy the table.
|
|
68
|
+
</Fragment>
|
|
69
|
+
</Infrastructure>
|
|
59
70
|
|
|
60
|
-
####
|
|
71
|
+
#### Deleting the Table
|
|
61
72
|
|
|
62
|
-
Disable
|
|
73
|
+
Disable protection for environments where table deletion is expected, such as short-lived development or preview stacks.
|
|
63
74
|
|
|
64
75
|
<Infrastructure>
|
|
65
76
|
<Fragment slot="cdk">
|
|
66
77
|
|
|
67
78
|
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
79
|
+
import { RemovalPolicy } from 'aws-cdk-lib';
|
|
68
80
|
import { MyTable } from '@my-scope/common-constructs';
|
|
69
81
|
|
|
70
82
|
const table = new MyTable(this, 'Table', {
|
|
71
83
|
deletionProtection: false,
|
|
84
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
72
85
|
});
|
|
73
86
|
```
|
|
74
87
|
</Fragment>
|
|
@@ -80,6 +93,22 @@ module "my_table" {
|
|
|
80
93
|
deletion_protection_enabled = false
|
|
81
94
|
}
|
|
82
95
|
```
|
|
96
|
+
|
|
97
|
+
`prevent_destroy` must be a literal — Terraform does not allow it to reference a variable — so it cannot be turned off from `main.tf`. Also remove the `lifecycle` block from the table in `common/terraform/src/core/dynamodb/dynamodb.tf`:
|
|
98
|
+
|
|
99
|
+
```hcl title="packages/common/terraform/src/core/dynamodb/dynamodb.tf" del={4-6}
|
|
100
|
+
resource "aws_dynamodb_table" "table" {
|
|
101
|
+
# ...
|
|
102
|
+
|
|
103
|
+
lifecycle {
|
|
104
|
+
prevent_destroy = true
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
:::caution
|
|
110
|
+
This module is shared by every table in your workspace, so removing the block removes that guard for all of them.
|
|
111
|
+
:::
|
|
83
112
|
</Fragment>
|
|
84
113
|
</Infrastructure>
|
|
85
114
|
|
|
@@ -3,21 +3,34 @@ title: Deletion Protection
|
|
|
3
3
|
---
|
|
4
4
|
import Infrastructure from '@components/infrastructure.astro';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
The Aurora cluster is protected by two independent guards, so that turning off either one alone cannot delete your data:
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
<Infrastructure>
|
|
9
|
+
<Fragment slot="cdk">
|
|
10
|
+
- `deletionProtection`, enforced by RDS.
|
|
11
|
+
- `RemovalPolicy.RETAIN`, enforced by CloudFormation, which leaves the cluster in place when it is removed from the stack.
|
|
12
|
+
</Fragment>
|
|
13
|
+
<Fragment slot="terraform">
|
|
14
|
+
- `deletion_protection`, enforced by RDS.
|
|
15
|
+
- `lifecycle { prevent_destroy = true }` on the cluster in `common/terraform/src/core/rdb/aurora/aurora.tf`, enforced by Terraform, which fails any plan that would destroy the cluster.
|
|
16
|
+
</Fragment>
|
|
17
|
+
</Infrastructure>
|
|
18
|
+
|
|
19
|
+
#### Deleting the Database
|
|
9
20
|
|
|
10
|
-
You can disable
|
|
21
|
+
You can disable protection for environments where database deletion is expected, such as short-lived development or preview stacks.
|
|
11
22
|
|
|
12
23
|
<Infrastructure>
|
|
13
24
|
<Fragment slot="cdk">
|
|
14
25
|
|
|
15
26
|
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
27
|
+
import { RemovalPolicy } from 'aws-cdk-lib';
|
|
16
28
|
import { MyDatabase } from '@my-scope/common-constructs';
|
|
17
29
|
|
|
18
30
|
const db = new MyDatabase(this, 'Db', {
|
|
19
31
|
...
|
|
20
32
|
deletionProtection: false,
|
|
33
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
21
34
|
});
|
|
22
35
|
```
|
|
23
36
|
</Fragment>
|
|
@@ -28,7 +41,24 @@ module "my_database" {
|
|
|
28
41
|
source = "../../common/terraform/src/app/dbs/my-database"
|
|
29
42
|
...
|
|
30
43
|
deletion_protection = false
|
|
44
|
+
skip_final_snapshot = true
|
|
31
45
|
}
|
|
32
46
|
```
|
|
47
|
+
|
|
48
|
+
`prevent_destroy` must be a literal — Terraform does not allow it to reference a variable — so it cannot be turned off from `main.tf`. Also remove the `lifecycle` block from the cluster in `common/terraform/src/core/rdb/aurora/aurora.tf`:
|
|
49
|
+
|
|
50
|
+
```hcl title="packages/common/terraform/src/core/rdb/aurora/aurora.tf" del={4-6}
|
|
51
|
+
resource "aws_rds_cluster" "database" {
|
|
52
|
+
# ...
|
|
53
|
+
|
|
54
|
+
lifecycle {
|
|
55
|
+
prevent_destroy = true
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
:::caution
|
|
61
|
+
This module is shared by every database in your workspace, so removing the block removes that guard for all of them.
|
|
62
|
+
:::
|
|
33
63
|
</Fragment>
|
|
34
64
|
</Infrastructure>
|
|
@@ -5,6 +5,8 @@ import Infrastructure from '@components/infrastructure.astro';
|
|
|
5
5
|
|
|
6
6
|
Performance Insights is enabled on the Aurora writer instance by default (encrypted with the cluster's KMS key). Aurora engine logs are also exported to [CloudWatch Logs](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_LogAccess.html) by default, configured to surface schema-level activity without leaking row data.
|
|
7
7
|
|
|
8
|
+
Exported log volume — and so [CloudWatch Logs ingestion cost](https://aws.amazon.com/cloudwatch/pricing/) — scales with schema changes and connections rather than query traffic, since the log types that carry full statement text are excluded. On Aurora MySQL the `CONNECT` audit event is emitted per connection, so workloads that open a connection per request produce more than ones that pool.
|
|
9
|
+
|
|
8
10
|
Disable log export per database if not required:
|
|
9
11
|
|
|
10
12
|
<Infrastructure>
|
|
@@ -3,7 +3,7 @@ title: Serverless Capacity
|
|
|
3
3
|
---
|
|
4
4
|
import Infrastructure from '@components/infrastructure.astro';
|
|
5
5
|
|
|
6
|
-
Control Aurora Serverless v2 scaling limits to match your workload.
|
|
6
|
+
Control Aurora Serverless v2 scaling limits to match your workload. Both providers default to a minimum of 0.5 ACUs and a maximum of 4.
|
|
7
7
|
|
|
8
8
|
<Infrastructure>
|
|
9
9
|
<Fragment slot="cdk">
|