@aws/nx-plugin-mcp 1.0.0-rc.82 → 1.0.0-rc.83

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.
@@ -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
- resource "aws_iam_role_policy" "dynamodb_access" {
79
- role = module.my_agent.lambda_role_name
80
-
81
- policy = jsonencode({
82
- Version = "2012-10-17"
83
- Statement = [
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
- ]
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
- resource "aws_iam_role_policy" "dynamodb_access" {
79
- role = module.my_mcp_server.lambda_role_name
80
-
81
- policy = jsonencode({
82
- Version = "2012-10-17"
83
- Statement = [
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
- ]
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
- resource "aws_iam_role_policy" "dynamodb_access" {
91
- role = module.my_agent.lambda_role_name
92
-
93
- policy = jsonencode({
94
- Version = "2012-10-17"
95
- Statement = [
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
- ]
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
- resource "aws_iam_role_policy" "dynamodb_access" {
88
- role = module.my_mcp_server.lambda_role_name
89
-
90
- policy = jsonencode({
91
- Version = "2012-10-17"
92
- Statement = [
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
- ]
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>
@@ -38,7 +38,7 @@ module "my_table" {
38
38
  }
39
39
 
40
40
  resource "aws_iam_role_policy" "dynamodb_access" {
41
- role = module.my_api.lambda_role_name
41
+ role = module.my_api.lambda_execution_role_name
42
42
 
43
43
  policy = jsonencode({
44
44
  Version = "2012-10-17"
@@ -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
- Deletion protection is enabled by default to prevent accidental table deletion.
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
- #### Disable Deletion Protection
71
+ #### Deleting the Table
61
72
 
62
- Disable it for environments where table deletion is expected, such as short-lived development or preview stacks.
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
- Deletion protection is enabled by default (`deletionProtection: true` in CDK, `deletion_protection = true` in Terraform) to protect the Aurora cluster from accidental deletion.
6
+ The Aurora cluster is protected by two independent guards, so that turning off either one alone cannot delete your data:
7
7
 
8
- #### Disable Deletion Protection
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 deletion protection for environments where database deletion is expected, such as short-lived development or preview stacks.
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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws/nx-plugin-mcp",
3
- "version": "1.0.0-rc.82",
3
+ "version": "1.0.0-rc.83",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/awslabs/nx-plugin-for-aws.git",