@aws-blocks/core 0.3.0 → 0.5.0

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.
Files changed (147) hide show
  1. package/README.md +25 -0
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/api.js +32 -0
  4. package/dist/api.test.js +22 -0
  5. package/dist/bb-utils.d.ts +1 -0
  6. package/dist/bb-utils.d.ts.map +1 -1
  7. package/dist/bb-utils.js +3 -0
  8. package/dist/cdk/apigateway-account.d.ts +33 -0
  9. package/dist/cdk/apigateway-account.d.ts.map +1 -0
  10. package/dist/cdk/apigateway-account.js +60 -0
  11. package/dist/cdk/blocks-backend.d.ts +11 -0
  12. package/dist/cdk/blocks-backend.d.ts.map +1 -1
  13. package/dist/cdk/blocks-backend.js +72 -13
  14. package/dist/cdk/blocks-backend.test.js +88 -1
  15. package/dist/cdk/blocks-defaults.d.ts +76 -1
  16. package/dist/cdk/blocks-defaults.d.ts.map +1 -1
  17. package/dist/cdk/blocks-defaults.js +17 -1
  18. package/dist/cdk/blocks-defaults.test.js +17 -0
  19. package/dist/cdk/blocks-stack.test.js +44 -3
  20. package/dist/cdk/compute/compute-registry.d.ts +19 -0
  21. package/dist/cdk/compute/compute-registry.d.ts.map +1 -0
  22. package/dist/cdk/compute/compute-registry.js +38 -0
  23. package/dist/cdk/compute/compute.d.ts +82 -2
  24. package/dist/cdk/compute/compute.d.ts.map +1 -1
  25. package/dist/cdk/compute/compute.js +64 -2
  26. package/dist/cdk/compute/default-compute-factory.d.ts +1 -0
  27. package/dist/cdk/compute/default-compute-factory.d.ts.map +1 -1
  28. package/dist/cdk/config-registry.d.ts +34 -4
  29. package/dist/cdk/config-registry.d.ts.map +1 -1
  30. package/dist/cdk/config-registry.js +83 -25
  31. package/dist/cdk/config-registry.test.d.ts +2 -0
  32. package/dist/cdk/config-registry.test.d.ts.map +1 -0
  33. package/dist/cdk/config-registry.test.js +127 -0
  34. package/dist/cdk/dashboard-registry.d.ts +41 -0
  35. package/dist/cdk/dashboard-registry.d.ts.map +1 -0
  36. package/dist/cdk/dashboard-registry.js +61 -0
  37. package/dist/cdk/index.d.ts +90 -6
  38. package/dist/cdk/index.d.ts.map +1 -1
  39. package/dist/cdk/index.js +135 -13
  40. package/dist/cdk/internal.d.ts +3 -1
  41. package/dist/cdk/internal.d.ts.map +1 -1
  42. package/dist/cdk/internal.js +4 -1
  43. package/dist/cdk/tracer-registry.d.ts +31 -0
  44. package/dist/cdk/tracer-registry.d.ts.map +1 -0
  45. package/dist/cdk/tracer-registry.js +49 -0
  46. package/dist/cdk/vpc-requirements-registry.d.ts +33 -0
  47. package/dist/cdk/vpc-requirements-registry.d.ts.map +1 -0
  48. package/dist/cdk/vpc-requirements-registry.js +46 -0
  49. package/dist/cdk/vpc-types.d.ts +151 -0
  50. package/dist/cdk/vpc-types.d.ts.map +1 -0
  51. package/dist/cdk/vpc-types.js +3 -0
  52. package/dist/cdk/vpc.d.ts +59 -0
  53. package/dist/cdk/vpc.d.ts.map +1 -0
  54. package/dist/cdk/vpc.js +298 -0
  55. package/dist/cdk/vpc.test.d.ts +2 -0
  56. package/dist/cdk/vpc.test.d.ts.map +1 -0
  57. package/dist/cdk/vpc.test.js +285 -0
  58. package/dist/client/index.d.ts +1 -1
  59. package/dist/client/index.d.ts.map +1 -1
  60. package/dist/client/index.js +1 -1
  61. package/dist/common/config.d.ts +34 -0
  62. package/dist/common/config.d.ts.map +1 -1
  63. package/dist/common/config.js +45 -3
  64. package/dist/common/config.test.js +19 -0
  65. package/dist/common/index.d.ts +8 -0
  66. package/dist/common/index.d.ts.map +1 -1
  67. package/dist/errors.d.ts +21 -0
  68. package/dist/errors.d.ts.map +1 -1
  69. package/dist/errors.js +25 -0
  70. package/dist/hosting.d.ts +9 -0
  71. package/dist/hosting.d.ts.map +1 -1
  72. package/dist/hosting.js +12 -1
  73. package/dist/hosting.test.js +63 -1
  74. package/dist/index.cdk.d.ts +3 -2
  75. package/dist/index.cdk.d.ts.map +1 -1
  76. package/dist/index.cdk.js +2 -2
  77. package/dist/index.d.ts +1 -1
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +1 -1
  80. package/dist/lambda-handler.d.ts +17 -0
  81. package/dist/lambda-handler.d.ts.map +1 -1
  82. package/dist/lambda-handler.js +61 -5
  83. package/dist/lambda-handler.test.js +191 -2
  84. package/dist/raw-route.d.ts +15 -1
  85. package/dist/raw-route.d.ts.map +1 -1
  86. package/dist/raw-route.js +96 -12
  87. package/dist/raw-route.test.js +332 -1
  88. package/dist/scripts/dev-server.d.ts.map +1 -1
  89. package/dist/scripts/dev-server.js +11 -0
  90. package/dist/scripts/extract-ts-types.d.ts.map +1 -1
  91. package/dist/scripts/extract-ts-types.js +107 -23
  92. package/dist/scripts/extract-ts-types.test.js +225 -26
  93. package/dist/scripts/generate-spec.d.ts.map +1 -1
  94. package/dist/scripts/generate-spec.js +14 -5
  95. package/dist/scripts/generate-spec.test.js +93 -0
  96. package/dist/scripts/sandbox-empty-buckets.test.d.ts +2 -0
  97. package/dist/scripts/sandbox-empty-buckets.test.d.ts.map +1 -0
  98. package/dist/scripts/sandbox-empty-buckets.test.js +171 -0
  99. package/dist/scripts/sandbox.d.ts +54 -0
  100. package/dist/scripts/sandbox.d.ts.map +1 -1
  101. package/dist/scripts/sandbox.js +163 -25
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/package.json +10 -1
  105. package/src/api.test.ts +25 -0
  106. package/src/api.ts +39 -0
  107. package/src/bb-utils.ts +3 -0
  108. package/src/cdk/apigateway-account.ts +66 -0
  109. package/src/cdk/blocks-backend.test.ts +168 -60
  110. package/src/cdk/blocks-backend.ts +299 -227
  111. package/src/cdk/blocks-defaults.test.ts +21 -0
  112. package/src/cdk/blocks-defaults.ts +79 -1
  113. package/src/cdk/blocks-stack.test.ts +57 -13
  114. package/src/cdk/compute/compute-registry.ts +45 -0
  115. package/src/cdk/compute/compute.ts +114 -2
  116. package/src/cdk/compute/default-compute-factory.ts +1 -0
  117. package/src/cdk/config-registry.test.ts +149 -0
  118. package/src/cdk/config-registry.ts +92 -34
  119. package/src/cdk/dashboard-registry.ts +68 -0
  120. package/src/cdk/index.ts +427 -256
  121. package/src/cdk/internal.ts +6 -2
  122. package/src/cdk/tracer-registry.ts +54 -0
  123. package/src/cdk/vpc-requirements-registry.ts +63 -0
  124. package/src/cdk/vpc-types.ts +158 -0
  125. package/src/cdk/vpc.test.ts +348 -0
  126. package/src/cdk/vpc.ts +336 -0
  127. package/src/client/index.ts +1 -1
  128. package/src/common/config.test.ts +21 -0
  129. package/src/common/config.ts +47 -3
  130. package/src/common/index.ts +8 -0
  131. package/src/errors.ts +26 -0
  132. package/src/hosting.test.ts +87 -1
  133. package/src/hosting.ts +24 -1
  134. package/src/index.cdk.ts +11 -1
  135. package/src/index.ts +1 -1
  136. package/src/lambda-handler.test.ts +220 -2
  137. package/src/lambda-handler.ts +65 -4
  138. package/src/raw-route.test.ts +427 -1
  139. package/src/raw-route.ts +125 -12
  140. package/src/scripts/dev-server.ts +12 -1
  141. package/src/scripts/extract-ts-types.test.ts +228 -26
  142. package/src/scripts/extract-ts-types.ts +104 -20
  143. package/src/scripts/generate-spec.test.ts +101 -0
  144. package/src/scripts/generate-spec.ts +15 -5
  145. package/src/scripts/sandbox-empty-buckets.test.ts +191 -0
  146. package/src/scripts/sandbox.ts +185 -24
  147. package/src/version.ts +1 -1
