@aws/nx-plugin 0.82.1 → 0.83.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 (54) hide show
  1. package/LICENSE-THIRD-PARTY +34 -6
  2. package/package.json +1 -1
  3. package/src/infra/app/__snapshots__/generator.spec.ts.snap +4 -4
  4. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +148 -56
  5. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +53 -3
  6. package/src/py/mcp-server/generator.js +1 -0
  7. package/src/py/mcp-server/generator.js.map +1 -1
  8. package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +53 -3
  9. package/src/py/strands-agent/generator.js +1 -0
  10. package/src/py/strands-agent/generator.js.map +1 -1
  11. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +108 -50
  12. package/src/smithy/ts/api/generator.js +2 -0
  13. package/src/smithy/ts/api/generator.js.map +1 -1
  14. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +256 -128
  15. package/src/trpc/backend/generator.js +2 -0
  16. package/src/trpc/backend/generator.js.map +1 -1
  17. package/src/ts/lambda-function/generator.js +2 -0
  18. package/src/ts/lambda-function/generator.js.map +1 -1
  19. package/src/ts/lib/vitest.js +2 -0
  20. package/src/ts/lib/vitest.js.map +1 -1
  21. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +54 -3
  22. package/src/ts/mcp-server/generator.js +7 -1
  23. package/src/ts/mcp-server/generator.js.map +1 -1
  24. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +372 -26
  25. package/src/ts/react-website/app/generator.js +5 -1
  26. package/src/ts/react-website/app/generator.js.map +1 -1
  27. package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +2 -2
  28. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +2 -0
  29. package/src/ts/strands-agent/__snapshots__/generator.spec.ts.snap +52 -3
  30. package/src/ts/strands-agent/generator.js +3 -1
  31. package/src/ts/strands-agent/generator.js.map +1 -1
  32. package/src/utils/__snapshots__/shared-constructs.spec.ts.snap +157 -5
  33. package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +14 -0
  34. package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +37 -2
  35. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +1 -1
  36. package/src/utils/api-constructs/files/cdk/app/apis/http/__apiNameKebabCase__.ts.template +19 -17
  37. package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +28 -21
  38. package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +4 -3
  39. package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +24 -5
  40. package/src/utils/api-constructs/files/cdk/core/api/utils/utils.ts.template +4 -1
  41. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +11 -2
  42. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +11 -2
  43. package/src/utils/files/common/constructs/src/core/runtime-config.ts.template +157 -5
  44. package/src/utils/files/terraform/src/core/runtime-config/appconfig/appconfig.tf.template +100 -0
  45. package/src/utils/files/terraform/src/core/runtime-config/entry/entry.tf.template +19 -17
  46. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +12 -5
  47. package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +2 -2
  48. package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +2 -0
  49. package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +2 -1
  50. package/src/utils/versions.d.ts +6 -1
  51. package/src/utils/versions.js +5 -0
  52. package/src/utils/versions.js.map +1 -1
  53. package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +8 -3
  54. package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +10 -1
@@ -3218,12 +3218,12 @@ SOFTWARE.
3218
3218
 
3219
3219
  ---
3220
3220
 
3221
- The following software may be included in this product: @esbuild/linux-x64 (0.27.3)
3221
+ The following software may be included in this product: @esbuild/darwin-arm64 (0.27.3)
3222
3222
  This software contains the following license and notice below:
3223
3223
 
3224
3224
  MIT License
3225
3225
 
3226
- Copyright (c) The maintainers of @esbuild/linux-x64 <https://github.com/evanw/esbuild#readme>
3226
+ Copyright (c) The maintainers of @esbuild/darwin-arm64 <https://github.com/evanw/esbuild#readme>
3227
3227
 
3228
3228
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
3229
3229
  associated documentation files (the "Software"), to deal in the Software without restriction, including
@@ -4415,7 +4415,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4415
4415
 
4416
4416
  ---
4417
4417
 
4418
- The following software may be included in this product: @nx/nx-linux-x64-gnu (22.5.3)
4418
+ The following software may be included in this product: @nx/nx-darwin-arm64 (22.5.3)
4419
4419
  This software contains the following license and notice below:
4420
4420
 
4421
4421
  (The MIT License)
@@ -5133,7 +5133,7 @@ THE SOFTWARE.
5133
5133
 
5134
5134
  ---
5135
5135
 
