@aws-blocks/bb-distributed-table 0.1.4 → 0.1.6
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/DESIGN.md +18 -1
- package/README.md +57 -1
- package/dist/index.aws.d.ts +3 -2
- package/dist/index.aws.d.ts.map +1 -1
- package/dist/index.aws.js +3 -0
- package/dist/index.cdk.d.ts +12 -2
- package/dist/index.cdk.d.ts.map +1 -1
- package/dist/index.cdk.js +137 -6
- package/dist/index.cdk.test.js +324 -3
- package/dist/index.mock.d.ts +3 -2
- package/dist/index.mock.d.ts.map +1 -1
- package/dist/index.mock.js +3 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/src/index.aws.ts +6 -0
- package/src/index.cdk.test.ts +353 -3
- package/src/index.cdk.ts +152 -8
- package/src/index.mock.ts +6 -0
- package/src/types.ts +85 -0
- package/src/version.ts +1 -1
package/dist/index.cdk.test.js
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
import { test } from 'node:test';
|
|
13
13
|
import assert from 'node:assert';
|
|
14
14
|
import * as cdk from 'aws-cdk-lib';
|
|
15
|
-
import { Template } from 'aws-cdk-lib/assertions';
|
|
16
|
-
import { Scope, DEFAULT_NODE_RUNTIME } from '@aws-blocks/core/cdk';
|
|
15
|
+
import { Template, Match, Annotations } from 'aws-cdk-lib/assertions';
|
|
16
|
+
import { Scope, DEFAULT_NODE_RUNTIME, BlocksPresets } from '@aws-blocks/core/cdk';
|
|
17
17
|
import { z } from 'zod';
|
|
18
18
|
import { DistributedTable } from './index.cdk.js';
|
|
19
19
|
const userSchema = z.object({
|
|
@@ -23,21 +23,28 @@ const userSchema = z.object({
|
|
|
23
23
|
});
|
|
24
24
|
class StubBlocksStack extends cdk.Stack {
|
|
25
25
|
handler;
|
|
26
|
+
executionRole;
|
|
26
27
|
id;
|
|
28
|
+
defaults = BlocksPresets.production;
|
|
27
29
|
constructor(scope, id) {
|
|
28
30
|
super(scope, id);
|
|
29
31
|
this.id = id;
|
|
30
32
|
globalThis.CURRENT_BLOCKS_STACK = this;
|
|
33
|
+
this.executionRole = new cdk.aws_iam.Role(this, 'BlocksRole', {
|
|
34
|
+
assumedBy: new cdk.aws_iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
35
|
+
});
|
|
31
36
|
this.handler = new cdk.aws_lambda.Function(this, 'StubHandler', {
|
|
32
37
|
runtime: DEFAULT_NODE_RUNTIME,
|
|
33
38
|
handler: 'index.handler',
|
|
34
39
|
code: cdk.aws_lambda.Code.fromInline('exports.handler = async () => {};'),
|
|
40
|
+
role: this.executionRole,
|
|
35
41
|
});
|
|
36
42
|
}
|
|
37
43
|
}
|
|
38
|
-
function setup() {
|
|
44
|
+
function setup(defaults = BlocksPresets.production) {
|
|
39
45
|
const app = new cdk.App();
|
|
40
46
|
const stack = new StubBlocksStack(app, 'TestStack');
|
|
47
|
+
stack.defaults = defaults;
|
|
41
48
|
const parent = new Scope('app');
|
|
42
49
|
return { stack, parent };
|
|
43
50
|
}
|
|
@@ -50,6 +57,281 @@ test('CDK: default DistributedTable provisions a DynamoDB table', () => {
|
|
|
50
57
|
const template = Template.fromStack(stack);
|
|
51
58
|
template.resourceCountIs('AWS::DynamoDB::Table', 1);
|
|
52
59
|
});
|
|
60
|
+
// ── Secure-by-default durability & encryption (prod) ────────────────────────
|
|
61
|
+
// Regression for the bug bash finding: prod DDB tables shipped with
|
|
62
|
+
// DeletionProtection off, PITR disabled, and SSE (KMS) unset.
|
|
63
|
+
test('CDK: prod DistributedTable enables PITR by default', () => {
|
|
64
|
+
const { stack, parent } = setup();
|
|
65
|
+
new DistributedTable(parent, 'users', {
|
|
66
|
+
schema: userSchema,
|
|
67
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
68
|
+
});
|
|
69
|
+
const template = Template.fromStack(stack);
|
|
70
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
71
|
+
PointInTimeRecoverySpecification: { PointInTimeRecoveryEnabled: true },
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
test('CDK: default PITR does not pin a recovery window (DynamoDB 35-day default)', () => {
|
|
75
|
+
const { stack, parent } = setup();
|
|
76
|
+
new DistributedTable(parent, 'users', {
|
|
77
|
+
schema: userSchema,
|
|
78
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
79
|
+
});
|
|
80
|
+
const template = Template.fromStack(stack);
|
|
81
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
82
|
+
PointInTimeRecoverySpecification: {
|
|
83
|
+
PointInTimeRecoveryEnabled: true,
|
|
84
|
+
RecoveryPeriodInDays: Match.absent(),
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
test('CDK: pointInTimeRecovery { retentionDays } enables PITR and pins the window', () => {
|
|
89
|
+
const { stack, parent } = setup();
|
|
90
|
+
new DistributedTable(parent, 'users', {
|
|
91
|
+
schema: userSchema,
|
|
92
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
93
|
+
pointInTimeRecovery: { retentionDays: 7 },
|
|
94
|
+
});
|
|
95
|
+
const template = Template.fromStack(stack);
|
|
96
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
97
|
+
PointInTimeRecoverySpecification: {
|
|
98
|
+
PointInTimeRecoveryEnabled: true,
|
|
99
|
+
RecoveryPeriodInDays: 7,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
test('CDK: an out-of-range retentionDays falls back to the default window (still enabled)', () => {
|
|
104
|
+
const { stack, parent } = setup();
|
|
105
|
+
new DistributedTable(parent, 'users', {
|
|
106
|
+
schema: userSchema,
|
|
107
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
108
|
+
pointInTimeRecovery: { retentionDays: 60 },
|
|
109
|
+
});
|
|
110
|
+
const template = Template.fromStack(stack);
|
|
111
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
112
|
+
PointInTimeRecoverySpecification: {
|
|
113
|
+
PointInTimeRecoveryEnabled: true,
|
|
114
|
+
RecoveryPeriodInDays: Match.absent(),
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
test('CDK: pointInTimeRecovery: false disables PITR', () => {
|
|
119
|
+
const { stack, parent } = setup();
|
|
120
|
+
new DistributedTable(parent, 'users', {
|
|
121
|
+
schema: userSchema,
|
|
122
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
123
|
+
pointInTimeRecovery: false,
|
|
124
|
+
});
|
|
125
|
+
const template = Template.fromStack(stack);
|
|
126
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
127
|
+
PointInTimeRecoverySpecification: Match.absent(),
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
test('CDK: prod DistributedTable enables DeletionProtection by default', () => {
|
|
131
|
+
const { stack, parent } = setup();
|
|
132
|
+
new DistributedTable(parent, 'users', {
|
|
133
|
+
schema: userSchema,
|
|
134
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
135
|
+
});
|
|
136
|
+
const template = Template.fromStack(stack);
|
|
137
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
138
|
+
DeletionProtectionEnabled: true,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
test('CDK: prod DistributedTable enables SSE (KMS-managed) by default', () => {
|
|
142
|
+
const { stack, parent } = setup();
|
|
143
|
+
new DistributedTable(parent, 'users', {
|
|
144
|
+
schema: userSchema,
|
|
145
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
146
|
+
});
|
|
147
|
+
const template = Template.fromStack(stack);
|
|
148
|
+
// AWS_MANAGED emits SSEEnabled:true with no SSEType (the aws/dynamodb key).
|
|
149
|
+
// Contrast with the AWS-owned default, which emits no SSESpecification at all,
|
|
150
|
+
// and customer-managed, which adds SSEType:'KMS' + a KMSMasterKeyId.
|
|
151
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
152
|
+
SSESpecification: { SSEEnabled: true, SSEType: Match.absent() },
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
test('CDK: prod DistributedTable table is RETAINed on stack delete by default', () => {
|
|
156
|
+
const { stack, parent } = setup();
|
|
157
|
+
new DistributedTable(parent, 'users', {
|
|
158
|
+
schema: userSchema,
|
|
159
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
160
|
+
});
|
|
161
|
+
const template = Template.fromStack(stack);
|
|
162
|
+
template.hasResource('AWS::DynamoDB::Table', {
|
|
163
|
+
DeletionPolicy: 'Retain',
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
// (Sandbox-default behavior — DESTROY, deletion protection off, PITR off — is
|
|
167
|
+
// covered by the "adopts sandbox defaults" / "PITR follows the stack defaults"
|
|
168
|
+
// tests above, which drive it through the stack `defaults` rather than the
|
|
169
|
+
// `sandboxMode` context.)
|
|
170
|
+
// ── Customer overrides win over the secure defaults ─────────────────────────
|
|
171
|
+
test('CDK: customer can opt OUT of PITR + protection in prod', () => {
|
|
172
|
+
const { stack, parent } = setup();
|
|
173
|
+
new DistributedTable(parent, 'users', {
|
|
174
|
+
schema: userSchema,
|
|
175
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
176
|
+
pointInTimeRecovery: false,
|
|
177
|
+
protection: 'disposable',
|
|
178
|
+
});
|
|
179
|
+
const template = Template.fromStack(stack);
|
|
180
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
181
|
+
PointInTimeRecoverySpecification: Match.absent(),
|
|
182
|
+
DeletionProtectionEnabled: false,
|
|
183
|
+
});
|
|
184
|
+
template.hasResource('AWS::DynamoDB::Table', { DeletionPolicy: 'Delete' });
|
|
185
|
+
});
|
|
186
|
+
test('CDK: customer can opt INTO durable/protected tables even under the sandbox preset', () => {
|
|
187
|
+
const { stack, parent } = setup(BlocksPresets.sandbox);
|
|
188
|
+
new DistributedTable(parent, 'users', {
|
|
189
|
+
schema: userSchema,
|
|
190
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
191
|
+
pointInTimeRecovery: true,
|
|
192
|
+
protection: 'locked',
|
|
193
|
+
});
|
|
194
|
+
const template = Template.fromStack(stack);
|
|
195
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
196
|
+
PointInTimeRecoverySpecification: { PointInTimeRecoveryEnabled: true },
|
|
197
|
+
DeletionProtectionEnabled: true,
|
|
198
|
+
});
|
|
199
|
+
template.hasResource('AWS::DynamoDB::Table', { DeletionPolicy: 'Retain' });
|
|
200
|
+
});
|
|
201
|
+
test("CDK: protection 'retained' orphans the table without locking deletes", () => {
|
|
202
|
+
const { stack, parent } = setup();
|
|
203
|
+
new DistributedTable(parent, 'users', {
|
|
204
|
+
schema: userSchema,
|
|
205
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
206
|
+
protection: 'retained',
|
|
207
|
+
});
|
|
208
|
+
const template = Template.fromStack(stack);
|
|
209
|
+
// RETAIN on stack delete, but deletion protection OFF (a direct delete works).
|
|
210
|
+
template.hasResource('AWS::DynamoDB::Table', { DeletionPolicy: 'Retain' });
|
|
211
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
212
|
+
DeletionProtectionEnabled: false,
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
test('CDK: customer-managed encryption provisions a KMS key', () => {
|
|
216
|
+
const { stack, parent } = setup();
|
|
217
|
+
new DistributedTable(parent, 'users', {
|
|
218
|
+
schema: userSchema,
|
|
219
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
220
|
+
encryption: 'customer-managed',
|
|
221
|
+
});
|
|
222
|
+
const template = Template.fromStack(stack);
|
|
223
|
+
template.resourceCountIs('AWS::KMS::Key', 1);
|
|
224
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
225
|
+
SSESpecification: { SSEEnabled: true, SSEType: 'KMS' },
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
test('CDK: fromKmsKey encrypts with an existing key and provisions no new KMS key', () => {
|
|
229
|
+
const { stack, parent } = setup();
|
|
230
|
+
const keyArn = 'arn:aws:kms:us-east-1:111122223333:key/abcd-1234-ef56';
|
|
231
|
+
new DistributedTable(parent, 'orders', {
|
|
232
|
+
schema: userSchema,
|
|
233
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
234
|
+
encryption: DistributedTable.fromKmsKey(keyArn),
|
|
235
|
+
});
|
|
236
|
+
const template = Template.fromStack(stack);
|
|
237
|
+
// Bringing an existing key must NOT mint a new one (the whole point — a
|
|
238
|
+
// shared key across tables instead of one dedicated key each).
|
|
239
|
+
template.resourceCountIs('AWS::KMS::Key', 0);
|
|
240
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
241
|
+
SSESpecification: { SSEEnabled: true, SSEType: 'KMS', KMSMasterKeyId: keyArn },
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
test('CDK: two tables sharing one fromKmsKey ref provision zero KMS keys', () => {
|
|
245
|
+
const { stack, parent } = setup();
|
|
246
|
+
const sharedKey = DistributedTable.fromKmsKey('arn:aws:kms:us-east-1:111122223333:key/shared-1');
|
|
247
|
+
new DistributedTable(parent, 'orders', {
|
|
248
|
+
schema: userSchema,
|
|
249
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
250
|
+
encryption: sharedKey,
|
|
251
|
+
});
|
|
252
|
+
new DistributedTable(parent, 'events', {
|
|
253
|
+
schema: userSchema,
|
|
254
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
255
|
+
encryption: sharedKey,
|
|
256
|
+
});
|
|
257
|
+
const template = Template.fromStack(stack);
|
|
258
|
+
template.resourceCountIs('AWS::KMS::Key', 0);
|
|
259
|
+
template.resourceCountIs('AWS::DynamoDB::Table', 2);
|
|
260
|
+
});
|
|
261
|
+
test('CDK: fromExisting ignores durability props (customer owns the table)', () => {
|
|
262
|
+
const { stack, parent } = setup();
|
|
263
|
+
new DistributedTable(parent, 'users', {
|
|
264
|
+
schema: userSchema,
|
|
265
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
266
|
+
table: DistributedTable.fromExisting('preexisting-users-table'),
|
|
267
|
+
// These must be inert when wrapping an existing table.
|
|
268
|
+
pointInTimeRecovery: true,
|
|
269
|
+
protection: 'locked',
|
|
270
|
+
encryption: 'customer-managed',
|
|
271
|
+
});
|
|
272
|
+
const template = Template.fromStack(stack);
|
|
273
|
+
// No table is provisioned, and customer-managed encryption does NOT
|
|
274
|
+
// provision a CMK — proving the durability options are ignored.
|
|
275
|
+
template.resourceCountIs('AWS::DynamoDB::Table', 0);
|
|
276
|
+
template.resourceCountIs('AWS::KMS::Key', 0);
|
|
277
|
+
});
|
|
278
|
+
// ── Durability follows the stack `defaults` when no per-block override (#302) ──
|
|
279
|
+
test('CDK: table adopts sandbox defaults (DESTROY, deletion protection off)', () => {
|
|
280
|
+
const { stack, parent } = setup(BlocksPresets.sandbox);
|
|
281
|
+
new DistributedTable(parent, 'users', {
|
|
282
|
+
schema: userSchema,
|
|
283
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
284
|
+
});
|
|
285
|
+
const template = Template.fromStack(stack);
|
|
286
|
+
template.hasResource('AWS::DynamoDB::Table', { DeletionPolicy: 'Delete' });
|
|
287
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', { DeletionProtectionEnabled: false });
|
|
288
|
+
});
|
|
289
|
+
test('CDK: table adopts production defaults (RETAIN, deletion protection on)', () => {
|
|
290
|
+
const { stack, parent } = setup(BlocksPresets.production);
|
|
291
|
+
new DistributedTable(parent, 'users', {
|
|
292
|
+
schema: userSchema,
|
|
293
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
294
|
+
});
|
|
295
|
+
const template = Template.fromStack(stack);
|
|
296
|
+
template.hasResource('AWS::DynamoDB::Table', { DeletionPolicy: 'Retain' });
|
|
297
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', { DeletionProtectionEnabled: true });
|
|
298
|
+
});
|
|
299
|
+
test('CDK: PITR follows the stack defaults — off under the sandbox preset', () => {
|
|
300
|
+
const { stack, parent } = setup(BlocksPresets.sandbox);
|
|
301
|
+
new DistributedTable(parent, 'users', {
|
|
302
|
+
schema: userSchema,
|
|
303
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
304
|
+
});
|
|
305
|
+
const template = Template.fromStack(stack);
|
|
306
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
307
|
+
PointInTimeRecoverySpecification: Match.absent(),
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
test('CDK: options.pointInTimeRecovery overrides the stack defaults (on under sandbox)', () => {
|
|
311
|
+
const { stack, parent } = setup(BlocksPresets.sandbox);
|
|
312
|
+
new DistributedTable(parent, 'users', {
|
|
313
|
+
schema: userSchema,
|
|
314
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
315
|
+
pointInTimeRecovery: true,
|
|
316
|
+
});
|
|
317
|
+
const template = Template.fromStack(stack);
|
|
318
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
319
|
+
PointInTimeRecoverySpecification: { PointInTimeRecoveryEnabled: true },
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
test('CDK: a per-block protection option overrides the stack defaults', () => {
|
|
323
|
+
// Sandbox preset would give DESTROY + no protection; `protection: 'locked'`
|
|
324
|
+
// must win, proving the per-block override sits on top of the #302 defaults.
|
|
325
|
+
const { stack, parent } = setup(BlocksPresets.sandbox);
|
|
326
|
+
new DistributedTable(parent, 'users', {
|
|
327
|
+
schema: userSchema,
|
|
328
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
329
|
+
protection: 'locked',
|
|
330
|
+
});
|
|
331
|
+
const template = Template.fromStack(stack);
|
|
332
|
+
template.hasResource('AWS::DynamoDB::Table', { DeletionPolicy: 'Retain' });
|
|
333
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', { DeletionProtectionEnabled: true });
|
|
334
|
+
});
|
|
53
335
|
test('CDK: DistributedTable.fromExisting does NOT provision a table (regression)', () => {
|
|
54
336
|
const { stack, parent } = setup();
|
|
55
337
|
new DistributedTable(parent, 'users', {
|
|
@@ -91,3 +373,42 @@ test('CDK: calling a runtime data method throws an actionable error (not a crypt
|
|
|
91
373
|
assert.throws(() => table[method]('k'), /cannot be called during CDK synth/, `${method}() should throw the actionable synth-time error`);
|
|
92
374
|
}
|
|
93
375
|
});
|
|
376
|
+
// ── Synth-time warnings actually fire (not just the fallback values) ─────────
|
|
377
|
+
test('CDK: an unrecognized protection value warns at synth', () => {
|
|
378
|
+
const { stack, parent } = setup();
|
|
379
|
+
new DistributedTable(parent, 'users', {
|
|
380
|
+
schema: userSchema,
|
|
381
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
382
|
+
protection: 'retian', // intentional typo — exercise the synth guard
|
|
383
|
+
});
|
|
384
|
+
Annotations.fromStack(stack).hasWarning('*', Match.stringLikeRegexp('Unrecognized protection'));
|
|
385
|
+
});
|
|
386
|
+
test('CDK: an unrecognized encryption value warns at synth', () => {
|
|
387
|
+
const { stack, parent } = setup();
|
|
388
|
+
new DistributedTable(parent, 'users', {
|
|
389
|
+
schema: userSchema,
|
|
390
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
391
|
+
encryption: 'kms', // intentional typo — exercise the synth guard
|
|
392
|
+
});
|
|
393
|
+
Annotations.fromStack(stack).hasWarning('*', Match.stringLikeRegexp('Unrecognized encryption'));
|
|
394
|
+
});
|
|
395
|
+
test('CDK: an out-of-range retentionDays warns at synth', () => {
|
|
396
|
+
const { stack, parent } = setup();
|
|
397
|
+
new DistributedTable(parent, 'users', {
|
|
398
|
+
schema: userSchema,
|
|
399
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
400
|
+
pointInTimeRecovery: { retentionDays: 60 },
|
|
401
|
+
});
|
|
402
|
+
Annotations.fromStack(stack).hasWarning('*', Match.stringLikeRegexp('retentionDays must be an integer'));
|
|
403
|
+
});
|
|
404
|
+
test('CDK: durability options passed alongside fromExisting warn at synth', () => {
|
|
405
|
+
const { stack, parent } = setup();
|
|
406
|
+
new DistributedTable(parent, 'users', {
|
|
407
|
+
schema: userSchema,
|
|
408
|
+
key: { partitionKey: 'userId', sortKey: 'createdAt' },
|
|
409
|
+
table: DistributedTable.fromExisting('preexisting-users-table'),
|
|
410
|
+
protection: 'locked',
|
|
411
|
+
pointInTimeRecovery: { retentionDays: 14 },
|
|
412
|
+
});
|
|
413
|
+
Annotations.fromStack(stack).hasWarning('*', Match.stringLikeRegexp('wrapped via fromExisting'));
|
|
414
|
+
});
|
package/dist/index.mock.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Scope } from '@aws-blocks/core';
|
|
2
2
|
import type { ScopeParent } from '@aws-blocks/core';
|
|
3
3
|
export { DistributedTableErrors } from './errors.js';
|
|
4
|
-
export type { TableKeyConfig, DistributedTableOptions, ReadValidationMode, ExternalTableRef, TableKey, PartitionKeyCondition, SortKeyCondition, KeyCondition, QueryOptions, ScanOptions, PutOptions, DeleteOptions, } from './types.js';
|
|
5
|
-
import type { TableKeyConfig, DistributedTableOptions, ExternalTableRef, ScanOptions, PutOptions, DeleteOptions, TableKey } from './types.js';
|
|
4
|
+
export type { TableKeyConfig, DistributedTableOptions, ReadValidationMode, ExternalTableRef, ExternalKmsKeyRef, TableKey, PartitionKeyCondition, SortKeyCondition, KeyCondition, QueryOptions, ScanOptions, PutOptions, DeleteOptions, } from './types.js';
|
|
5
|
+
import type { TableKeyConfig, DistributedTableOptions, ExternalTableRef, ExternalKmsKeyRef, ScanOptions, PutOptions, DeleteOptions, TableKey } from './types.js';
|
|
6
6
|
/**
|
|
7
7
|
* Structured data storage backed by DynamoDB with secondary indexes and
|
|
8
8
|
* rich query capabilities.
|
|
@@ -99,6 +99,7 @@ export declare class DistributedTable<T, K extends TableKeyConfig<T> = TableKeyC
|
|
|
99
99
|
*/
|
|
100
100
|
deleteBatch(keys: TableKey<T, K>[]): Promise<void>;
|
|
101
101
|
static fromExisting(tableName: string): ExternalTableRef;
|
|
102
|
+
static fromKmsKey(keyArn: string): ExternalKmsKeyRef;
|
|
102
103
|
private checkFieldEquals;
|
|
103
104
|
private serializeKey;
|
|
104
105
|
private loadFromDisk;
|
package/dist/index.mock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mock.d.ts","sourceRoot":"","sources":["../src/index.mock.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAA0B,MAAM,kBAAkB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAMpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,YAAY,EACX,cAAc,EACd,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACR,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,aAAa,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EACX,cAAc,EACd,uBAAuB,EACvB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.mock.d.ts","sourceRoot":"","sources":["../src/index.mock.ts"],"names":[],"mappings":"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"}
|
package/dist/index.mock.js
CHANGED
|
@@ -276,6 +276,9 @@ export class DistributedTable extends Scope {
|
|
|
276
276
|
static fromExisting(tableName) {
|
|
277
277
|
return { __brand: 'ExternalTableRef', tableName };
|
|
278
278
|
}
|
|
279
|
+
static fromKmsKey(keyArn) {
|
|
280
|
+
return { __brand: 'ExternalKmsKeyRef', keyArn };
|
|
281
|
+
}
|
|
279
282
|
// ── Internal ────────────────────────────────────────────────────────────
|
|
280
283
|
checkFieldEquals(keyStr, fields) {
|
|
281
284
|
const entries = Object.entries(fields).filter(([, v]) => v !== undefined);
|
package/dist/types.d.ts
CHANGED
|
@@ -43,6 +43,82 @@ export interface DistributedTableOptions<T, K extends TableKeyConfig<T> = TableK
|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
ttl?: keyof T & string;
|
|
46
|
+
/**
|
|
47
|
+
* DynamoDB Point-in-Time Recovery (continuous backups) — restore the table
|
|
48
|
+
* to any second within a retention window, protecting against accidental
|
|
49
|
+
* writes/deletes and logical corruption.
|
|
50
|
+
*
|
|
51
|
+
* A single knob, since the recovery window only means anything when PITR is
|
|
52
|
+
* on:
|
|
53
|
+
* - `true` — enable PITR with the default 35-day window.
|
|
54
|
+
* - `false` — disable PITR.
|
|
55
|
+
* - `{ retentionDays: n }` — enable PITR and keep `n` days of continuous
|
|
56
|
+
* backups (**1–35**). A shorter window reduces backup-storage cost at the
|
|
57
|
+
* expense of how far back you can restore.
|
|
58
|
+
*
|
|
59
|
+
* When omitted, the stack-wide default applies (`defaults.pointInTimeRecovery`
|
|
60
|
+
* from `BlocksPresets` — on under `production`, off under `sandbox`). A
|
|
61
|
+
* per-block value always wins.
|
|
62
|
+
*
|
|
63
|
+
* Note: PITR bills for continuous-backup storage (per GB-month of table
|
|
64
|
+
* size), so it is not free on large tables.
|
|
65
|
+
*/
|
|
66
|
+
pointInTimeRecovery?: boolean | {
|
|
67
|
+
retentionDays: number;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* How hard the table is to destroy — a single knob spanning DynamoDB
|
|
71
|
+
* deletion protection and the CloudFormation removal policy, which together
|
|
72
|
+
* answer one question: "can this table be destroyed?"
|
|
73
|
+
*
|
|
74
|
+
* - `'disposable'`: `RemovalPolicy.DESTROY`, deletion protection **off**.
|
|
75
|
+
* Deleting the stack deletes the table. The **sandbox default** — keeps
|
|
76
|
+
* `sandbox:destroy` a one-command teardown.
|
|
77
|
+
* - `'retained'`: `RemovalPolicy.RETAIN`, deletion protection **off**.
|
|
78
|
+
* Deleting the stack orphans (keeps) the table, but a direct
|
|
79
|
+
* `DeleteTable`/console delete still works. Use when you want the data to
|
|
80
|
+
* survive stack teardown without blocking intentional deletes.
|
|
81
|
+
* - `'locked'`: `RemovalPolicy.RETAIN` **and** deletion protection **on**.
|
|
82
|
+
* The table survives stack deletion and DynamoDB refuses a direct delete
|
|
83
|
+
* until protection is turned off. The **production default**.
|
|
84
|
+
*
|
|
85
|
+
* When omitted, removal policy and deletion protection follow the stack-wide
|
|
86
|
+
* `defaults` (`BlocksPresets.production` ≈ `'locked'`, `BlocksPresets.sandbox`
|
|
87
|
+
* ≈ `'disposable'`). A per-block value always wins.
|
|
88
|
+
*
|
|
89
|
+
* Replaces the separate `deletionProtection` + `removalPolicy` booleans:
|
|
90
|
+
* those two knobs could encode the contradictory `deletionProtection: true`
|
|
91
|
+
* + `removalPolicy: 'destroy'` state, which wedges stack deletion (CFN
|
|
92
|
+
* issues `DeleteTable`, DynamoDB refuses it, the stack lands in
|
|
93
|
+
* `DELETE_FAILED`). A single enum makes that state unrepresentable.
|
|
94
|
+
*/
|
|
95
|
+
protection?: 'disposable' | 'retained' | 'locked';
|
|
96
|
+
/**
|
|
97
|
+
* Server-side encryption at rest.
|
|
98
|
+
*
|
|
99
|
+
* - `'aws-managed'` (default): SSE with the AWS-managed `aws/dynamodb` KMS
|
|
100
|
+
* key. Auditable via CloudTrail with no per-key monthly charge.
|
|
101
|
+
* - `'customer-managed'`: provisions a **dedicated** customer-managed KMS
|
|
102
|
+
* key (CMK) for this table, giving you full control over rotation and key
|
|
103
|
+
* policy. Incurs standard KMS key + request charges — and note this mints
|
|
104
|
+
* a **separate key per table**, so a dozen tables means a dozen keys.
|
|
105
|
+
* - a {@link ExternalKmsKeyRef} from {@link DistributedTable.fromKmsKey}:
|
|
106
|
+
* uses an **existing** CMK you already own, so several tables can share one
|
|
107
|
+
* key (and one monthly charge) instead of each provisioning its own.
|
|
108
|
+
*
|
|
109
|
+
* DynamoDB is always encrypted at rest; this only selects the key.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* // Share one key across several tables
|
|
114
|
+
* const key = DistributedTable.fromKmsKey(
|
|
115
|
+
* 'arn:aws:kms:us-east-1:111122223333:key/abcd-1234',
|
|
116
|
+
* );
|
|
117
|
+
* new DistributedTable(scope, 'orders', { schema, key: { partitionKey: 'id' }, encryption: key });
|
|
118
|
+
* new DistributedTable(scope, 'events', { schema, key: { partitionKey: 'id' }, encryption: key });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
encryption?: 'aws-managed' | 'customer-managed' | ExternalKmsKeyRef;
|
|
46
122
|
/**
|
|
47
123
|
* How reads (`get`, `getBatch`, `query`, `scan`) reconcile a stored item with
|
|
48
124
|
* the configured `schema`. Writes (`put`/`putBatch`) always validate; this
|
|
@@ -93,6 +169,16 @@ export interface ExternalTableRef {
|
|
|
93
169
|
readonly __brand: 'ExternalTableRef';
|
|
94
170
|
readonly tableName: string;
|
|
95
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* A reference to an existing customer-managed KMS key, produced by
|
|
174
|
+
* {@link DistributedTable.fromKmsKey}. Pass it as the `encryption` option to
|
|
175
|
+
* encrypt the table with a CMK you already own — letting several tables share
|
|
176
|
+
* one key instead of each provisioning its own dedicated key.
|
|
177
|
+
*/
|
|
178
|
+
export interface ExternalKmsKeyRef {
|
|
179
|
+
readonly __brand: 'ExternalKmsKeyRef';
|
|
180
|
+
readonly keyArn: string;
|
|
181
|
+
}
|
|
96
182
|
/**
|
|
97
183
|
* Picks exactly the key fields from T and makes them required.
|
|
98
184
|
* Non-key fields are excluded.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-blocks/bb-distributed-table",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/aws-devtools-labs/aws-blocks.git",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"test": "node --test --test-concurrency=1 dist/index.test.js dist/parity.test.js dist/index.cdk.test.js"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@aws-blocks/core": "^0.
|
|
43
|
-
"@aws-blocks/bb-logger": "^0.1.
|
|
42
|
+
"@aws-blocks/core": "^0.3.0",
|
|
43
|
+
"@aws-blocks/bb-logger": "^0.1.5",
|
|
44
44
|
"@aws-sdk/client-dynamodb": "^3.0.0",
|
|
45
45
|
"@aws-sdk/lib-dynamodb": "^3.0.0",
|
|
46
46
|
"@standard-schema/spec": "^1.0.0",
|
package/src/index.aws.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type {
|
|
|
23
23
|
DistributedTableOptions,
|
|
24
24
|
ReadValidationMode,
|
|
25
25
|
ExternalTableRef,
|
|
26
|
+
ExternalKmsKeyRef,
|
|
26
27
|
TableKey,
|
|
27
28
|
PartitionKeyCondition,
|
|
28
29
|
SortKeyCondition,
|
|
@@ -37,6 +38,7 @@ import type {
|
|
|
37
38
|
TableKeyConfig,
|
|
38
39
|
DistributedTableOptions,
|
|
39
40
|
ExternalTableRef,
|
|
41
|
+
ExternalKmsKeyRef,
|
|
40
42
|
ScanOptions,
|
|
41
43
|
PutOptions,
|
|
42
44
|
DeleteOptions,
|
|
@@ -280,6 +282,10 @@ export class DistributedTable<
|
|
|
280
282
|
return { __brand: 'ExternalTableRef' as const, tableName };
|
|
281
283
|
}
|
|
282
284
|
|
|
285
|
+
static fromKmsKey(keyArn: string): ExternalKmsKeyRef {
|
|
286
|
+
return { __brand: 'ExternalKmsKeyRef' as const, keyArn };
|
|
287
|
+
}
|
|
288
|
+
|
|
283
289
|
// ── Internal ────────────────────────────────────────────────────────────
|
|
284
290
|
|
|
285
291
|
private async validateItem(item: T): Promise<void> {
|