@aws-blocks/bb-distributed-data 0.1.6 → 0.1.8
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/dist/index.cdk.d.ts.map +1 -1
- package/dist/index.cdk.js +17 -8
- package/dist/index.cdk.test.js +71 -11
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/dist/index.cdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cdk.d.ts","sourceRoot":"","sources":["../src/index.cdk.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"index.cdk.d.ts","sourceRoot":"","sources":["../src/index.cdk.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAA0E,MAAM,sBAAsB,CAAC;AACrH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AASpD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAG7D,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,0BAA0B;IAwGhF;;;;;OAKG;IACH,SAAS,IAAI,KAAK;CAGnB;AAaD,OAAO,EAAE,GAAG,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.cdk.js
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* Provisions Aurora DSQL cluster via CloudFormation.
|
|
6
6
|
* Optionally runs migrations via a CustomResource Lambda.
|
|
7
7
|
*/
|
|
8
|
-
import { Scope, DEFAULT_NODE_RUNTIME, synthGuard, blocksNodejsBundling } from '@aws-blocks/core/cdk';
|
|
8
|
+
import { Scope, DEFAULT_NODE_RUNTIME, synthGuard, blocksNodejsBundling, registerConfig } from '@aws-blocks/core/cdk';
|
|
9
9
|
import * as cdk from 'aws-cdk-lib';
|
|
10
10
|
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
11
11
|
import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
12
|
+
import { LogGroup } from 'aws-cdk-lib/aws-logs';
|
|
12
13
|
import * as cr from 'aws-cdk-lib/custom-resources';
|
|
13
14
|
import { createHash } from 'node:crypto';
|
|
14
15
|
import { readdirSync, readFileSync } from 'node:fs';
|
|
@@ -39,17 +40,19 @@ export class DistributedDatabase extends Scope {
|
|
|
39
40
|
});
|
|
40
41
|
cluster.applyRemovalPolicy(removalPolicy);
|
|
41
42
|
const endpoint = cluster.getAtt('Endpoint').toString();
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
this
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
// Config for runtime — flows through S3 config (loaded into process.env at
|
|
44
|
+
// cold start) like every other block, instead of a direct env var.
|
|
45
|
+
registerConfig(this, `BLOCKS_${envName}_ENDPOINT`, endpoint);
|
|
46
|
+
registerConfig(this, `BLOCKS_${envName}_REGION`, region);
|
|
47
|
+
// IAM grant — the shared execution role gets DML-only access via custom DB
|
|
48
|
+
// role (least privilege).
|
|
49
|
+
this.executionRole.addToPrincipalPolicy(new iam.PolicyStatement({
|
|
47
50
|
actions: ['dsql:DbConnect'],
|
|
48
51
|
resources: [`arn:aws:dsql:${region}:${stack.account}:cluster/${cluster.ref}`],
|
|
49
52
|
}));
|
|
50
53
|
new cdk.CfnOutput(stack, `${this.fullId}DsqlEndpoint`, { value: endpoint });
|
|
51
|
-
// The
|
|
52
|
-
const appRoleArn = this.
|
|
54
|
+
// The shared execution role ARN is mapped to the custom DB role.
|
|
55
|
+
const appRoleArn = this.executionRole.roleArn;
|
|
53
56
|
// Resolve migrations path if provided
|
|
54
57
|
const resolvedMigrationsPath = options?.migrationsPath ? resolve(options.migrationsPath) : undefined;
|
|
55
58
|
const migrationsHash = resolvedMigrationsPath ? hashMigrationsDir(resolvedMigrationsPath) : 'no-migrations';
|
|
@@ -62,6 +65,12 @@ export class DistributedDatabase extends Scope {
|
|
|
62
65
|
handler: 'handler',
|
|
63
66
|
runtime: DEFAULT_NODE_RUNTIME,
|
|
64
67
|
timeout: cdk.Duration.minutes(MIGRATION_LAMBDA_TIMEOUT_MINUTES),
|
|
68
|
+
// Own the migration Lambda's log group so its retention follows the
|
|
69
|
+
// stack-wide default instead of AWS's infinite retention.
|
|
70
|
+
logGroup: new LogGroup(stack, `${this.fullId}DsqlMigrationLogs`, {
|
|
71
|
+
retention: this.defaults.logRetention,
|
|
72
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
73
|
+
}),
|
|
65
74
|
environment: {
|
|
66
75
|
DSQL_ENDPOINT: endpoint,
|
|
67
76
|
DSQL_REGION: region,
|
package/dist/index.cdk.test.js
CHANGED
|
@@ -18,12 +18,17 @@ const MIGRATIONS_DIR = '.bb-data/__test_cdk_migrations__';
|
|
|
18
18
|
function synth(build) {
|
|
19
19
|
const app = new cdk.App();
|
|
20
20
|
const stack = new cdk.Stack(app, 'TestStack');
|
|
21
|
+
const executionRole = new cdk.aws_iam.Role(stack, 'BlocksRole', {
|
|
22
|
+
assumedBy: new cdk.aws_iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
23
|
+
});
|
|
21
24
|
const handler = new lambda.Function(stack, 'Handler', {
|
|
22
25
|
runtime: DEFAULT_NODE_RUNTIME,
|
|
23
26
|
handler: 'index.handler',
|
|
24
27
|
code: lambda.Code.fromInline('exports.handler = async () => {};'),
|
|
28
|
+
role: executionRole,
|
|
25
29
|
});
|
|
26
30
|
stack.handler = handler;
|
|
31
|
+
stack.executionRole = executionRole;
|
|
27
32
|
globalThis.CURRENT_BLOCKS_STACK = stack;
|
|
28
33
|
try {
|
|
29
34
|
build(stack);
|
|
@@ -59,13 +64,18 @@ test('CDK: per-block removalPolicy is independent of deletion protection', () =>
|
|
|
59
64
|
// RETAINed on stack delete but not deletion-protected.
|
|
60
65
|
const app = new cdk.App();
|
|
61
66
|
const stack = new cdk.Stack(app, 'IndepStack');
|
|
67
|
+
const executionRole = new cdk.aws_iam.Role(stack, 'BlocksRole', {
|
|
68
|
+
assumedBy: new cdk.aws_iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
69
|
+
});
|
|
62
70
|
const handler = new lambda.Function(stack, 'Handler', {
|
|
63
71
|
runtime: DEFAULT_NODE_RUNTIME,
|
|
64
72
|
handler: 'index.handler',
|
|
65
73
|
code: lambda.Code.fromInline('exports.handler = async () => {};'),
|
|
74
|
+
role: executionRole,
|
|
66
75
|
});
|
|
67
76
|
stack.handler = handler;
|
|
68
77
|
stack.defaults = BlocksPresets.sandbox;
|
|
78
|
+
stack.executionRole = executionRole;
|
|
69
79
|
globalThis.CURRENT_BLOCKS_STACK = stack;
|
|
70
80
|
try {
|
|
71
81
|
new DistributedDatabase(scope(stack), 'mydsql', { removalPolicy: 'retain' });
|
|
@@ -82,15 +92,20 @@ test('CDK: per-block removalPolicy is independent of deletion protection', () =>
|
|
|
82
92
|
test('CDK: sandbox defaults disable deletion protection', () => {
|
|
83
93
|
const app = new cdk.App();
|
|
84
94
|
const stack = new cdk.Stack(app, 'SandboxStack');
|
|
95
|
+
const executionRole = new cdk.aws_iam.Role(stack, 'BlocksRole', {
|
|
96
|
+
assumedBy: new cdk.aws_iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
97
|
+
});
|
|
85
98
|
const handler = new lambda.Function(stack, 'Handler', {
|
|
86
99
|
runtime: DEFAULT_NODE_RUNTIME,
|
|
87
100
|
handler: 'index.handler',
|
|
88
101
|
code: lambda.Code.fromInline('exports.handler = async () => {};'),
|
|
102
|
+
role: executionRole,
|
|
89
103
|
});
|
|
90
104
|
stack.handler = handler;
|
|
91
105
|
// The cluster's removal/protection follows the stack-wide defaults (resolved
|
|
92
106
|
// via the globalThis fallback here), not the sandboxMode context.
|
|
93
107
|
stack.defaults = BlocksPresets.sandbox;
|
|
108
|
+
stack.executionRole = executionRole;
|
|
94
109
|
globalThis.CURRENT_BLOCKS_STACK = stack;
|
|
95
110
|
try {
|
|
96
111
|
new DistributedDatabase(scope(stack), 'mydsql');
|
|
@@ -120,18 +135,36 @@ test('CDK: handler gets dsql:DbConnect policy (least privilege)', () => {
|
|
|
120
135
|
},
|
|
121
136
|
});
|
|
122
137
|
});
|
|
123
|
-
// ---
|
|
124
|
-
test('CDK:
|
|
125
|
-
const
|
|
126
|
-
|
|
138
|
+
// --- Runtime config (endpoint + region) ---
|
|
139
|
+
test('CDK: registers ENDPOINT and REGION via the config registry (not handler env vars)', () => {
|
|
140
|
+
const app = new cdk.App();
|
|
141
|
+
const stack = new cdk.Stack(app, 'TestStack');
|
|
142
|
+
const executionRole = new cdk.aws_iam.Role(stack, 'BlocksRole', {
|
|
143
|
+
assumedBy: new cdk.aws_iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
127
144
|
});
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
const handler = new lambda.Function(stack, 'Handler', {
|
|
146
|
+
runtime: DEFAULT_NODE_RUNTIME,
|
|
147
|
+
handler: 'index.handler',
|
|
148
|
+
code: lambda.Code.fromInline('exports.handler = async () => {};'),
|
|
149
|
+
role: executionRole,
|
|
150
|
+
});
|
|
151
|
+
stack.handler = handler;
|
|
152
|
+
stack.executionRole = executionRole;
|
|
153
|
+
globalThis.CURRENT_BLOCKS_STACK = stack;
|
|
154
|
+
try {
|
|
155
|
+
new DistributedDatabase(scope(stack), 'mydsql');
|
|
156
|
+
// Endpoint + region now flow through the config registry (loaded into
|
|
157
|
+
// process.env at cold start) like every other block — not a direct env var
|
|
158
|
+
// on the handler.
|
|
159
|
+
const registry = stack[Symbol.for('BLOCKS_CONFIG_REGISTRY')];
|
|
160
|
+
assert.ok(registry, 'config registry exists on the stack');
|
|
161
|
+
const keys = [...registry.entries.keys()];
|
|
162
|
+
assert.ok(keys.some(k => k.includes('ENDPOINT')), `Expected an ENDPOINT config key, got: ${keys}`);
|
|
163
|
+
assert.ok(keys.some(k => k.includes('REGION')), `Expected a REGION config key, got: ${keys}`);
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
delete globalThis.CURRENT_BLOCKS_STACK;
|
|
167
|
+
}
|
|
135
168
|
});
|
|
136
169
|
// --- CfnOutput ---
|
|
137
170
|
test('CDK: stack has endpoint output', () => {
|
|
@@ -156,6 +189,33 @@ test('CDK: migration/provisioning resources always created', () => {
|
|
|
156
189
|
const hasDsqlGrant = policyValues.some((p) => JSON.stringify(p).includes('dsql:DbConnectAdmin'));
|
|
157
190
|
assert.ok(hasDsqlGrant, 'Migration Lambda should have dsql:DbConnectAdmin');
|
|
158
191
|
});
|
|
192
|
+
test('CDK: DSQL migration Lambda log group adopts defaults.logRetention', () => {
|
|
193
|
+
const app = new cdk.App();
|
|
194
|
+
const stack = new cdk.Stack(app, 'DsqlMigrationRetentionStack');
|
|
195
|
+
const executionRole = new cdk.aws_iam.Role(stack, 'BlocksRole', {
|
|
196
|
+
assumedBy: new cdk.aws_iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
197
|
+
});
|
|
198
|
+
const handler = new lambda.Function(stack, 'Handler', {
|
|
199
|
+
runtime: DEFAULT_NODE_RUNTIME,
|
|
200
|
+
handler: 'index.handler',
|
|
201
|
+
code: lambda.Code.fromInline('exports.handler = async () => {};'),
|
|
202
|
+
role: executionRole,
|
|
203
|
+
});
|
|
204
|
+
stack.handler = handler;
|
|
205
|
+
stack.executionRole = executionRole;
|
|
206
|
+
stack.defaults = BlocksPresets.sandbox;
|
|
207
|
+
globalThis.CURRENT_BLOCKS_STACK = stack;
|
|
208
|
+
try {
|
|
209
|
+
new DistributedDatabase(scope(stack), 'mydsql');
|
|
210
|
+
const template = Template.fromStack(stack);
|
|
211
|
+
// The always-created migration Lambda now owns an explicit log group whose
|
|
212
|
+
// retention follows the stack-wide default (sandbox → one week).
|
|
213
|
+
template.hasResourceProperties('AWS::Logs::LogGroup', { RetentionInDays: 7 });
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
delete globalThis.CURRENT_BLOCKS_STACK;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
159
219
|
test('CDK: migration resources created when migrationsPath is provided', () => {
|
|
160
220
|
rmSync(MIGRATIONS_DIR, { recursive: true, force: true });
|
|
161
221
|
mkdirSync(MIGRATIONS_DIR, { recursive: true });
|
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-data",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/aws-devtools-labs/aws-blocks.git",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"test": "node --test 'dist/**/*.test.js'"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@aws-blocks/core": "^0.
|
|
40
|
+
"@aws-blocks/core": "^0.4.0",
|
|
41
41
|
"@aws-blocks/data-common": "^0.1.4",
|
|
42
|
-
"@aws-blocks/bb-logger": "^0.1.
|
|
42
|
+
"@aws-blocks/bb-logger": "^0.1.6",
|
|
43
43
|
"@aws-sdk/dsql-signer": "^3.700.0",
|
|
44
44
|
"@electric-sql/pglite": "^0.2.0",
|
|
45
45
|
"pg": "^8.13.0"
|