5136
- The following software may be included in this product: @rollup/rollup-linux-x64-gnu (4.50.1)
5136
+ The following software may be included in this product: @rollup/rollup-darwin-arm64 (4.50.1)
5137
5137
  This software contains the following license and notice below:
5138
5138
 
5139
5139
  MIT License
@@ -5185,7 +5185,7 @@ SOFTWARE.
5185
5185
 
5186
5186
  ---
5187
5187
 
5188
- The following software may be included in this product: @rspack/binding-linux-x64-gnu (1.6.8)
5188
+ The following software may be included in this product: @rspack/binding-darwin-arm64 (1.6.8)
5189
5189
  This software contains the following license and notice below:
5190
5190
 
5191
5191
  MIT License
@@ -12950,6 +12950,34 @@ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHE
12950
12950
 
12951
12951
  ---
12952
12952
 
12953
+ The following software may be included in this product: fsevents (2.3.3)
12954
+ This software contains the following license and notice below:
12955
+
12956
+ MIT License
12957
+ -----------
12958
+
12959
+ Copyright (C) 2010-2020 by Philipp Dunkel, Ben Noordhuis, Elan Shankar, Paul Miller
12960
+
12961
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12962
+ of this software and associated documentation files (the "Software"), to deal
12963
+ in the Software without restriction, including without limitation the rights
12964
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12965
+ copies of the Software, and to permit persons to whom the Software is
12966
+ furnished to do so, subject to the following conditions:
12967
+
12968
+ The above copyright notice and this permission notice shall be included in
12969
+ all copies or substantial portions of the Software.
12970
+
12971
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12972
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12973
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12974
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12975
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12976
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
12977
+ THE SOFTWARE.
12978
+
12979
+ ---
12980
+
12953
12981
  The following software may be included in this product: function-bind (1.1.2)
12954
12982
  This software contains the following license and notice below:
12955
12983
 
@@ -39785,7 +39813,7 @@ defined by the Mozilla Public License, v. 2.0.
39785
39813
 
39786
39814
  ---
39787
39815
 
39788
- The following software may be included in this product: lightningcss-linux-x64-gnu (1.31.1)
39816
+ The following software may be included in this product: lightningcss-darwin-arm64 (1.31.1)
39789
39817
  This software contains the following license and notice below:
39790
39818
 
39791
39819
  Mozilla Public License Version 2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws/nx-plugin",
3
- "version": "0.82.1",
3
+ "version": "0.83.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/awslabs/nx-plugin-for-aws.git",
@@ -21,7 +21,7 @@ exports[`infra generator > should add required dependencies to package.json > de
21
21
  "@swc/core": "~1.15.5",
22
22
  "@swc/helpers": "~0.5.18",
23
23
  "@types/node": "22.19.13",
24
- "@vitest/coverage-v8": "^4.0.0",
24
+ "@vitest/coverage-v8": "4.0.18",
25
25
  "eslint": "^9.8.0",
26
26
  "eslint-config-prettier": "^10.0.0",
27
27
  "eslint-plugin-prettier": "5.5.5",
@@ -32,7 +32,7 @@ exports[`infra generator > should add required dependencies to package.json > de
32
32
  "typescript": "~5.9.2",
33
33
  "typescript-eslint": "^8.40.0",
34
34
  "vite": "^7.0.0",
35
- "vitest": "^4.0.8",
35
+ "vitest": "4.0.18",
36
36
  }
37
37
  `;
38
38
 
@@ -55,7 +55,7 @@ exports[`infra generator > should add required dependencies to package.json > pa
55
55
  "@swc/core": "~1.15.5",
56
56
  "@swc/helpers": "~0.5.18",
57
57
  "@types/node": "22.19.13",
58
- "@vitest/coverage-v8": "^4.0.0",
58
+ "@vitest/coverage-v8": "4.0.18",
59
59
  "eslint": "^9.8.0",
60
60
  "eslint-config-prettier": "^10.0.0",
61
61
  "eslint-plugin-prettier": "5.5.5",