@@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url';
8
8
  import * as cdk from 'aws-cdk-lib';
9
9
  import { Match, Template } from 'aws-cdk-lib/assertions';
10
10
  import * as apigateway from 'aws-cdk-lib/aws-apigateway';
11
+ import type { IWidget } from 'aws-cdk-lib/aws-cloudwatch';
11
12
  import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
12
13
  import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs';
13
14
  import type { Construct } from 'constructs';
@@ -18,6 +19,7 @@ import { BlocksPresets } from './blocks-defaults.js';
18
19
  import { Compute } from './compute/compute.js';
19
20
  import type { DefaultComputeFactory } from './compute/default-compute-factory.js';
20
21
  import { Scope } from './index.js';
22
+ import { getVpcContext } from './vpc.js';
21
23
 
22
24
  // A real app gets its default compute from @aws-blocks/bb-lambda-compute (via
23
25
  // @aws-blocks/blocks), which core's own tests can't depend on. Use an
@@ -30,16 +32,33 @@ class StubLambdaCompute extends Compute {
30
32
  readonly fn: lambda.NodejsFunction;
31
33
  readonly apiGateway: apigateway.RestApi;
32
34
  readonly apiUrl: string;
35
+ readonly logGroup: cdk.aws_logs.LogGroup;
33
36
 
34
37
  constructor(scope: ScopeParent, id: string) {
35
38
  super(id, { parent: scope });
39
+ this.logGroup = new cdk.aws_logs.LogGroup(this, 'HandlerLogGroup', {
40
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
41
+ });
42
+ // Discover the shared VPC context from the owning stack/backend, mirroring
43
+ // LambdaCompute — so the core-side VPC placement plumbing (initializeVpc →
44
+ // getVpcContext) is exercised by these tests without depending on
45
+ // @aws-blocks/bb-lambda-compute.
46
+ const vpcContext = getVpcContext(this);
36
47
  this.fn = new lambda.NodejsFunction(this, 'Handler', {
37
48
  entry: this.backendHandlerPath,
38
49
  runtime: cdk.aws_lambda.Runtime.NODEJS_22_X,
39
50
  handler: 'handler',
40
51
  role: this.executionRole,
52
+ logGroup: this.logGroup,
41
53
  environment: { BLOCKS_STACK_NAME: this.backendStackName },
42
54
  bundling: { minify: true, esbuildArgs: { '--conditions': 'aws-runtime' } },
55
+ ...(vpcContext
56
+ ? {
57
+ vpc: vpcContext.vpc,
58
+ vpcSubnets: vpcContext.computeSubnets,
59
+ securityGroups: [vpcContext.computeSecurityGroup],
60
+ }
61
+ : {}),
43
62
  });
44
63
  this.apiGateway = new apigateway.RestApi(this, 'API', { restApiName: 'Blocks API' });
45
64
  this.apiGateway.root.addProxy({
@@ -52,6 +71,17 @@ class StubLambdaCompute extends Compute {
52
71
  setEnv(key: string, value: string): void {
53
72
  this.fn.addEnvironment(key, value);
54
73
  }
74
+
75
+ protected applyTracing(): void {}
76
+ protected healthWidgets(_region: string): IWidget[][] {
77
+ return [];
78
+ }
79
+ protected loggingWidgets(_region: string): IWidget[][] {
80
+ return [];
81
+ }
82
+ protected tracingWidgets(_region: string): IWidget[][] {
83
+ return [];
84
+ }
55
85
  }
56
86
 
57
87
  const stubComputeFactory: DefaultComputeFactory = (root) => new StubLambdaCompute(root as never, 'DefaultCompute');
@@ -72,7 +102,12 @@ const importMetaHandlerPath = join(__dirname, '__fixtures__', 'import-meta-handl
72
102
  // Wraps BlocksBackend.create, injecting the stub default-compute factory the way
73
103
  // @aws-blocks/blocks injects LambdaCompute — so tests don't repeat it 15 times.
74
104
  const makeBackend = (scope: Construct, id: string, backendCDKPath: string) =>
75
- BlocksBackend.create(scope, id, { backendHandlerPath: handlerPath, backendCDKPath, defaults: BlocksPresets.production, defaultComputeFactory: stubComputeFactory });
105
+ BlocksBackend.create(scope, id, {
106
+ backendHandlerPath: handlerPath,
107
+ backendCDKPath,
108
+ defaults: BlocksPresets.production,
109
+ defaultComputeFactory: stubComputeFactory,
110
+ });
76
111
 
77
112
  describe('ESM cache-busting (multi-stage)', () => {
78
113
  test('BlocksBackend.create() with same backendCDKPath but different IDs produces constructs in each', async () => {
@@ -165,12 +200,31 @@ describe('shared execution role', () => {
165
200
  'BlocksRole should attach AWSLambdaBasicExecutionRole',
166
201
  );
167
202
 
203
+ // Core is BB-agnostic: with no Building Block that runs AS the shared role, the trust policy
204
+ // must NOT allow any compute principal beyond Lambda (e.g. bedrock-agentcore is added by the
205
+ // Agent BB's own construct, not here — see packages/bb-agent).
206
+ assert.ok(
207
+ !JSON.stringify(blocksRole.Properties.AssumeRolePolicyDocument).includes('bedrock-agentcore'),
208
+ 'core must not trust bedrock-agentcore by default (no agent → no AgentCore trust)',
209
+ );
210
+
168
211
  // The Blocks handler references the shared role, not an auto-generated one.
169
212
  template.hasResourceProperties('AWS::Lambda::Function', {
170
213
  Role: { 'Fn::GetAtt': [blocksRoleId, 'Arn'] },
171
214
  });
172
215
  });
173
216
 
217
+ test('exposes backendModulePath (props.backendCDKPath) for co-bundling BBs', async () => {
218
+ const app = new cdk.App();
219
+ const parent = new cdk.Stack(app, 'BackendPathStack');
220
+
221
+ const backend = await makeBackend(parent, 'Blocks', sideEffectBackendPath);
222
+
223
+ // Building Blocks that co-bundle the app backend at synth time (e.g. the Agent BB's AgentCore
224
+ // Runtime) discover it via globalThis.CURRENT_BLOCKS_STACK.backendModulePath.
225
+ assert.strictEqual(backend.backendModulePath, sideEffectBackendPath);
226
+ });
227
+
174
228
  test('a nested block resolves executionRole via the construct-tree walk', async () => {
175
229
  const app = new cdk.App();
176
230
  const parent = new cdk.Stack(app, 'RoleResolveStack');
@@ -206,25 +260,25 @@ describe('shared execution role', () => {
206
260
  });
207
261
 
208
262
  describe('CJS bundle: import.meta.url in the handler is shimmed (no Lambda-load crash)', () => {
209
- test('a handler that uses import.meta.url bundles successfully instead of throwing at load', async () => {
210
- // The handler is bundled to CJS, where `import.meta` is empty. Left unshimmed,
211
- // `fileURLToPath(import.meta.url)` compiles to `fileURLToPath(undefined)` and
212
- // throws at Lambda load (esbuild only warns, so the broken bundle would deploy).
213
- // blocksNodejsBundling shims import.meta.* to CommonJS equivalents, so bundling
214
- // (which runs synchronously during construction) succeeds. The runtime behaviour
215
- // of the emitted shim is verified directly in bundling.test.ts.
216
- const app = new cdk.App();
217
- const stack = new cdk.Stack(app, 'ImportMetaStack');
218
-
219
- await assert.doesNotReject(() =>
220
- BlocksBackend.create(stack, 'blocks', {
221
- backendHandlerPath: importMetaHandlerPath,
222
- backendCDKPath: sideEffectBackendPath,
223
- defaults: BlocksPresets.production,
224
- defaultComputeFactory: stubComputeFactory,
225
- }),
226
- );
227
- });
263
+ test('a handler that uses import.meta.url bundles successfully instead of throwing at load', async () => {
264
+ // The handler is bundled to CJS, where `import.meta` is empty. Left unshimmed,
265
+ // `fileURLToPath(import.meta.url)` compiles to `fileURLToPath(undefined)` and
266
+ // throws at Lambda load (esbuild only warns, so the broken bundle would deploy).
267
+ // blocksNodejsBundling shims import.meta.* to CommonJS equivalents, so bundling
268
+ // (which runs synchronously during construction) succeeds. The runtime behaviour
269
+ // of the emitted shim is verified directly in bundling.test.ts.
270
+ const app = new cdk.App();
271
+ const stack = new cdk.Stack(app, 'ImportMetaStack');
272
+
273
+ await assert.doesNotReject(() =>
274
+ BlocksBackend.create(stack, 'blocks', {
275
+ backendHandlerPath: importMetaHandlerPath,
276
+ backendCDKPath: sideEffectBackendPath,
277
+ defaults: BlocksPresets.production,
278
+ defaultComputeFactory: stubComputeFactory,
279
+ }),
280
+ );
281
+ });
228
282
  });
229
283
 
230
284
  describe('factory function support', () => {
@@ -324,44 +378,98 @@ describe('fullId is token-free (construct IDs / env-var keys)', () => {
324
378
  });
325
379
 
326
380
  describe('infrastructure defaults (backend-anchored)', () => {
327
- test('each backend exposes its own defaults', async () => {
328
- const app = new cdk.App();
329
- const stack = new cdk.Stack(app, 'TwoBackendsStack');
330
-
331
- const a = await BlocksBackend.create(stack, 'A', {
332
- backendHandlerPath: handlerPath,
333
- backendCDKPath: sideEffectBackendPath,
334
- defaults: BlocksPresets.production,
335
- defaultComputeFactory: stubComputeFactory,
336
- });
337
- const b = await BlocksBackend.create(stack, 'B', {
338
- backendHandlerPath: handlerPath,
339
- backendCDKPath: sideEffectBackendPath,
340
- defaults: BlocksPresets.sandbox,
341
- defaultComputeFactory: stubComputeFactory,
342
- });
343
-
344
- // Two backends in one stack must NOT clobber each other — defaults are
345
- // anchored on the backend, not the shared stack.
346
- assert.strictEqual(a.defaults, BlocksPresets.production);
347
- assert.strictEqual(b.defaults, BlocksPresets.sandbox);
348
- });
349
-
350
- test('a nested block resolves its owning backend defaults via the tree-walk', async () => {
351
- const app = new cdk.App();
352
- const stack = new cdk.Stack(app, 'ResolveDefaultsStack');
353
-
354
- const backend = await BlocksBackend.create(stack, 'Blocks', {
355
- backendHandlerPath: handlerPath,
356
- backendCDKPath: sideEffectBackendPath,
357
- defaults: BlocksPresets.sandbox,
358
- defaultComputeFactory: stubComputeFactory,
359
- });
360
-
361
- // A Scope under the backend resolves scope.defaults by walking up to it.
362
- const outer = new Scope('outer');
363
- const inner = new Scope('inner', { parent: outer });
364
- assert.strictEqual(inner.defaults, backend.defaults);
365
- assert.strictEqual(inner.defaults, BlocksPresets.sandbox);
366
- });
381
+ test('each backend exposes its own defaults', async () => {
382
+ const app = new cdk.App();
383
+ const stack = new cdk.Stack(app, 'TwoBackendsStack');
384
+
385
+ const a = await BlocksBackend.create(stack, 'A', {
386
+ backendHandlerPath: handlerPath,
387
+ backendCDKPath: sideEffectBackendPath,
388
+ defaults: BlocksPresets.production,
389
+ defaultComputeFactory: stubComputeFactory,
390
+ });
391
+ const b = await BlocksBackend.create(stack, 'B', {
392
+ backendHandlerPath: handlerPath,
393
+ backendCDKPath: sideEffectBackendPath,
394
+ defaults: BlocksPresets.sandbox,
395
+ defaultComputeFactory: stubComputeFactory,
396
+ });
397
+
398
+ // Two backends in one stack must NOT clobber each other — defaults are
399
+ // anchored on the backend, not the shared stack.
400
+ assert.strictEqual(a.defaults, BlocksPresets.production);
401
+ assert.strictEqual(b.defaults, BlocksPresets.sandbox);
402
+ });
403
+
404
+ test('a nested block resolves its owning backend defaults via the tree-walk', async () => {
405
+ const app = new cdk.App();
406
+ const stack = new cdk.Stack(app, 'ResolveDefaultsStack');
407
+
408
+ const backend = await BlocksBackend.create(stack, 'Blocks', {
409
+ backendHandlerPath: handlerPath,
410
+ backendCDKPath: sideEffectBackendPath,
411
+ defaults: BlocksPresets.sandbox,
412
+ defaultComputeFactory: stubComputeFactory,
413
+ });
414
+
415
+ // A Scope under the backend resolves scope.defaults by walking up to it.
416
+ const outer = new Scope('outer');
417
+ const inner = new Scope('inner', { parent: outer });
418
+ assert.strictEqual(inner.defaults, backend.defaults);
419
+ assert.strictEqual(inner.defaults, BlocksPresets.sandbox);
420
+ });
421
+ });
422
+
423
+ describe('VPC placement', () => {
424
+ test('places the handler Lambda in the VPC with a security group when vpc is provided', async () => {
425
+ const app = new cdk.App();
426
+ const parent = new cdk.Stack(app, 'VpcParent', {
427
+ env: { account: '123456789012', region: 'us-east-1' },
428
+ });
429
+ const vpc = new cdk.aws_ec2.Vpc(parent, 'AppVpc', { maxAzs: 2, natGateways: 1 });
430
+
431
+ await BlocksBackend.create(parent, 'Blocks', {
432
+ backendHandlerPath: handlerPath,
433
+ backendCDKPath: sideEffectBackendPath,
434
+ defaults: { ...BlocksPresets.production, vpc: { network: vpc } },
435
+ defaultComputeFactory: stubComputeFactory,
436
+ });
437
+
438
+ const template = Template.fromStack(parent);
439
+ // The handler Lambda is VPC-attached: it has a VpcConfig with subnets + SGs.
440
+ template.hasResourceProperties('AWS::Lambda::Function', {
441
+ VpcConfig: Match.objectLike({
442
+ SubnetIds: Match.anyValue(),
443
+ SecurityGroupIds: Match.anyValue(),
444
+ }),
445
+ });
446
+ // The VPC-access managed policy is attached to the execution role.
447
+ const policies = template.findResources('AWS::IAM::Role');
448
+ const hasVpcManagedPolicy = Object.values(policies).some((role: any) =>
449
+ JSON.stringify(role.Properties?.ManagedPolicyArns ?? []).includes('AWSLambdaVPCAccessExecutionRole'),
450
+ );
451
+ assert.ok(hasVpcManagedPolicy, 'execution role should have the VPC access managed policy');
452
+ });
453
+
454
+ test('no VpcConfig on the handler when vpc is omitted', async () => {
455
+ const app = new cdk.App();
456
+ const parent = new cdk.Stack(app, 'NoVpcParent');
457
+
458
+ await BlocksBackend.create(parent, 'Blocks', {
459
+ backendHandlerPath: handlerPath,
460
+ backendCDKPath: sideEffectBackendPath,
461
+ defaults: BlocksPresets.production,
462
+ defaultComputeFactory: stubComputeFactory,
463
+ });
464
+
465
+ const template = Template.fromStack(parent);
466
+ const fns = template.findResources('AWS::Lambda::Function');
467
+ for (const fn of Object.values(fns)) {
468
+ assert.strictEqual(
469
+ (fn as any).Properties?.VpcConfig,
470
+ undefined,
471
+ 'handler must not have VpcConfig when no VPC is configured',
472
+ );
473
+ }
474
+ });
367
475
  });