@@ -66,7 +66,7 @@ exports[`infra generator > should add required dependencies to package.json > pa
66
66
  "typescript": "~5.9.2",
67
67
  "typescript-eslint": "^8.40.0",
68
68
  "vite": "^7.0.0",
69
- "vitest": "^4.0.8",
69
+ "vitest": "4.0.18",
70
70
  },
71
71
  "name": "@proj/source",
72
72
  "type": "module",
@@ -384,10 +384,11 @@ export class HttpApi<
384
384
  });
385
385
 
386
386
  // Register the API URL in runtime configuration for client discovery
387
- RuntimeConfig.ensure(this).config.apis = {
388
- ...RuntimeConfig.ensure(this).config.apis!,
387
+ const rc = RuntimeConfig.ensure(this);
388
+ rc.set('connection', 'apis', {
389
+ ...rc.get('connection').apis,
389
390
  [apiName]: this.defaultStage.url!,
390
- };
391
+ });
391
392
  }
392
393
 
393
394
  /**
@@ -414,6 +415,7 @@ import {
414
415
  SnapStartConf,
415
416
  } from 'aws-cdk-lib/aws-lambda';
416
417
  import { Duration, Stack } from 'aws-cdk-lib';
418
+ import { RuntimeConfig } from '../../core/runtime-config.js';
417
419
  import { CorsHttpMethod, CfnApi } from 'aws-cdk-lib/aws-apigatewayv2';
418
420
  import { HttpIamAuthorizer } from 'aws-cdk-lib/aws-apigatewayv2-authorizers';
419
421
  import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations';
@@ -459,6 +461,7 @@ export class TestApi<
459
461
  * @returns An IntegrationBuilder with default lambda integrations
460
462
  */
461
463
  public static defaultIntegrations = (scope: Construct) => {
464
+ const rc = RuntimeConfig.ensure(scope);
462
465
  return IntegrationBuilder.http({
463
466
  pattern: 'isolated',
464
467
  operations: OPERATION_DETAILS,
@@ -478,6 +481,7 @@ export class TestApi<
478
481
  snapStart: SnapStartConf.ON_PUBLISHED_VERSIONS,
479
482
  environment: {
480
483
  AWS_CONNECTION_REUSE_ENABLED: '1',
484
+ RUNTIME_CONFIG_APP_ID: rc.appConfigApplicationId,
481
485
  PORT: '8000',
482
486
  AWS_LWA_INVOKE_MODE: 'buffered',
483
487
  AWS_LAMBDA_EXEC_WRAPPER: '/opt/bootstrap',
@@ -485,6 +489,7 @@ export class TestApi<
485
489
  },
486
490
  buildDefaultIntegration: (op, props: FunctionProps) => {
487
491
  const handler = new Function(scope, \`TestApi\${op}Handler\`, props);
492
+ rc.grantReadAppConfig(handler);
488
493
  const stack = Stack.of(scope);
489
494
  handler.addLayers(
490
495
  LayerVersion.fromLayerVersionArn(
@@ -529,21 +534,28 @@ export class TestApi<
529
534
  }
530
535
 
531
536
  /**
532
- * Restricts CORS to the website CloudFront distribution domains
537
+ * Restricts CORS to the provided origins
533
538
  *
534
- * Configures the CloudFront distribution domains as the only permitted CORS origins
535
- * (other than local host with default ports) in the API gateway
536
- * The CORS origins are not configured within the AWS Lambda integrations since
537
- * the associated header is controlled by API Gateway v2
539
+ * Configures the provided CloudFront distribution domains or origin strings
540
+ * as the only permitted CORS origins
541
+ * in the API gateway. The CORS origins are not configured within the AWS Lambda
542
+ * integrations since the associated header is controlled by API Gateway v2.
538
543
  *
539
- * @param cloudFrontDistribution - The CloudFront distribution to grant CORS from
544
+ * @param origins - The origin strings, CloudFront distributions, or objects containing a CloudFront distribution to grant CORS from
540
545
  */
541
546
  public restrictCorsTo(
542
- ...websites: { cloudFrontDistribution: Distribution }[]
547
+ ...origins: (
548
+ | string
549
+ | Distribution
550
+ | { cloudFrontDistribution: Distribution }
551
+ )[]
543
552
  ) {
544
- const allowedOrigins = websites.map(
545
- ({ cloudFrontDistribution }) =>
546
- \`https://\${cloudFrontDistribution.distributionDomainName}\`,
553
+ const allowedOrigins = origins.map((origin) =>
554
+ typeof origin === 'string'
555
+ ? origin
556
+ : 'cloudFrontDistribution' in origin
557
+ ? \`https://\${origin.cloudFrontDistribution.distributionDomainName}\`
558
+ : \`https://\${origin.distributionDomainName}\`,
547
559
  );
548
560
 
549
561
  const cfnApi = this.api.node.defaultChild;
@@ -554,11 +566,7 @@ export class TestApi<
554
566
  }
555
567
 
556
568
  cfnApi.corsConfiguration = {
557
- allowOrigins: [
558
- 'http://localhost:4200',
559
- 'http://localhost:4300',
560
- ...allowedOrigins,
561
- ],
569
+ allowOrigins: allowedOrigins,
562
570
  allowMethods: [CorsHttpMethod.ANY],
563
571
  allowHeaders: [
564
572
  'authorization',
@@ -936,13 +944,16 @@ export class IntegrationBuilder<
936
944
  `;
937
945
 
938
946
  exports[`fastapi project generator > should set up shared constructs for rest > rest-api.ts 1`] = `
939
- "import { Construct } from 'constructs';
947
+ "import { Construct, IConstruct } from 'constructs';
940
948
  import {
949
+ Cors,
950
+ Resource,
941
951
  RestApi as _RestApi,
942
952
  RestApiProps as _RestApiProps,
943
953
  IResource,
944
954
  Stage,
945
955
  } from 'aws-cdk-lib/aws-apigateway';
956
+ import { IAspect } from 'aws-cdk-lib';
946
957
  import { RuntimeConfig } from '../runtime-config.js';
947
958
  import {
948
959
  ApiIntegrations,
@@ -1041,7 +1052,7 @@ export class RestApi<
1041
1052
  };
1042
1053
 
1043
1054
  // Create API resources and methods for each operation
1044
- (Object.entries(operations) as [TOperation, OperationDetails][]).map(
1055
+ (Object.entries(operations) as [TOperation, OperationDetails][]).forEach(
1045
1056
  ([op, details]) => {
1046
1057
  const integration = resolveIntegration(op);
1047
1058
  const resource = this.getOrCreateResource(
@@ -1060,10 +1071,11 @@ export class RestApi<
1060
1071
  );
1061
1072
 
1062
1073
  // Register the API URL in runtime configuration for client discovery
1063
- RuntimeConfig.ensure(this).config.apis = {
1064
- ...RuntimeConfig.ensure(this).config.apis!,
1074
+ const rc = RuntimeConfig.ensure(this);
1075
+ rc.set('connection', 'apis', {
1076
+ ...rc.get('connection').apis,
1065
1077
  [apiName]: this.api.url!,
1066
- };
1078
+ });
1067
1079
  }
1068
1080
 
1069
1081
  /**
@@ -1085,6 +1097,21 @@ export class RestApi<
1085
1097
  return this.getOrCreateResource(childResource, pathParts);
1086
1098
  }
1087
1099
  }
1100
+
1101
+ export class AddCorsPreflightAspect implements IAspect {
1102
+ private getAllowedOrigins: () => readonly string[];
1103
+ constructor(getAllowedOrigins: () => readonly string[]) {
1104
+ this.getAllowedOrigins = getAllowedOrigins;
1105
+ }
1106
+ public visit(node: IConstruct): void {
1107
+ if (node instanceof Resource) {
1108
+ node.addCorsPreflight({
1109
+ allowOrigins: [...this.getAllowedOrigins()],
1110
+ allowMethods: Cors.ALL_METHODS,
1111
+ });
1112
+ }
1113
+ }
1114
+ }
1088
1115
  "
1089
1116
  `;
1090
1117
 
@@ -1101,13 +1128,13 @@ import {
1101
1128
  LayerVersion,
1102
1129
  SnapStartConf,
1103
1130
  } from 'aws-cdk-lib/aws-lambda';
1131
+ import { RuntimeConfig } from '../../core/runtime-config.js';
1104
1132
  import {
1105
1133
  AuthorizationType,
1106
- Cors,
1107
1134
  LambdaIntegration,
1108
1135
  ResponseTransferMode,
1109
1136
  } from 'aws-cdk-lib/aws-apigateway';
1110
- import { Duration, Stack } from 'aws-cdk-lib';
1137
+ import { Aspects, Duration, Stack } from 'aws-cdk-lib';
1111
1138
  import {
1112
1139
  PolicyDocument,
1113
1140
  PolicyStatement,
@@ -1121,7 +1148,7 @@ import {
1121
1148
  IntegrationBuilder,
1122
1149
  RestApiIntegration,
1123
1150
  } from '../../core/api/utils.js';
1124
- import { RestApi } from '../../core/api/rest-api.js';
1151
+ import { AddCorsPreflightAspect, RestApi } from '../../core/api/rest-api.js';
1125
1152
  import {
1126
1153
  OPERATION_DETAILS,
1127
1154
  Operations,
@@ -1149,6 +1176,8 @@ export interface TestApiProps<
1149
1176
  export class TestApi<
1150
1177
  TIntegrations extends ApiIntegrations<Operations, RestApiIntegration>,
1151
1178
  > extends RestApi<Operations, TIntegrations> {
1179
+ private allowedOrigins: readonly string[] = ['*'];
1180
+
1152
1181
  /**
1153
1182
  * Creates default integrations for all operations, which implement each operation as
1154
1183
  * its own individual lambda function.
@@ -1157,6 +1186,7 @@ export class TestApi<
1157
1186
  * @returns An IntegrationBuilder with default lambda integrations
1158
1187
  */
1159
1188
  public static defaultIntegrations = (scope: Construct) => {
1189
+ const rc = RuntimeConfig.ensure(scope);
1160
1190
  return IntegrationBuilder.rest({
1161
1191
  pattern: 'isolated',
1162
1192
  operations: OPERATION_DETAILS,
@@ -1176,6 +1206,7 @@ export class TestApi<
1176
1206
  snapStart: SnapStartConf.ON_PUBLISHED_VERSIONS,
1177
1207
  environment: {
1178
1208
  AWS_CONNECTION_REUSE_ENABLED: '1',
1209
+ RUNTIME_CONFIG_APP_ID: rc.appConfigApplicationId,
1179
1210
  PORT: '8000',
1180
1211
  AWS_LWA_INVOKE_MODE: 'response_stream',
1181
1212
  AWS_LAMBDA_EXEC_WRAPPER: '/opt/bootstrap',
@@ -1183,6 +1214,7 @@ export class TestApi<
1183
1214
  },
1184
1215
  buildDefaultIntegration: (op, props: FunctionProps) => {
1185
1216
  const handler = new Function(scope, \`TestApi\${op}Handler\`, props);
1217
+ rc.grantReadAppConfig(handler);
1186
1218
  const stack = Stack.of(scope);
1187
1219
  handler.addLayers(
1188
1220
  LayerVersion.fromLayerVersionArn(
@@ -1211,10 +1243,6 @@ export class TestApi<
1211
1243
  defaultMethodOptions: {
1212
1244
  authorizationType: AuthorizationType.IAM,
1213
1245
  },
1214
- defaultCorsPreflightOptions: {
1215
- allowOrigins: Cors.ALL_ORIGINS,
1216
- allowMethods: Cors.ALL_METHODS,
1217
- },
1218
1246
  deployOptions: {
1219
1247
  tracingEnabled: true,
1220
1248
  },
@@ -1232,32 +1260,42 @@ export class TestApi<
1232
1260
  operations: OPERATION_DETAILS,
1233
1261
  ...props,
1234
1262
  });
1263
+ Aspects.of(this).add(new AddCorsPreflightAspect(() => this.allowedOrigins));
1235
1264
  }
1236
1265
 
1237
1266
  /**
1238
- * Restricts CORS to the website CloudFront distribution domains
1239
- *
1240
- * Configures the CloudFront distribution domains as the only permitted CORS origins
1241
- * (other than local host) in the AWS Lambda integrations
1267
+ * Restricts CORS to the provided origins
1242
1268
  *
1243
- * Note that this restriction is not applied to preflight OPTIONS
1269
+ * Configures the provided CloudFront distribution domains or origin strings
1270
+ * as the only permitted CORS origins in API Gateway preflight responses and the
1271
+ * AWS Lambda integrations.
1244
1272
  *
1245
- * @param websites - The CloudFront distribution to grant CORS from
1273
+ * @param origins - The origin strings, CloudFront distributions, or objects containing a CloudFront distribution to grant CORS from
1246
1274
  */
1247
1275
  public restrictCorsTo(
1248
- ...websites: { cloudFrontDistribution: Distribution }[]
1276
+ ...origins: (
1277
+ | string
1278
+ | Distribution
1279
+ | { cloudFrontDistribution: Distribution }
1280
+ )[]
1249
1281
  ) {
1250
- const allowedOrigins = websites
1251
- .map(
1252
- ({ cloudFrontDistribution }) =>
1253
- \`https://\${cloudFrontDistribution.distributionDomainName}\`,
1254
- )
1255
- .join(',');
1282
+ const allowedOrigins = origins.map((origin) =>
1283
+ typeof origin === 'string'
1284
+ ? origin
1285
+ : 'cloudFrontDistribution' in origin
1286
+ ? \`https://\${origin.cloudFrontDistribution.distributionDomainName}\`
1287
+ : \`https://\${origin.distributionDomainName}\`,
1288
+ );
1289
+
1290
+ this.allowedOrigins = allowedOrigins;
1256
1291
 
1257
1292
  // Set ALLOWED_ORIGINS environment variable for all Lambda integrations
1258
1293
  Object.values(this.integrations).forEach((integration) => {
1259
1294
  if ('handler' in integration && integration.handler instanceof Function) {
1260
- integration.handler.addEnvironment('ALLOWED_ORIGINS', allowedOrigins);
1295
+ integration.handler.addEnvironment(
1296
+ 'ALLOWED_ORIGINS',
1297
+ allowedOrigins.join(','),
1298
+ );
1261
1299
  }
1262
1300
  });
1263
1301
  }
@@ -2157,12 +2195,21 @@ resource "aws_apigatewayv2_route" "proxy_routes" {
2157
2195
  module "add_url_to_runtime_config" {
2158
2196
  source = "../../../core/runtime-config/entry"
2159
2197
 
2160
- key_path = "apis.TestApi"
2161
- value = module.http_api.stage_invoke_url
2198
+ namespace = "connection"
2199
+ key = "apis"
2200
+ value = { "TestApi" = module.http_api.stage_invoke_url }
2162
2201
 
2163
2202
  depends_on = [module.http_api]
2164
2203
  }
2165
2204
 
2205
+ module "appconfig" {
2206
+ source = "../../../core/runtime-config/appconfig"
2207
+
2208
+ application_name = "TestApi-runtime-config"
2209
+
2210
+ depends_on = [module.add_url_to_runtime_config]
2211
+ }
2212
+
2166
2213
  # Lambda permission for API Gateway to invoke the function via alias
2167
2214
  resource "aws_lambda_permission" "api_gateway_invoke" {
2168
2215
  statement_id = "AllowExecutionFromAPIGateway"
@@ -2784,12 +2831,21 @@ resource "aws_apigatewayv2_route" "proxy_routes" {
2784
2831
  module "add_url_to_runtime_config" {
2785
2832
  source = "../../../core/runtime-config/entry"
2786
2833
 
2787
- key_path = "apis.TestApi"
2788
- value = module.http_api.stage_invoke_url
2834
+ namespace = "connection"
2835
+ key = "apis"
2836
+ value = { "TestApi" = module.http_api.stage_invoke_url }
2789
2837
 
2790
2838
  depends_on = [module.http_api]
2791
2839
  }
2792
2840
 
2841
+ module "appconfig" {
2842
+ source = "../../../core/runtime-config/appconfig"
2843
+
2844
+ application_name = "TestApi-runtime-config"
2845
+
2846
+ depends_on = [module.add_url_to_runtime_config]
2847
+ }
2848
+
2793
2849
  # Lambda permission for API Gateway to invoke the function via alias
2794
2850
  resource "aws_lambda_permission" "api_gateway_invoke" {
2795
2851
  statement_id = "AllowExecutionFromAPIGateway"
@@ -3413,12 +3469,21 @@ resource "aws_apigatewayv2_route" "proxy_routes" {
3413
3469
  module "add_url_to_runtime_config" {
3414
3470
  source = "../../../core/runtime-config/entry"
3415
3471
 
3416
- key_path = "apis.TestApi"
3417
- value = module.http_api.stage_invoke_url
3472
+ namespace = "connection"
3473
+ key = "apis"
3474
+ value = { "TestApi" = module.http_api.stage_invoke_url }
3418
3475
 
3419
3476
  depends_on = [module.http_api]
3420
3477
  }
3421
3478
 
3479
+ module "appconfig" {
3480
+ source = "../../../core/runtime-config/appconfig"
3481
+
3482
+ application_name = "TestApi-runtime-config"
3483
+
3484
+ depends_on = [module.add_url_to_runtime_config]
3485
+ }
3486
+
3422
3487
  # Lambda permission for API Gateway to invoke the function via alias
3423
3488
  resource "aws_lambda_permission" "api_gateway_invoke" {
3424
3489
  statement_id = "AllowExecutionFromAPIGateway"
@@ -4084,12 +4149,21 @@ resource "aws_lambda_permission" "api_gateway_invoke_streaming" {
4084
4149
  module "add_url_to_runtime_config" {
4085
4150
  source = "../../../core/runtime-config/entry"
4086
4151
 
4087
- key_path = "apis.TestApi"
4088
- value = aws_api_gateway_stage.api_stage.invoke_url
4152
+ namespace = "connection"
4153
+ key = "apis"
4154
+ value = { "TestApi" = aws_api_gateway_stage.api_stage.invoke_url }
4089
4155
 
4090
4156
  depends_on = [aws_api_gateway_stage.api_stage]
4091
4157
  }
4092
4158
 
4159
+ module "appconfig" {
4160
+ source = "../../../core/runtime-config/appconfig"
4161
+
4162
+ application_name = "TestApi-runtime-config"
4163
+
4164
+ depends_on = [module.add_url_to_runtime_config]
4165
+ }
4166
+
4093
4167
  # Outputs
4094
4168
 
4095
4169
  # API Gateway Outputs (from core module)
@@ -4746,12 +4820,21 @@ resource "aws_lambda_permission" "api_gateway_invoke_streaming" {
4746
4820
  module "add_url_to_runtime_config" {
4747
4821
  source = "../../../core/runtime-config/entry"
4748
4822
 
4749
- key_path = "apis.TestApi"
4750
- value = aws_api_gateway_stage.api_stage.invoke_url
4823
+ namespace = "connection"
4824
+ key = "apis"
4825
+ value = { "TestApi" = aws_api_gateway_stage.api_stage.invoke_url }
4751
4826
 
4752
4827
  depends_on = [aws_api_gateway_stage.api_stage]
4753
4828
  }
4754
4829
 
4830
+ module "appconfig" {
4831
+ source = "../../../core/runtime-config/appconfig"
4832
+
4833
+ application_name = "TestApi-runtime-config"
4834
+
4835
+ depends_on = [module.add_url_to_runtime_config]
4836
+ }
4837
+
4755
4838
  # Outputs
4756
4839
 
4757
4840
  # API Gateway Outputs (from core module)
@@ -5399,12 +5482,21 @@ resource "aws_lambda_permission" "api_gateway_invoke_streaming" {
5399
5482
  module "add_url_to_runtime_config" {
5400
5483
  source = "../../../core/runtime-config/entry"
5401
5484
 
5402
- key_path = "apis.TestApi"
5403
- value = aws_api_gateway_stage.api_stage.invoke_url
5485
+ namespace = "connection"
5486
+ key = "apis"
5487
+ value = { "TestApi" = aws_api_gateway_stage.api_stage.invoke_url }
5404
5488
 
5405
5489
  depends_on = [aws_api_gateway_stage.api_stage]
5406
5490
  }
5407
5491
 
5492
+ module "appconfig" {
5493
+ source = "../../../core/runtime-config/appconfig"
5494
+
5495
+ application_name = "TestApi-runtime-config"
5496
+
5497
+ depends_on = [module.add_url_to_runtime_config]
5498
+ }
5499
+
5408
5500
  # Outputs
5409
5501
 
5410
5502
  # API Gateway Outputs (from core module)
@@ -25,6 +25,7 @@ import {
25
25
  Runtime,
26
26
  RuntimeProps,
27
27
  } from '@aws-cdk/aws-bedrock-agentcore-alpha';
28
+ import { RuntimeConfig } from '../../../core/runtime-config.js';
28
29
 
29
30
  export type SnapshotBedrockServerProps = Omit<
30
31
  RuntimeProps,
@@ -42,6 +43,8 @@ export class SnapshotBedrockServer extends Construct {
42
43
  ) {
43
44
  super(scope, id);
44
45
 
46
+ const rc = RuntimeConfig.ensure(this);
47
+
45
48
  this.dockerImage = AgentRuntimeArtifact.fromAsset(
46
49
  path.dirname(url.fileURLToPath(new URL(import.meta.url))),
47
50
  {
@@ -61,6 +64,17 @@ export class SnapshotBedrockServer extends Construct {
61
64
  protocolConfiguration: ProtocolType.MCP,
62
65
  agentRuntimeArtifact: this.dockerImage,
63
66
  ...props,
67
+ environmentVariables: {
68
+ RUNTIME_CONFIG_APP_ID: rc.appConfigApplicationId,
69
+ ...props?.environmentVariables,
70
+ },
71
+ });
72
+
73
+ rc.grantReadAppConfig(this.agentCoreRuntime);
74
+
75
+ rc.set('connection', 'agentRuntimes', {
76
+ ...rc.get('connection').agentRuntimes,
77
+ SnapshotBedrockServer: this.agentCoreRuntime.agentRuntimeArn,
64
78
  });
65
79
  }
66
80
  }
@@ -406,7 +420,7 @@ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
406
420
 
407
421
  depends_on = [
408
422
  null_resource.docker_publish,
409
- aws_iam_role_policy.agent_core_runtime_policy
423
+ aws_iam_role_policy_attachment.agent_core_policy
410
424
  ]
411
425
  }
412
426
 
@@ -466,6 +480,12 @@ variable "tags" {
466
480
  default = {}
467
481
  }
468
482
 
483
+ module "appconfig" {
484
+ source = "../../../core/runtime-config/appconfig"
485
+
486
+ application_name = "TerraformSnapshotServer-runtime-config"
487
+ }
488
+
469
489
  module "agent_core_runtime" {
470
490
  source = "../../../core/agent-core"
471
491
  agent_runtime_name = "TerraformSnapshotServer"
@@ -478,9 +498,33 @@ module "agent_core_runtime" {
478
498
  # }
479
499
  # }
480
500
 
481
- env = var.env
482
- additional_iam_policy_statements = var.additional_iam_policy_statements
501
+ env = merge({
502
+ RUNTIME_CONFIG_APP_ID = module.appconfig.application_id
503
+ }, var.env)
504
+ additional_iam_policy_statements = concat([
505
+ {
506
+ Effect = "Allow"
507
+ Action = [
508
+ "appconfig:StartConfigurationSession",
509
+ "appconfig:GetLatestConfiguration"
510
+ ]
511
+ Resource = ["\${module.appconfig.application_arn}/*"]
512
+ }
513
+ ], var.additional_iam_policy_statements)
483
514
  tags = var.tags
515
+
516
+ depends_on = [module.appconfig]
517
+ }
518
+
519
+ # Add agent runtime ARN to runtime config
520
+ module "add_agent_runtime_to_runtime_config" {
521
+ source = "../../../core/runtime-config/entry"
522
+
523
+ namespace = "connection"
524
+ key = "agentRuntimes"
525
+ value = { "TerraformSnapshotServer" = module.agent_core_runtime.agent_core_runtime_arn }
526
+
527
+ depends_on = [module.agent_core_runtime]
484
528
  }
485
529
 
486
530
  output "agent_core_runtime_role_arn" {
@@ -492,6 +536,11 @@ output "agent_core_runtime_arn" {
492
536
  description = "ARN of the Bedrock Agent Core runtime"
493
537
  value = module.agent_core_runtime.agent_core_runtime_arn
494
538
  }
539
+
540
+ output "appconfig_application_id" {
541
+ description = "AppConfig Application ID for runtime config"
542
+ value = module.appconfig.application_id
543
+ }
495
544
  "
496
545
  `;
497
546
 
@@ -561,6 +610,7 @@ exports[`py#mcp-server generator > should match snapshot for generated files > u
561
610
  name = "proj.test_project"
562
611
  version = "0.1.0"
563
612
  dependencies = [
613
+ "aws-lambda-powertools==3.25.0",
564
614
  "mcp==1.26.0",
565
615
  "uvicorn==0.41.0",
566
616
  "boto3==1.42.63",
@@ -50,6 +50,7 @@ const pyMcpServerGenerator = (tree, options) => tslib_1.__awaiter(void 0, void 0
50
50
  moduleName,
51
51
  }, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
52
52
  (0, py_1.addDependenciesToPyProjectToml)(tree, project.root, [
53
+ 'aws-lambda-powertools',
53
54
  'mcp',
54
55
  'uvicorn',
55
56
  'boto3',