From 3a844e0a44c30388d8b0298799d55f0dd62bde72 Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Thu, 26 Mar 2026 14:25:15 +0000 Subject: [PATCH 1/8] fix: remove unnecessary VPC endpoints for RDS connections Only the SSM VPC endpoint is needed for Lambda to access Parameter Store. The other 4 endpoints (ssmmessages, ec2, ec2messages, kms) are never used by the code but cost customers ~$350/year per AZ. Fixes #3409 --- .../src/__tests__/rds-pg-array-objects.test.ts | 8 ++++---- .../amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts | 8 ++++---- .../src/rds-v2-tests-common/rds-model-v2.ts | 8 ++++---- .../src/resolvers/rds/resolver.ts | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts b/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts index 5ea140f400..53d43aa30c 100644 --- a/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts @@ -137,10 +137,10 @@ describe('RDS Model Directive', () => { expect(rdsLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); }; afterAll(async () => { diff --git a/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts b/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts index eeb0cf53fc..5dbe5de22c 100644 --- a/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts @@ -109,10 +109,10 @@ describe('RDS Model Directive', () => { expect(rdsLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); }; afterAll(async () => { diff --git a/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts b/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts index 4e688313c4..61dff87acb 100644 --- a/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts +++ b/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts @@ -118,10 +118,10 @@ export const testRDSModel = (engine: ImportedRDSType, queries: string[]): void = expect(sqlLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); // Validate patching lambda and subscription const sqlPatchingLambdaFunction = getResource(resources, resourceNames.sqlPatchingLambdaFunction, CDK_FUNCTION_TYPE); diff --git a/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts b/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts index e45c9a9e38..517311b70b 100644 --- a/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts +++ b/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts @@ -98,8 +98,8 @@ export const getSsmEndpoint = (scope: Construct, resourceNames: SQLLambdaResourc return Fn.join('', ['ssm.', Fn.ref('AWS::Region'), '.amazonaws.com']); } - // Although the Lambda function will only invoke SSM directly, internally the SDK makes calls to other services as well - const services = ['ssm', 'ssmmessages', 'ec2', 'ec2messages', 'kms']; + // Only the SSM VPC endpoint is needed for Lambda to access Parameter Store + const services = ['ssm']; const endpoints = addVpcEndpoints(scope, sqlLambdaVpcConfig, resourceNames, services); const endpointEntries = endpoints.find((endpoint) => endpoint.service === 'ssm')?.endpoint.attrDnsEntries; if (!endpointEntries) { @@ -300,7 +300,7 @@ const addVpcEndpoint = ( ): CfnVPCEndpoint => { const serviceEndpointPrefix = 'com.amazonaws'; const endpoint = new CfnVPCEndpoint(scope, `${resourceNames.sqlVpcEndpointPrefix}${serviceSuffix}`, { - serviceName: Fn.join('', [serviceEndpointPrefix, '.', Fn.ref('AWS::Region'), '.', serviceSuffix]), // Sample: com.amazonaws.us-east-1.ssmmessages + serviceName: Fn.join('', [serviceEndpointPrefix, '.', Fn.ref('AWS::Region'), '.', serviceSuffix]), // Sample: com.amazonaws.us-east-1.ssm vpcEndpointType: 'Interface', vpcId: sqlLambdaVpcConfig.vpcId, subnetIds: extractSubnetForVpcEndpoint(sqlLambdaVpcConfig.subnetAvailabilityZoneConfig), From 6d879ef61e47d8c6f8b8092983ad7e840c0cdaeb Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Fri, 19 Jun 2026 08:46:04 +0000 Subject: [PATCH 2/8] test: update sql-model-definition VPC endpoint count assertion to 1 --- .../src/__tests__/__functional__/sql-model-definition.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts b/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts index c0d49cfd74..1736faa067 100644 --- a/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts +++ b/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts @@ -97,8 +97,8 @@ describe('sql-bound API generated resource access', () => { (resource) => resource.cfnResourceType === 'AWS::EC2::VPCEndpoint', ); - // 5 endpoints per SQL Lambda function. Update this test accordingly as we add additional data sources bound to separate functions. - expect(endpoints.length).toBe(5); + // Only the `ssm` endpoint is created per SQL Lambda function. Update this test accordingly as we add additional data sources bound to separate functions. + expect(endpoints.length).toBe(1); }); it('secrets manager as credentials store', () => { From 722d35f2bf4a8d7f68e0fe6141c68879d64fcd2b Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Tue, 30 Jun 2026 14:25:17 +0000 Subject: [PATCH 3/8] test(amplify-category-api-e2e-tests): revert premature VPC-endpoint e2e assertion [#3449] Released transformer (graphql-model-transformer@2.14.2) still emits all 5 endpoints in the Gen1 amplify-push e2e. The reduction to only 'ssm' is covered by the unit test sql-model-definition.test.ts. Re-enable once >=3.x ships. --- .../src/__tests__/rds-pg-array-objects.test.ts | 9 +++++---- .../src/__tests__/rds-pg-import.test.ts | 9 +++++---- .../src/rds-v2-tests-common/rds-model-v2.ts | 9 +++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts b/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts index 53d43aa30c..eabf6b67d6 100644 --- a/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts @@ -137,10 +137,11 @@ describe('RDS Model Directive', () => { expect(rdsLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + // TODO(#3449): re-enable the reduced VPC-endpoint assertion (only 'ssm' expected) once graphql-model-transformer >=3.x ships in the released @aws-amplify/cli-internal that this Gen1 amplify-push e2e installs. The reduction is validated by the unit test sql-model-definition.test.ts (endpoints.length === 1). + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); }; afterAll(async () => { diff --git a/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts b/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts index 5dbe5de22c..d3f3c4cefb 100644 --- a/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts @@ -109,10 +109,11 @@ describe('RDS Model Directive', () => { expect(rdsLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + // TODO(#3449): re-enable the reduced VPC-endpoint assertion (only 'ssm' expected) once graphql-model-transformer >=3.x ships in the released @aws-amplify/cli-internal that this Gen1 amplify-push e2e installs. The reduction is validated by the unit test sql-model-definition.test.ts (endpoints.length === 1). + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); }; afterAll(async () => { diff --git a/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts b/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts index 61dff87acb..3a4dbbcacc 100644 --- a/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts +++ b/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts @@ -118,10 +118,11 @@ export const testRDSModel = (engine: ImportedRDSType, queries: string[]): void = expect(sqlLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); - expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeUndefined(); + // TODO(#3449): re-enable the reduced VPC-endpoint assertion (only 'ssm' expected) once graphql-model-transformer >=3.x ships in the released @aws-amplify/cli-internal that this Gen1 amplify-push e2e installs. The reduction is validated by the unit test sql-model-definition.test.ts (endpoints.length === 1). + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); + expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2messages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); // Validate patching lambda and subscription const sqlPatchingLambdaFunction = getResource(resources, resourceNames.sqlPatchingLambdaFunction, CDK_FUNCTION_TYPE); From cf15db1703ef8086d539af7091eb582232b43e2f Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Tue, 30 Jun 2026 14:26:55 +0000 Subject: [PATCH 4/8] ci(amplify-category-api-e2e-tests): add throwaway buildspec for RDS revert [#3449] Runs only the 4 affected RDS groups + prerequisites. Remove before merge. --- codebuild_specs/verify_rds_assertions.yml | 62 +++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 codebuild_specs/verify_rds_assertions.yml diff --git a/codebuild_specs/verify_rds_assertions.yml b/codebuild_specs/verify_rds_assertions.yml new file mode 100644 index 0000000000..dd73f4eabb --- /dev/null +++ b/codebuild_specs/verify_rds_assertions.yml @@ -0,0 +1,62 @@ +# throwaway buildspec to verify the reverted VPC-endpoint assertion [#3449] +# runs ONLY the 4 affected RDS groups + their prerequisites (build_linux, publish_to_local_registry). +# blocks copied verbatim from codebuild_specs/e2e_workflow_api_gql.yml. do not regenerate. +version: 0.2 +env: + shell: bash + compute-type: BUILD_GENERAL1_MEDIUM + variables: + JSII_DEPRECATED: quiet +batch: + fast-fail: false + build-graph: + - identifier: build_linux + buildspec: codebuild_specs/build_linux.yml + env: + compute-type: BUILD_GENERAL1_LARGE + - identifier: publish_to_local_registry + buildspec: codebuild_specs/publish_to_local_registry.yml + env: + compute-type: BUILD_GENERAL1_MEDIUM + depend-on: + - build_linux + - identifier: rds_pg_model_v2 + buildspec: codebuild_specs/run_e2e_tests.yml + env: + compute-type: BUILD_GENERAL1_MEDIUM + variables: + NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' + TEST_SUITE: src/__tests__/rds-pg-model-v2.test.ts + CLI_REGION: eu-west-3 + depend-on: + - publish_to_local_registry + - identifier: rds_pg_import + buildspec: codebuild_specs/run_e2e_tests.yml + env: + compute-type: BUILD_GENERAL1_MEDIUM + variables: + NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' + TEST_SUITE: src/__tests__/rds-pg-import.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - identifier: rds_pg_array_objects + buildspec: codebuild_specs/run_e2e_tests.yml + env: + compute-type: BUILD_GENERAL1_MEDIUM + variables: + NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' + TEST_SUITE: src/__tests__/rds-pg-array-objects.test.ts + CLI_REGION: eu-central-1 + depend-on: + - publish_to_local_registry + - identifier: rds_mysql_model_v2 + buildspec: codebuild_specs/run_e2e_tests.yml + env: + compute-type: BUILD_GENERAL1_MEDIUM + variables: + NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' + TEST_SUITE: src/__tests__/rds-mysql-model-v2.test.ts + CLI_REGION: us-west-2 + depend-on: + - publish_to_local_registry From fccb2ab6b844df706f63a6e33acc2d7a713dfc3d Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Tue, 30 Jun 2026 15:24:52 +0000 Subject: [PATCH 5/8] chore: remove throwaway verify_rds_assertions.yml e2e spec [#3449] --- codebuild_specs/verify_rds_assertions.yml | 62 ----------------------- 1 file changed, 62 deletions(-) delete mode 100644 codebuild_specs/verify_rds_assertions.yml diff --git a/codebuild_specs/verify_rds_assertions.yml b/codebuild_specs/verify_rds_assertions.yml deleted file mode 100644 index dd73f4eabb..0000000000 --- a/codebuild_specs/verify_rds_assertions.yml +++ /dev/null @@ -1,62 +0,0 @@ -# throwaway buildspec to verify the reverted VPC-endpoint assertion [#3449] -# runs ONLY the 4 affected RDS groups + their prerequisites (build_linux, publish_to_local_registry). -# blocks copied verbatim from codebuild_specs/e2e_workflow_api_gql.yml. do not regenerate. -version: 0.2 -env: - shell: bash - compute-type: BUILD_GENERAL1_MEDIUM - variables: - JSII_DEPRECATED: quiet -batch: - fast-fail: false - build-graph: - - identifier: build_linux - buildspec: codebuild_specs/build_linux.yml - env: - compute-type: BUILD_GENERAL1_LARGE - - identifier: publish_to_local_registry - buildspec: codebuild_specs/publish_to_local_registry.yml - env: - compute-type: BUILD_GENERAL1_MEDIUM - depend-on: - - build_linux - - identifier: rds_pg_model_v2 - buildspec: codebuild_specs/run_e2e_tests.yml - env: - compute-type: BUILD_GENERAL1_MEDIUM - variables: - NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' - TEST_SUITE: src/__tests__/rds-pg-model-v2.test.ts - CLI_REGION: eu-west-3 - depend-on: - - publish_to_local_registry - - identifier: rds_pg_import - buildspec: codebuild_specs/run_e2e_tests.yml - env: - compute-type: BUILD_GENERAL1_MEDIUM - variables: - NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' - TEST_SUITE: src/__tests__/rds-pg-import.test.ts - CLI_REGION: us-east-1 - depend-on: - - publish_to_local_registry - - identifier: rds_pg_array_objects - buildspec: codebuild_specs/run_e2e_tests.yml - env: - compute-type: BUILD_GENERAL1_MEDIUM - variables: - NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' - TEST_SUITE: src/__tests__/rds-pg-array-objects.test.ts - CLI_REGION: eu-central-1 - depend-on: - - publish_to_local_registry - - identifier: rds_mysql_model_v2 - buildspec: codebuild_specs/run_e2e_tests.yml - env: - compute-type: BUILD_GENERAL1_MEDIUM - variables: - NODE_OPTIONS: '--max-old-space-size=6656 --experimental-vm-modules' - TEST_SUITE: src/__tests__/rds-mysql-model-v2.test.ts - CLI_REGION: us-west-2 - depend-on: - - publish_to_local_registry From 430deed6d4e3fbd84d9ef9edb48e8c51e19d04cb Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Fri, 3 Jul 2026 15:06:03 +0000 Subject: [PATCH 6/8] feat: gate RDS VPC endpoint minimization behind minimizeRdsVpcEndpoints feature flag (default off) --- .../__tests__/rds-pg-array-objects.test.ts | 1 - .../src/__tests__/rds-pg-import.test.ts | 1 - .../src/rds-v2-tests-common/rds-model-v2.ts | 1 - packages/amplify-graphql-api-construct/.jsii | 185 +++++++++++------- packages/amplify-graphql-api-construct/API.md | 2 + .../sql-model-definition.test.ts | 45 ++++- .../src/internal/default-parameters.ts | 1 + .../src/types.ts | 16 ++ .../amplify-sql-resource-generator.test.ts | 53 +++++ .../src/resolvers/rds/resolver.ts | 24 ++- .../resources/rds-model-resource-generator.ts | 8 +- .../transform-parameters.ts | 3 + .../transform-parameters.ts | 8 + 13 files changed, 264 insertions(+), 84 deletions(-) diff --git a/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts b/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts index eabf6b67d6..5ea140f400 100644 --- a/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/rds-pg-array-objects.test.ts @@ -137,7 +137,6 @@ describe('RDS Model Directive', () => { expect(rdsLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - // TODO(#3449): re-enable the reduced VPC-endpoint assertion (only 'ssm' expected) once graphql-model-transformer >=3.x ships in the released @aws-amplify/cli-internal that this Gen1 amplify-push e2e installs. The reduction is validated by the unit test sql-model-definition.test.ts (endpoints.length === 1). expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); diff --git a/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts b/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts index d3f3c4cefb..eeb0cf53fc 100644 --- a/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/rds-pg-import.test.ts @@ -109,7 +109,6 @@ describe('RDS Model Directive', () => { expect(rdsLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - // TODO(#3449): re-enable the reduced VPC-endpoint assertion (only 'ssm' expected) once graphql-model-transformer >=3.x ships in the released @aws-amplify/cli-internal that this Gen1 amplify-push e2e installs. The reduction is validated by the unit test sql-model-definition.test.ts (endpoints.length === 1). expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); diff --git a/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts b/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts index 3a4dbbcacc..4e688313c4 100644 --- a/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts +++ b/packages/amplify-e2e-tests/src/rds-v2-tests-common/rds-model-v2.ts @@ -118,7 +118,6 @@ export const testRDSModel = (engine: ImportedRDSType, queries: string[]): void = expect(sqlLambdaFunction.Properties.VpcConfig.SecurityGroupIds.length).toBeGreaterThan(0); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssm`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); - // TODO(#3449): re-enable the reduced VPC-endpoint assertion (only 'ssm' expected) once graphql-model-transformer >=3.x ships in the released @aws-amplify/cli-internal that this Gen1 amplify-push e2e installs. The reduction is validated by the unit test sql-model-definition.test.ts (endpoints.length === 1). expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ssmmessages`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}kms`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); expect(getResource(resources, `${resourceNames.sqlVpcEndpointPrefix}ec2`, CDK_VPC_ENDPOINT_TYPE)).toBeDefined(); diff --git a/packages/amplify-graphql-api-construct/.jsii b/packages/amplify-graphql-api-construct/.jsii index 0748e1ef59..b7b5b99ffb 100644 --- a/packages/amplify-graphql-api-construct/.jsii +++ b/packages/amplify-graphql-api-construct/.jsii @@ -9176,7 +9176,7 @@ }, "name": "@aws-amplify/graphql-api-construct", "readme": { - "markdown": "# Amplify Graphql API Construct\n\n[![View on Construct Hub](https://constructs.dev/badge?package=%40aws-amplify%2Fgraphql-api-construct)](https://constructs.dev/packages/@aws-amplify/graphql-api-construct)\n\nThis package vends an L3 CDK Construct wrapping the behavior of the Amplify GraphQL Transformer. This enables quick development and interation of AppSync APIs which support the Amplify GraphQL Directives. For more information on schema modeling in GraphQL, please refer to the [amplify developer docs](https://docs.amplify.aws/cli/graphql/overview/).\n\nThe primary way to use this construct is to invoke it with a provided schema (either as an inline graphql string, or as one or more `appsync.SchemaFile`) objects, and with authorization config provided. There are 5 supported methods for authorization of an AppSync API, all of which are supported by this construct. For more information on authorization rule definitions in Amplify, refer to the [authorization docs](https://docs.amplify.aws/cli/graphql/authorization-rules/). Note: currently at least one authorization rule is required, and if multiple are specified, a `defaultAuthorizationMode` must be specified on the api as well. Specified authorization modes must be a superset of those configured in the graphql schema.\n\n## Examples\n\n### Simple Todo List With Cognito Userpool-based Owner Authorization\n\nIn this example, we create a single model, which will use `user pool` auth in order to allow logged in users to create and manage their own `todos` privately.\n\nWe create a cdk App and Stack, though you may be deploying this to a custom stack, this is purely illustrative for a concise demo.\n\nWe then wire this through to import a user pool which was already deployed (creating and deploying is out of scope for this example).\n\n```ts\nimport { App, Stack } from 'aws-cdk-lib';\nimport { UserPool } from 'aws-cdk-lib/aws-cognito';\nimport { AmplifyGraphqlApi, AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct';\n\nconst app = new App();\nconst stack = new Stack(app, 'TodoStack');\n\nnew AmplifyGraphqlApi(stack, 'TodoApp', {\n definition: AmplifyGraphqlDefinition.fromString(/* GraphQL */ `\n type Todo @model @auth(rules: [{ allow: owner }]) {\n description: String!\n completed: Boolean\n }\n `),\n authorizationModes: {\n userPoolConfig: {\n userPool: UserPool.fromUserPoolId(stack, 'ImportedUserPool', ''),\n },\n },\n});\n```\n\n### Multiple related models, with public read access, and admin read/write access\n\nIn this example, we create a two related models, which will use which logged in users in the 'Author' and 'Admin' user groups will have\nfull access to, and customers requesting with api key will only have read permissions on.\n\n```ts\nimport { App, Stack } from 'aws-cdk-lib';\nimport { UserPool } from 'aws-cdk-lib/aws-cognito';\nimport { AmplifyGraphqlApi, AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct';\n\nconst app = new App();\nconst stack = new Stack(app, 'BlogStack');\n\nnew AmplifyGraphqlApi(stack, 'BlogApp', {\n definition: AmplifyGraphqlDefinition.fromString(/* GraphQL */ `\n type Blog @model @auth(rules: [{ allow: public, operations: [read] }, { allow: groups, groups: [\"Author\", \"Admin\"] }]) {\n title: String!\n description: String\n posts: [Post] @hasMany\n }\n\n type Post @model @auth(rules: [{ allow: public, operations: [read] }, { allow: groups, groups: [\"Author\", \"Admin\"] }]) {\n title: String!\n content: [String]\n blog: Blog @belongsTo\n }\n `),\n authorizationModes: {\n defaultAuthorizationMode: 'API_KEY',\n apiKeyConfig: {\n description: 'Api Key for public access',\n expires: cdk.Duration.days(7),\n },\n userPoolConfig: {\n userPool: UserPool.fromUserPoolId(stack, 'ImportedUserPool', ''),\n },\n },\n});\n```\n\n### Import GraphQL Schema from files, instead of inline\n\nIn this example, we import the schema definition itself from one or more local files, rather than an inline graphql string.\n\n```graphql\n# todo.graphql\ntype Todo @model @auth(rules: [{ allow: owner }]) {\n content: String!\n done: Boolean\n}\n```\n\n```graphql\n# blog.graphql\ntype Blog @model @auth(rules: [{ allow: owner }, { allow: public, operations: [read] }]) {\n title: String!\n description: String\n posts: [Post] @hasMany\n}\n\ntype Post @model @auth(rules: [{ allow: owner }, { allow: public, operations: [read] }]) {\n title: String!\n content: [String]\n blog: Blog @belongsTo\n}\n```\n\n```ts\n// app.ts\nimport { App, Stack } from 'aws-cdk-lib';\nimport { UserPool } from 'aws-cdk-lib/aws-cognito';\nimport { AmplifyGraphqlApi, AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct';\n\nconst app = new App();\nconst stack = new Stack(app, 'MultiFileStack');\n\nnew AmplifyGraphqlApi(stack, 'MultiFileDefinition', {\n definition: AmplifyGraphqlDefinition.fromFiles(path.join(__dirname, 'todo.graphql'), path.join(__dirname, 'blog.graphql')),\n authorizationModes: {\n defaultAuthorizationMode: 'API_KEY',\n apiKeyConfig: {\n description: 'Api Key for public access',\n expires: cdk.Duration.days(7),\n },\n userPoolConfig: {\n userPool: UserPool.fromUserPoolId(stack, 'ImportedUserPool', ''),\n },\n },\n});\n```\n\n# API Reference \n\n## Constructs \n\n### AmplifyGraphqlApi \n\nL3 Construct which invokes the Amplify Transformer Pattern over an input Graphql Schema.\n\nThis can be used to quickly define appsync apis which support full CRUD+List and Subscriptions, relationships,\nauth, search over data, the ability to inject custom business logic and query/mutation operations, and connect to ML services.\n\nFor more information, refer to the docs links below:\nData Modeling - https://docs.amplify.aws/cli/graphql/data-modeling/\nAuthorization - https://docs.amplify.aws/cli/graphql/authorization-rules/\nCustom Business Logic - https://docs.amplify.aws/cli/graphql/custom-business-logic/\nSearch - https://docs.amplify.aws/cli/graphql/search-and-result-aggregations/\nML Services - https://docs.amplify.aws/cli/graphql/connect-to-machine-learning-services/\n\nFor a full reference of the supported custom graphql directives - https://docs.amplify.aws/cli/graphql/directives-reference/\n\nThe output of this construct is a mapping of L2 or L1 resources generated by the transformer, which generally follow the access pattern\n\n```typescript\n const api = new AmplifyGraphQlApi(this, 'api', { });\n // Access L2 resources under `.resources`\n api.resources.tables[\"Todo\"].tableArn;\n\n // Access L1 resources under `.resources.cfnResources`\n api.resources.cfnResources.cfnGraphqlApi.xrayEnabled = true;\n Object.values(api.resources.cfnResources.cfnTables).forEach(table => {\n table.pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: false };\n });\n```\n`resources..` - you can then perform any CDK action on these resulting resoureces.\n\n#### Initializers \n\n```typescript\nimport { AmplifyGraphqlApi } from '@aws-amplify/graphql-api-construct'\n\nnew AmplifyGraphqlApi(scope: Construct, id: string, props: AmplifyGraphqlApiProps)\n```\n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| scope | constructs.Construct | the scope to create this construct within. |\n| id | string | the id to use for this api. |\n| props | AmplifyGraphqlApiProps | the properties used to configure the generated api. |\n\n---\n\n##### `scope`Required \n\n- *Type:* constructs.Construct\n\nthe scope to create this construct within.\n\n---\n\n##### `id`Required \n\n- *Type:* string\n\nthe id to use for this api.\n\n---\n\n##### `props`Required \n\n- *Type:* AmplifyGraphqlApiProps\n\nthe properties used to configure the generated api.\n\n---\n\n#### Methods \n\n| **Name** | **Description** |\n| --- | --- |\n| toString | Returns a string representation of this construct. |\n| addDynamoDbDataSource | Add a new DynamoDB data source to this API. |\n| addElasticsearchDataSource | Add a new elasticsearch data source to this API. |\n| addEventBridgeDataSource | Add an EventBridge data source to this api. |\n| addFunction | Add an appsync function to the api. |\n| addHttpDataSource | Add a new http data source to this API. |\n| addLambdaDataSource | Add a new Lambda data source to this API. |\n| addNoneDataSource | Add a new dummy data source to this API. |\n| addOpenSearchDataSource | dd a new OpenSearch data source to this API. |\n| addRdsDataSource | Add a new Rds data source to this API. |\n| addResolver | Add a resolver to the api. |\n\n---\n\n##### `toString` \n\n```typescript\npublic toString(): string\n```\n\nReturns a string representation of this construct.\n\n##### `addDynamoDbDataSource` \n\n```typescript\npublic addDynamoDbDataSource(id: string, table: ITable, options?: DataSourceOptions): DynamoDbDataSource\n```\n\nAdd a new DynamoDB data source to this API.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `table`Required \n\n- *Type:* aws-cdk-lib.aws_dynamodb.ITable\n\nThe DynamoDB table backing this data source.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.DataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### ~~`addElasticsearchDataSource`~~ \n\n```typescript\npublic addElasticsearchDataSource(id: string, domain: IDomain, options?: DataSourceOptions): ElasticsearchDataSource\n```\n\nAdd a new elasticsearch data source to this API.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `domain`Required \n\n- *Type:* aws-cdk-lib.aws_elasticsearch.IDomain\n\nThe elasticsearch domain for this data source.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.DataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### `addEventBridgeDataSource` \n\n```typescript\npublic addEventBridgeDataSource(id: string, eventBus: IEventBus, options?: DataSourceOptions): EventBridgeDataSource\n```\n\nAdd an EventBridge data source to this api.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `eventBus`Required \n\n- *Type:* aws-cdk-lib.aws_events.IEventBus\n\nThe EventBridge EventBus on which to put events.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.DataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### `addFunction` \n\n```typescript\npublic addFunction(id: string, props: AddFunctionProps): AppsyncFunction\n```\n\nAdd an appsync function to the api.\n\n###### `id`Required \n\n- *Type:* string\n\nthe function's id.\n\n---\n\n###### `props`Required \n\n- *Type:* AddFunctionProps\n\n---\n\n##### `addHttpDataSource` \n\n```typescript\npublic addHttpDataSource(id: string, endpoint: string, options?: HttpDataSourceOptions): HttpDataSource\n```\n\nAdd a new http data source to this API.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `endpoint`Required \n\n- *Type:* string\n\nThe http endpoint.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.HttpDataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### `addLambdaDataSource` \n\n```typescript\npublic addLambdaDataSource(id: string, lambdaFunction: IFunction, options?: DataSourceOptions): LambdaDataSource\n```\n\nAdd a new Lambda data source to this API.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `lambdaFunction`Required \n\n- *Type:* aws-cdk-lib.aws_lambda.IFunction\n\nThe Lambda function to call to interact with this data source.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.DataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### `addNoneDataSource` \n\n```typescript\npublic addNoneDataSource(id: string, options?: DataSourceOptions): NoneDataSource\n```\n\nAdd a new dummy data source to this API.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\nUseful for pipeline resolvers and for backend changes that don't require a data source.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.DataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### `addOpenSearchDataSource` \n\n```typescript\npublic addOpenSearchDataSource(id: string, domain: IDomain, options?: DataSourceOptions): OpenSearchDataSource\n```\n\ndd a new OpenSearch data source to this API.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `domain`Required \n\n- *Type:* aws-cdk-lib.aws_opensearchservice.IDomain\n\nThe OpenSearch domain for this data source.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.DataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### `addRdsDataSource` \n\n```typescript\npublic addRdsDataSource(id: string, serverlessCluster: IServerlessCluster, secretStore: ISecret, databaseName?: string, options?: DataSourceOptions): RdsDataSource\n```\n\nAdd a new Rds data source to this API.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe data source's id.\n\n---\n\n###### `serverlessCluster`Required \n\n- *Type:* aws-cdk-lib.aws_rds.IServerlessCluster\n\nThe serverless cluster to interact with this data source.\n\n---\n\n###### `secretStore`Required \n\n- *Type:* aws-cdk-lib.aws_secretsmanager.ISecret\n\nThe secret store that contains the username and password for the serverless cluster.\n\n---\n\n###### `databaseName`Optional \n\n- *Type:* string\n\nThe optional name of the database to use within the cluster.\n\n---\n\n###### `options`Optional \n\n- *Type:* aws-cdk-lib.aws_appsync.DataSourceOptions\n\nThe optional configuration for this data source.\n\n---\n\n##### `addResolver` \n\n```typescript\npublic addResolver(id: string, props: ExtendedResolverProps): Resolver\n```\n\nAdd a resolver to the api.\n\nThis is a proxy method to the L2 GraphqlApi Construct.\n\n###### `id`Required \n\n- *Type:* string\n\nThe resolver's id.\n\n---\n\n###### `props`Required \n\n- *Type:* aws-cdk-lib.aws_appsync.ExtendedResolverProps\n\nthe resolver properties.\n\n---\n\n#### Static Functions \n\n| **Name** | **Description** |\n| --- | --- |\n| isConstruct | Checks if `x` is a construct. |\n\n---\n\n##### ~~`isConstruct`~~ \n\n```typescript\nimport { AmplifyGraphqlApi } from '@aws-amplify/graphql-api-construct'\n\nAmplifyGraphqlApi.isConstruct(x: any)\n```\n\nChecks if `x` is a construct.\n\n###### `x`Required \n\n- *Type:* any\n\nAny object.\n\n---\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| node | constructs.Node | The tree node. |\n| apiId | string | Generated Api Id. |\n| generatedFunctionSlots | MutationFunctionSlot \\| QueryFunctionSlot \\| SubscriptionFunctionSlot[] | Resolvers generated by the transform process, persisted on the side in order to facilitate pulling a manifest for the purposes of inspecting and producing overrides. |\n| graphqlUrl | string | Graphql URL For the generated API. |\n| realtimeUrl | string | Realtime URL For the generated API. |\n| resources | AmplifyGraphqlApiResources | Generated L1 and L2 CDK resources. |\n| apiKey | string | Generated Api Key if generated. |\n\n---\n\n##### `node`Required \n\n```typescript\npublic readonly node: Node;\n```\n\n- *Type:* constructs.Node\n\nThe tree node.\n\n---\n\n##### `apiId`Required \n\n```typescript\npublic readonly apiId: string;\n```\n\n- *Type:* string\n\nGenerated Api Id.\n\nMay be a CDK Token.\n\n---\n\n##### `generatedFunctionSlots`Required \n\n```typescript\npublic readonly generatedFunctionSlots: MutationFunctionSlot | QueryFunctionSlot | SubscriptionFunctionSlot[];\n```\n\n- *Type:* MutationFunctionSlot | QueryFunctionSlot | SubscriptionFunctionSlot[]\n\nResolvers generated by the transform process, persisted on the side in order to facilitate pulling a manifest for the purposes of inspecting and producing overrides.\n\n---\n\n##### `graphqlUrl`Required \n\n```typescript\npublic readonly graphqlUrl: string;\n```\n\n- *Type:* string\n\nGraphql URL For the generated API.\n\nMay be a CDK Token.\n\n---\n\n##### `realtimeUrl`Required \n\n```typescript\npublic readonly realtimeUrl: string;\n```\n\n- *Type:* string\n\nRealtime URL For the generated API.\n\nMay be a CDK Token.\n\n---\n\n##### `resources`Required \n\n```typescript\npublic readonly resources: AmplifyGraphqlApiResources;\n```\n\n- *Type:* AmplifyGraphqlApiResources\n\nGenerated L1 and L2 CDK resources.\n\n---\n\n##### `apiKey`Optional \n\n```typescript\npublic readonly apiKey: string;\n```\n\n- *Type:* string\n\nGenerated Api Key if generated.\n\nMay be a CDK Token.\n\n---\n\n\n## Structs \n\n### AddFunctionProps \n\nInput type properties when adding a new appsync.AppsyncFunction to the generated API. This is equivalent to the Omit.\n\n#### Initializer \n\n```typescript\nimport { AddFunctionProps } from '@aws-amplify/graphql-api-construct'\n\nconst addFunctionProps: AddFunctionProps = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| dataSource | aws-cdk-lib.aws_appsync.BaseDataSource | the data source linked to this AppSync Function. |\n| name | string | the name of the AppSync Function. |\n| code | aws-cdk-lib.aws_appsync.Code | The function code. |\n| description | string | the description for this AppSync Function. |\n| requestMappingTemplate | aws-cdk-lib.aws_appsync.MappingTemplate | the request mapping template for the AppSync Function. |\n| responseMappingTemplate | aws-cdk-lib.aws_appsync.MappingTemplate | the response mapping template for the AppSync Function. |\n| runtime | aws-cdk-lib.aws_appsync.FunctionRuntime | The functions runtime. |\n\n---\n\n##### `dataSource`Required \n\n```typescript\npublic readonly dataSource: BaseDataSource;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.BaseDataSource\n\nthe data source linked to this AppSync Function.\n\n---\n\n##### `name`Required \n\n```typescript\npublic readonly name: string;\n```\n\n- *Type:* string\n\nthe name of the AppSync Function.\n\n---\n\n##### `code`Optional \n\n```typescript\npublic readonly code: Code;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.Code\n- *Default:* no code is used\n\nThe function code.\n\n---\n\n##### `description`Optional \n\n```typescript\npublic readonly description: string;\n```\n\n- *Type:* string\n- *Default:* no description\n\nthe description for this AppSync Function.\n\n---\n\n##### `requestMappingTemplate`Optional \n\n```typescript\npublic readonly requestMappingTemplate: MappingTemplate;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.MappingTemplate\n- *Default:* no request mapping template\n\nthe request mapping template for the AppSync Function.\n\n---\n\n##### `responseMappingTemplate`Optional \n\n```typescript\npublic readonly responseMappingTemplate: MappingTemplate;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.MappingTemplate\n- *Default:* no response mapping template\n\nthe response mapping template for the AppSync Function.\n\n---\n\n##### `runtime`Optional \n\n```typescript\npublic readonly runtime: FunctionRuntime;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.FunctionRuntime\n- *Default:* no function runtime, VTL mapping templates used\n\nThe functions runtime.\n\n---\n\n### AmplifyDynamoDbModelDataSourceStrategy \n\nUse custom resource type 'Custom::AmplifyDynamoDBTable' to provision table.\n\n#### Initializer \n\n```typescript\nimport { AmplifyDynamoDbModelDataSourceStrategy } from '@aws-amplify/graphql-api-construct'\n\nconst amplifyDynamoDbModelDataSourceStrategy: AmplifyDynamoDbModelDataSourceStrategy = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| dbType | string | *No description.* |\n| provisionStrategy | string | *No description.* |\n\n---\n\n##### `dbType`Required \n\n```typescript\npublic readonly dbType: string;\n```\n\n- *Type:* string\n\n---\n\n##### `provisionStrategy`Required \n\n```typescript\npublic readonly provisionStrategy: string;\n```\n\n- *Type:* string\n\n---\n\n### AmplifyGraphqlApiCfnResources \n\nL1 CDK resources from the Api which were generated as part of the transform.\n\nThese are potentially stored under nested stacks, but presented organized by type instead.\n\n#### Initializer \n\n```typescript\nimport { AmplifyGraphqlApiCfnResources } from '@aws-amplify/graphql-api-construct'\n\nconst amplifyGraphqlApiCfnResources: AmplifyGraphqlApiCfnResources = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| additionalCfnResources | {[ key: string ]: aws-cdk-lib.CfnResource} | Remaining L1 resources generated, keyed by logicalId. |\n| amplifyDynamoDbTables | {[ key: string ]: AmplifyDynamoDbTableWrapper} | The Generated Amplify DynamoDb Table L1 resource wrapper, keyed by model type name. |\n| cfnDataSources | {[ key: string ]: aws-cdk-lib.aws_appsync.CfnDataSource} | The Generated AppSync DataSource L1 Resources, keyed by logicalId. |\n| cfnFunctionConfigurations | {[ key: string ]: aws-cdk-lib.aws_appsync.CfnFunctionConfiguration} | The Generated AppSync Function L1 Resources, keyed by logicalId. |\n| cfnFunctions | {[ key: string ]: aws-cdk-lib.aws_lambda.CfnFunction} | The Generated Lambda Function L1 Resources, keyed by function name. |\n| cfnGraphqlApi | aws-cdk-lib.aws_appsync.CfnGraphQLApi | The Generated AppSync Api L1 Resource. |\n| cfnGraphqlSchema | aws-cdk-lib.aws_appsync.CfnGraphQLSchema | The Generated AppSync Schema L1 Resource. |\n| cfnResolvers | {[ key: string ]: aws-cdk-lib.aws_appsync.CfnResolver} | The Generated AppSync Resolver L1 Resources, keyed by logicalId. |\n| cfnRoles | {[ key: string ]: aws-cdk-lib.aws_iam.CfnRole} | The Generated IAM Role L1 Resources, keyed by logicalId. |\n| cfnTables | {[ key: string ]: aws-cdk-lib.aws_dynamodb.CfnTable} | The Generated DynamoDB Table L1 Resources, keyed by logicalId. |\n| cfnApiKey | aws-cdk-lib.aws_appsync.CfnApiKey | The Generated AppSync Api Key L1 Resource. |\n\n---\n\n##### `additionalCfnResources`Required \n\n```typescript\npublic readonly additionalCfnResources: {[ key: string ]: CfnResource};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.CfnResource}\n\nRemaining L1 resources generated, keyed by logicalId.\n\n---\n\n##### `amplifyDynamoDbTables`Required \n\n```typescript\npublic readonly amplifyDynamoDbTables: {[ key: string ]: AmplifyDynamoDbTableWrapper};\n```\n\n- *Type:* {[ key: string ]: AmplifyDynamoDbTableWrapper}\n\nThe Generated Amplify DynamoDb Table L1 resource wrapper, keyed by model type name.\n\n---\n\n##### `cfnDataSources`Required \n\n```typescript\npublic readonly cfnDataSources: {[ key: string ]: CfnDataSource};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_appsync.CfnDataSource}\n\nThe Generated AppSync DataSource L1 Resources, keyed by logicalId.\n\n---\n\n##### `cfnFunctionConfigurations`Required \n\n```typescript\npublic readonly cfnFunctionConfigurations: {[ key: string ]: CfnFunctionConfiguration};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_appsync.CfnFunctionConfiguration}\n\nThe Generated AppSync Function L1 Resources, keyed by logicalId.\n\n---\n\n##### `cfnFunctions`Required \n\n```typescript\npublic readonly cfnFunctions: {[ key: string ]: CfnFunction};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_lambda.CfnFunction}\n\nThe Generated Lambda Function L1 Resources, keyed by function name.\n\n---\n\n##### `cfnGraphqlApi`Required \n\n```typescript\npublic readonly cfnGraphqlApi: CfnGraphQLApi;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.CfnGraphQLApi\n\nThe Generated AppSync Api L1 Resource.\n\n---\n\n##### `cfnGraphqlSchema`Required \n\n```typescript\npublic readonly cfnGraphqlSchema: CfnGraphQLSchema;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.CfnGraphQLSchema\n\nThe Generated AppSync Schema L1 Resource.\n\n---\n\n##### `cfnResolvers`Required \n\n```typescript\npublic readonly cfnResolvers: {[ key: string ]: CfnResolver};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_appsync.CfnResolver}\n\nThe Generated AppSync Resolver L1 Resources, keyed by logicalId.\n\n---\n\n##### `cfnRoles`Required \n\n```typescript\npublic readonly cfnRoles: {[ key: string ]: CfnRole};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_iam.CfnRole}\n\nThe Generated IAM Role L1 Resources, keyed by logicalId.\n\n---\n\n##### `cfnTables`Required \n\n```typescript\npublic readonly cfnTables: {[ key: string ]: CfnTable};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_dynamodb.CfnTable}\n\nThe Generated DynamoDB Table L1 Resources, keyed by logicalId.\n\n---\n\n##### `cfnApiKey`Optional \n\n```typescript\npublic readonly cfnApiKey: CfnApiKey;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.CfnApiKey\n\nThe Generated AppSync Api Key L1 Resource.\n\n---\n\n### AmplifyGraphqlApiProps \n\nInput props for the AmplifyGraphqlApi construct.\n\nSpecifies what the input to transform into an Api, and configurations for\nthe transformation process.\n\n#### Initializer \n\n```typescript\nimport { AmplifyGraphqlApiProps } from '@aws-amplify/graphql-api-construct'\n\nconst amplifyGraphqlApiProps: AmplifyGraphqlApiProps = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| authorizationModes | AuthorizationModes | Required auth modes for the Api. |\n| definition | IAmplifyGraphqlDefinition | The definition to transform in a full Api. |\n| apiName | string | Name to be used for the AppSync Api. |\n| conflictResolution | ConflictResolution | Configure conflict resolution on the Api, which is required to enable DataStore Api functionality. |\n| dataStoreConfiguration | DataStoreConfiguration | Configure DataStore conflict resolution on the Api. |\n| disableOutputStorage | boolean | Disables storing construct output. |\n| functionNameMap | {[ key: string ]: aws-cdk-lib.aws_lambda.IFunction} | Lambda functions referenced in the definitions's. |\n| functionSlots | MutationFunctionSlot \\| QueryFunctionSlot \\| SubscriptionFunctionSlot[] | Overrides for a given slot in the generated resolver pipelines. |\n| outputStorageStrategy | IBackendOutputStorageStrategy | Strategy to store construct outputs. |\n| predictionsBucket | aws-cdk-lib.aws_s3.IBucket | If using predictions, a bucket must be provided which will be used to search for assets. |\n| stackMappings | {[ key: string ]: string} | StackMappings override the assigned nested stack on a per-resource basis. |\n| transformerPlugins | any[] | Provide a list of additional custom transformers which are injected into the transform process. |\n| translationBehavior | PartialTranslationBehavior | This replaces feature flags from the Api construct, for general information on what these parameters do, refer to https://docs.amplify.aws/cli/reference/feature-flags/#graphQLTransformer. |\n\n---\n\n##### `authorizationModes`Required \n\n```typescript\npublic readonly authorizationModes: AuthorizationModes;\n```\n\n- *Type:* AuthorizationModes\n\nRequired auth modes for the Api.\n\nThis object must be a superset of the configured auth providers in the Api definition.\nFor more information, refer to https://docs.amplify.aws/cli/graphql/authorization-rules/\n\n---\n\n##### `definition`Required \n\n```typescript\npublic readonly definition: IAmplifyGraphqlDefinition;\n```\n\n- *Type:* IAmplifyGraphqlDefinition\n\nThe definition to transform in a full Api.\n\nCan be constructed via the AmplifyGraphqlDefinition class.\n\n---\n\n##### `apiName`Optional \n\n```typescript\npublic readonly apiName: string;\n```\n\n- *Type:* string\n\nName to be used for the AppSync Api.\n\nDefault: construct id.\n\n---\n\n##### ~~`conflictResolution`~~Optional \n\n- *Deprecated:* use dataStoreConfiguration instead.\n\n```typescript\npublic readonly conflictResolution: ConflictResolution;\n```\n\n- *Type:* ConflictResolution\n\nConfigure conflict resolution on the Api, which is required to enable DataStore Api functionality.\n\nFor more information, refer to https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js/\n\n---\n\n##### `dataStoreConfiguration`Optional \n\n```typescript\npublic readonly dataStoreConfiguration: DataStoreConfiguration;\n```\n\n- *Type:* DataStoreConfiguration\n\nConfigure DataStore conflict resolution on the Api.\n\nConflict resolution is required to enable DataStore Api functionality.\nFor more information, refer to https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js/\n\n---\n\n##### `disableOutputStorage`Optional \n\n```typescript\npublic readonly disableOutputStorage: boolean;\n```\n\n- *Type:* boolean\n\nDisables storing construct output.\n\nOutput storage should be disabled when creating multiple GraphQL APIs in a single CDK synthesis.\noutputStorageStrategy will be ignored if this is set to true.\n\n---\n\n##### `functionNameMap`Optional \n\n```typescript\npublic readonly functionNameMap: {[ key: string ]: IFunction};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_lambda.IFunction}\n\nLambda functions referenced in the definitions's.\n\n---\n\n##### `functionSlots`Optional \n\n```typescript\npublic readonly functionSlots: MutationFunctionSlot | QueryFunctionSlot | SubscriptionFunctionSlot[];\n```\n\n- *Type:* MutationFunctionSlot | QueryFunctionSlot | SubscriptionFunctionSlot[]\n\nOverrides for a given slot in the generated resolver pipelines.\n\nFor more information about what slots are available,\nrefer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#override-amplify-generated-resolvers.\n\n---\n\n##### `outputStorageStrategy`Optional \n\n```typescript\npublic readonly outputStorageStrategy: IBackendOutputStorageStrategy;\n```\n\n- *Type:* IBackendOutputStorageStrategy\n\nStrategy to store construct outputs.\n\nIf no outputStorageStrategey is provided a default strategy will be used.\n\n---\n\n##### `predictionsBucket`Optional \n\n```typescript\npublic readonly predictionsBucket: IBucket;\n```\n\n- *Type:* aws-cdk-lib.aws_s3.IBucket\n\nIf using predictions, a bucket must be provided which will be used to search for assets.\n\n---\n\n##### `stackMappings`Optional \n\n```typescript\npublic readonly stackMappings: {[ key: string ]: string};\n```\n\n- *Type:* {[ key: string ]: string}\n\nStackMappings override the assigned nested stack on a per-resource basis.\n\nOnly applies to resolvers, and takes the form\n{ : }\nIt is not recommended to use this parameter unless you are encountering stack resource count limits, and worth noting that\nafter initial deployment AppSync resolvers cannot be moved between nested stacks, they will need to be removed from the app,\nthen re-added from a new stack.\n\n---\n\n##### `transformerPlugins`Optional \n\n```typescript\npublic readonly transformerPlugins: any[];\n```\n\n- *Type:* any[]\n\nProvide a list of additional custom transformers which are injected into the transform process.\n\nThese custom transformers must be implemented with aws-cdk-lib >=2.80.0, and\n\n---\n\n##### `translationBehavior`Optional \n\n```typescript\npublic readonly translationBehavior: PartialTranslationBehavior;\n```\n\n- *Type:* PartialTranslationBehavior\n\nThis replaces feature flags from the Api construct, for general information on what these parameters do, refer to https://docs.amplify.aws/cli/reference/feature-flags/#graphQLTransformer.\n\n---\n\n### AmplifyGraphqlApiResources \n\nAccessible resources from the Api which were generated as part of the transform.\n\nThese are potentially stored under nested stacks, but presented organized by type instead.\n\n#### Initializer \n\n```typescript\nimport { AmplifyGraphqlApiResources } from '@aws-amplify/graphql-api-construct'\n\nconst amplifyGraphqlApiResources: AmplifyGraphqlApiResources = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| cfnResources | AmplifyGraphqlApiCfnResources | L1 Cfn Resources, for when dipping down a level of abstraction is desirable. |\n| functions | {[ key: string ]: aws-cdk-lib.aws_lambda.IFunction} | The Generated Lambda Function L1 Resources, keyed by function name. |\n| graphqlApi | aws-cdk-lib.aws_appsync.IGraphqlApi | The Generated AppSync Api L2 Resource, includes the Schema. |\n| nestedStacks | {[ key: string ]: aws-cdk-lib.NestedStack} | Nested Stacks generated by the Api Construct. |\n| roles | {[ key: string ]: aws-cdk-lib.aws_iam.IRole} | The Generated IAM Role L2 Resources, keyed by logicalId. |\n| tables | {[ key: string ]: aws-cdk-lib.aws_dynamodb.ITable} | The Generated DynamoDB Table L2 Resources, keyed by logicalId. |\n\n---\n\n##### `cfnResources`Required \n\n```typescript\npublic readonly cfnResources: AmplifyGraphqlApiCfnResources;\n```\n\n- *Type:* AmplifyGraphqlApiCfnResources\n\nL1 Cfn Resources, for when dipping down a level of abstraction is desirable.\n\n---\n\n##### `functions`Required \n\n```typescript\npublic readonly functions: {[ key: string ]: IFunction};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_lambda.IFunction}\n\nThe Generated Lambda Function L1 Resources, keyed by function name.\n\n---\n\n##### `graphqlApi`Required \n\n```typescript\npublic readonly graphqlApi: IGraphqlApi;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.IGraphqlApi\n\nThe Generated AppSync Api L2 Resource, includes the Schema.\n\n---\n\n##### `nestedStacks`Required \n\n```typescript\npublic readonly nestedStacks: {[ key: string ]: NestedStack};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.NestedStack}\n\nNested Stacks generated by the Api Construct.\n\n---\n\n##### `roles`Required \n\n```typescript\npublic readonly roles: {[ key: string ]: IRole};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_iam.IRole}\n\nThe Generated IAM Role L2 Resources, keyed by logicalId.\n\n---\n\n##### `tables`Required \n\n```typescript\npublic readonly tables: {[ key: string ]: ITable};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_dynamodb.ITable}\n\nThe Generated DynamoDB Table L2 Resources, keyed by logicalId.\n\n---\n\n### ApiKeyAuthorizationConfig \n\nConfiguration for Api Keys on the Graphql Api.\n\n#### Initializer \n\n```typescript\nimport { ApiKeyAuthorizationConfig } from '@aws-amplify/graphql-api-construct'\n\nconst apiKeyAuthorizationConfig: ApiKeyAuthorizationConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| expires | aws-cdk-lib.Duration | A duration representing the time from Cloudformation deploy until expiry. |\n| description | string | Optional description for the Api Key to attach to the Api. |\n\n---\n\n##### `expires`Required \n\n```typescript\npublic readonly expires: Duration;\n```\n\n- *Type:* aws-cdk-lib.Duration\n\nA duration representing the time from Cloudformation deploy until expiry.\n\n---\n\n##### `description`Optional \n\n```typescript\npublic readonly description: string;\n```\n\n- *Type:* string\n\nOptional description for the Api Key to attach to the Api.\n\n---\n\n### AuthorizationModes \n\nAuthorization Modes to apply to the Api.\n\nAt least one modes must be provided, and if more than one are provided a defaultAuthorizationMode must be specified.\nFor more information on Amplify Api auth, refer to https://docs.amplify.aws/cli/graphql/authorization-rules/#authorization-strategies\n\n#### Initializer \n\n```typescript\nimport { AuthorizationModes } from '@aws-amplify/graphql-api-construct'\n\nconst authorizationModes: AuthorizationModes = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| adminRoles | aws-cdk-lib.aws_iam.IRole[] | A list of roles granted full R/W access to the Api. |\n| apiKeyConfig | ApiKeyAuthorizationConfig | AppSync Api Key config, required if a 'apiKey' auth provider is specified in the Api. |\n| defaultAuthorizationMode | string | Default auth mode to provide to the Api, required if more than one config type is specified. |\n| iamConfig | IAMAuthorizationConfig | IAM Auth config, required if an 'iam' auth provider is specified in the Api. |\n| lambdaConfig | LambdaAuthorizationConfig | Lambda config, required if a 'function' auth provider is specified in the Api. |\n| oidcConfig | OIDCAuthorizationConfig | Cognito OIDC config, required if a 'oidc' auth provider is specified in the Api. |\n| userPoolConfig | UserPoolAuthorizationConfig | Cognito UserPool config, required if a 'userPools' auth provider is specified in the Api. |\n\n---\n\n##### ~~`adminRoles`~~Optional \n\n- *Deprecated:* , use iamConfig.allowListedRoles instead.\n\n```typescript\npublic readonly adminRoles: IRole[];\n```\n\n- *Type:* aws-cdk-lib.aws_iam.IRole[]\n\nA list of roles granted full R/W access to the Api.\n\n---\n\n##### `apiKeyConfig`Optional \n\n```typescript\npublic readonly apiKeyConfig: ApiKeyAuthorizationConfig;\n```\n\n- *Type:* ApiKeyAuthorizationConfig\n\nAppSync Api Key config, required if a 'apiKey' auth provider is specified in the Api.\n\nApplies to 'public' auth strategy.\n\n---\n\n##### `defaultAuthorizationMode`Optional \n\n```typescript\npublic readonly defaultAuthorizationMode: string;\n```\n\n- *Type:* string\n\nDefault auth mode to provide to the Api, required if more than one config type is specified.\n\n---\n\n##### `iamConfig`Optional \n\n```typescript\npublic readonly iamConfig: IAMAuthorizationConfig;\n```\n\n- *Type:* IAMAuthorizationConfig\n\nIAM Auth config, required if an 'iam' auth provider is specified in the Api.\n\nApplies to 'public' and 'private' auth strategies.\n\n---\n\n##### `lambdaConfig`Optional \n\n```typescript\npublic readonly lambdaConfig: LambdaAuthorizationConfig;\n```\n\n- *Type:* LambdaAuthorizationConfig\n\nLambda config, required if a 'function' auth provider is specified in the Api.\n\nApplies to 'custom' auth strategy.\n\n---\n\n##### `oidcConfig`Optional \n\n```typescript\npublic readonly oidcConfig: OIDCAuthorizationConfig;\n```\n\n- *Type:* OIDCAuthorizationConfig\n\nCognito OIDC config, required if a 'oidc' auth provider is specified in the Api.\n\nApplies to 'owner', 'private', and 'group' auth strategies.\n\n---\n\n##### `userPoolConfig`Optional \n\n```typescript\npublic readonly userPoolConfig: UserPoolAuthorizationConfig;\n```\n\n- *Type:* UserPoolAuthorizationConfig\n\nCognito UserPool config, required if a 'userPools' auth provider is specified in the Api.\n\nApplies to 'owner', 'private', and 'group' auth strategies.\n\n---\n\n### AutomergeConflictResolutionStrategy \n\nEnable optimistic concurrency on the project.\n\n#### Initializer \n\n```typescript\nimport { AutomergeConflictResolutionStrategy } from '@aws-amplify/graphql-api-construct'\n\nconst automergeConflictResolutionStrategy: AutomergeConflictResolutionStrategy = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| detectionType | string | The conflict detection type used for resolution. |\n| handlerType | string | This conflict resolution strategy executes an auto-merge. |\n\n---\n\n##### `detectionType`Required \n\n```typescript\npublic readonly detectionType: string;\n```\n\n- *Type:* string\n\nThe conflict detection type used for resolution.\n\n---\n\n##### `handlerType`Required \n\n```typescript\npublic readonly handlerType: string;\n```\n\n- *Type:* string\n\nThis conflict resolution strategy executes an auto-merge.\n\nFor more information, refer to https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html#conflict-detection-and-resolution\n\n---\n\n### ConflictResolution \n\nProject level configuration for conflict resolution.\n\n#### Initializer \n\n```typescript\nimport { ConflictResolution } from '@aws-amplify/graphql-api-construct'\n\nconst conflictResolution: ConflictResolution = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| models | {[ key: string ]: AutomergeConflictResolutionStrategy \\| OptimisticConflictResolutionStrategy \\| CustomConflictResolutionStrategy} | Model-specific conflict resolution overrides. |\n| project | AutomergeConflictResolutionStrategy \\| OptimisticConflictResolutionStrategy \\| CustomConflictResolutionStrategy | Project-wide config for conflict resolution. |\n\n---\n\n##### ~~`models`~~Optional \n\n- *Deprecated:* use DataStoreConfiguration instead.\n\n```typescript\npublic readonly models: {[ key: string ]: AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy};\n```\n\n- *Type:* {[ key: string ]: AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy}\n\nModel-specific conflict resolution overrides.\n\n---\n\n##### ~~`project`~~Optional \n\n- *Deprecated:* use DataStoreConfiguration instead.\n\n```typescript\npublic readonly project: AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy;\n```\n\n- *Type:* AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy\n\nProject-wide config for conflict resolution.\n\nApplies to all non-overridden models.\n\n---\n\n### ConflictResolutionStrategyBase \n\nCommon parameters for conflict resolution.\n\n#### Initializer \n\n```typescript\nimport { ConflictResolutionStrategyBase } from '@aws-amplify/graphql-api-construct'\n\nconst conflictResolutionStrategyBase: ConflictResolutionStrategyBase = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| detectionType | string | The conflict detection type used for resolution. |\n\n---\n\n##### `detectionType`Required \n\n```typescript\npublic readonly detectionType: string;\n```\n\n- *Type:* string\n\nThe conflict detection type used for resolution.\n\n---\n\n### CustomConflictResolutionStrategy \n\nEnable custom sync on the project, powered by a lambda.\n\n#### Initializer \n\n```typescript\nimport { CustomConflictResolutionStrategy } from '@aws-amplify/graphql-api-construct'\n\nconst customConflictResolutionStrategy: CustomConflictResolutionStrategy = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| detectionType | string | The conflict detection type used for resolution. |\n| conflictHandler | aws-cdk-lib.aws_lambda.IFunction | The function which will be invoked for conflict resolution. |\n| handlerType | string | This conflict resolution strategy uses a lambda handler type. |\n\n---\n\n##### `detectionType`Required \n\n```typescript\npublic readonly detectionType: string;\n```\n\n- *Type:* string\n\nThe conflict detection type used for resolution.\n\n---\n\n##### `conflictHandler`Required \n\n```typescript\npublic readonly conflictHandler: IFunction;\n```\n\n- *Type:* aws-cdk-lib.aws_lambda.IFunction\n\nThe function which will be invoked for conflict resolution.\n\n---\n\n##### `handlerType`Required \n\n```typescript\npublic readonly handlerType: string;\n```\n\n- *Type:* string\n\nThis conflict resolution strategy uses a lambda handler type.\n\nFor more information, refer to https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html#conflict-detection-and-resolution\n\n---\n\n### CustomSqlDataSourceStrategy \n\nThe input type for defining a ModelDataSourceStrategy used to resolve a field annotated with a `@sql` directive.\n\nAlthough this is a\npublic type, you should rarely need to use this. The AmplifyGraphqlDefinition factory methods (e.g., `fromString`,\n`fromFilesAndStrategy`) will automatically construct this structure for you.\n\n#### Initializer \n\n```typescript\nimport { CustomSqlDataSourceStrategy } from '@aws-amplify/graphql-api-construct'\n\nconst customSqlDataSourceStrategy: CustomSqlDataSourceStrategy = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| fieldName | string | The field name with which the custom SQL is associated. |\n| strategy | SQLLambdaModelDataSourceStrategy | The strategy used to create the datasource that will resolve the custom SQL statement. |\n| typeName | string | The built-in type (either \"Query\" or \"Mutation\") with which the custom SQL is associated. |\n\n---\n\n##### `fieldName`Required \n\n```typescript\npublic readonly fieldName: string;\n```\n\n- *Type:* string\n\nThe field name with which the custom SQL is associated.\n\n---\n\n##### `strategy`Required \n\n```typescript\npublic readonly strategy: SQLLambdaModelDataSourceStrategy;\n```\n\n- *Type:* SQLLambdaModelDataSourceStrategy\n\nThe strategy used to create the datasource that will resolve the custom SQL statement.\n\n---\n\n##### `typeName`Required \n\n```typescript\npublic readonly typeName: string;\n```\n\n- *Type:* string\n\nThe built-in type (either \"Query\" or \"Mutation\") with which the custom SQL is associated.\n\n---\n\n### DataStoreConfiguration \n\nProject level configuration for DataStore.\n\n#### Initializer \n\n```typescript\nimport { DataStoreConfiguration } from '@aws-amplify/graphql-api-construct'\n\nconst dataStoreConfiguration: DataStoreConfiguration = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| models | {[ key: string ]: AutomergeConflictResolutionStrategy \\| OptimisticConflictResolutionStrategy \\| CustomConflictResolutionStrategy} | Model-specific conflict resolution overrides. |\n| project | AutomergeConflictResolutionStrategy \\| OptimisticConflictResolutionStrategy \\| CustomConflictResolutionStrategy | Project-wide config for conflict resolution. |\n\n---\n\n##### `models`Optional \n\n```typescript\npublic readonly models: {[ key: string ]: AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy};\n```\n\n- *Type:* {[ key: string ]: AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy}\n\nModel-specific conflict resolution overrides.\n\n---\n\n##### `project`Optional \n\n```typescript\npublic readonly project: AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy;\n```\n\n- *Type:* AutomergeConflictResolutionStrategy | OptimisticConflictResolutionStrategy | CustomConflictResolutionStrategy\n\nProject-wide config for conflict resolution.\n\nApplies to all non-overridden models.\n\n---\n\n### DefaultDynamoDbModelDataSourceStrategy \n\nUse default CloudFormation type 'AWS::DynamoDB::Table' to provision table.\n\n#### Initializer \n\n```typescript\nimport { DefaultDynamoDbModelDataSourceStrategy } from '@aws-amplify/graphql-api-construct'\n\nconst defaultDynamoDbModelDataSourceStrategy: DefaultDynamoDbModelDataSourceStrategy = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| dbType | string | *No description.* |\n| provisionStrategy | string | *No description.* |\n\n---\n\n##### `dbType`Required \n\n```typescript\npublic readonly dbType: string;\n```\n\n- *Type:* string\n\n---\n\n##### `provisionStrategy`Required \n\n```typescript\npublic readonly provisionStrategy: string;\n```\n\n- *Type:* string\n\n---\n\n### FunctionSlotBase \n\nCommon slot parameters.\n\n#### Initializer \n\n```typescript\nimport { FunctionSlotBase } from '@aws-amplify/graphql-api-construct'\n\nconst functionSlotBase: FunctionSlotBase = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| fieldName | string | The field to attach this function to on the Api definition. |\n| function | FunctionSlotOverride | The overridden behavior for this slot. |\n| slotIndex | number | The slot index to use to inject this into the execution pipeline. |\n\n---\n\n##### `fieldName`Required \n\n```typescript\npublic readonly fieldName: string;\n```\n\n- *Type:* string\n\nThe field to attach this function to on the Api definition.\n\n---\n\n##### `function`Required \n\n```typescript\npublic readonly function: FunctionSlotOverride;\n```\n\n- *Type:* FunctionSlotOverride\n\nThe overridden behavior for this slot.\n\n---\n\n##### `slotIndex`Required \n\n```typescript\npublic readonly slotIndex: number;\n```\n\n- *Type:* number\n\nThe slot index to use to inject this into the execution pipeline.\n\nFor more information on slotting, refer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#extend-amplify-generated-resolvers\n\n---\n\n### FunctionSlotOverride \n\nParams exposed to support configuring and overriding pipelined slots.\n\nThis allows configuration of the underlying function,\nincluding the request and response mapping templates.\n\n#### Initializer \n\n```typescript\nimport { FunctionSlotOverride } from '@aws-amplify/graphql-api-construct'\n\nconst functionSlotOverride: FunctionSlotOverride = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| requestMappingTemplate | aws-cdk-lib.aws_appsync.MappingTemplate | Override request mapping template for the function slot. |\n| responseMappingTemplate | aws-cdk-lib.aws_appsync.MappingTemplate | Override response mapping template for the function slot. |\n\n---\n\n##### `requestMappingTemplate`Optional \n\n```typescript\npublic readonly requestMappingTemplate: MappingTemplate;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.MappingTemplate\n\nOverride request mapping template for the function slot.\n\nExecuted before the datasource is invoked.\n\n---\n\n##### `responseMappingTemplate`Optional \n\n```typescript\npublic readonly responseMappingTemplate: MappingTemplate;\n```\n\n- *Type:* aws-cdk-lib.aws_appsync.MappingTemplate\n\nOverride response mapping template for the function slot.\n\nExecuted after the datasource is invoked.\n\n---\n\n### IAMAuthorizationConfig \n\nConfiguration for IAM Authorization on the Graphql Api.\n\n#### Initializer \n\n```typescript\nimport { IAMAuthorizationConfig } from '@aws-amplify/graphql-api-construct'\n\nconst iAMAuthorizationConfig: IAMAuthorizationConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| authenticatedUserRole | aws-cdk-lib.aws_iam.IRole | Authenticated user role, applies to { provider: iam, allow: private } access. |\n| identityPoolId | string | ID for the Cognito Identity Pool vending auth and unauth roles. |\n| unauthenticatedUserRole | aws-cdk-lib.aws_iam.IRole | Unauthenticated user role, applies to { provider: iam, allow: public } access. |\n| allowListedRoles | string \\| aws-cdk-lib.aws_iam.IRole[] | A list of IAM roles which will be granted full read/write access to the generated model if IAM auth is enabled. |\n\n---\n\n##### `authenticatedUserRole`Required \n\n```typescript\npublic readonly authenticatedUserRole: IRole;\n```\n\n- *Type:* aws-cdk-lib.aws_iam.IRole\n\nAuthenticated user role, applies to { provider: iam, allow: private } access.\n\n---\n\n##### `identityPoolId`Required \n\n```typescript\npublic readonly identityPoolId: string;\n```\n\n- *Type:* string\n\nID for the Cognito Identity Pool vending auth and unauth roles.\n\nFormat: `:`\n\n---\n\n##### `unauthenticatedUserRole`Required \n\n```typescript\npublic readonly unauthenticatedUserRole: IRole;\n```\n\n- *Type:* aws-cdk-lib.aws_iam.IRole\n\nUnauthenticated user role, applies to { provider: iam, allow: public } access.\n\n---\n\n##### `allowListedRoles`Optional \n\n```typescript\npublic readonly allowListedRoles: string | IRole[];\n```\n\n- *Type:* string | aws-cdk-lib.aws_iam.IRole[]\n\nA list of IAM roles which will be granted full read/write access to the generated model if IAM auth is enabled.\n\nIf an IRole is provided, the role `name` will be used for matching.\nIf a string is provided, the raw value will be used for matching.\n\n---\n\n### LambdaAuthorizationConfig \n\nConfiguration for Custom Lambda authorization on the Graphql Api.\n\n#### Initializer \n\n```typescript\nimport { LambdaAuthorizationConfig } from '@aws-amplify/graphql-api-construct'\n\nconst lambdaAuthorizationConfig: LambdaAuthorizationConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| function | aws-cdk-lib.aws_lambda.IFunction | The authorizer lambda function. |\n| ttl | aws-cdk-lib.Duration | How long the results are cached. |\n\n---\n\n##### `function`Required \n\n```typescript\npublic readonly function: IFunction;\n```\n\n- *Type:* aws-cdk-lib.aws_lambda.IFunction\n\nThe authorizer lambda function.\n\n---\n\n##### `ttl`Required \n\n```typescript\npublic readonly ttl: Duration;\n```\n\n- *Type:* aws-cdk-lib.Duration\n\nHow long the results are cached.\n\n---\n\n### MutationFunctionSlot \n\nSlot types for Mutation Resolvers.\n\n#### Initializer \n\n```typescript\nimport { MutationFunctionSlot } from '@aws-amplify/graphql-api-construct'\n\nconst mutationFunctionSlot: MutationFunctionSlot = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| fieldName | string | The field to attach this function to on the Api definition. |\n| function | FunctionSlotOverride | The overridden behavior for this slot. |\n| slotIndex | number | The slot index to use to inject this into the execution pipeline. |\n| slotName | string | The slot name to inject this behavior into. |\n| typeName | string | This slot type applies to the Mutation type on the Api definition. |\n\n---\n\n##### `fieldName`Required \n\n```typescript\npublic readonly fieldName: string;\n```\n\n- *Type:* string\n\nThe field to attach this function to on the Api definition.\n\n---\n\n##### `function`Required \n\n```typescript\npublic readonly function: FunctionSlotOverride;\n```\n\n- *Type:* FunctionSlotOverride\n\nThe overridden behavior for this slot.\n\n---\n\n##### `slotIndex`Required \n\n```typescript\npublic readonly slotIndex: number;\n```\n\n- *Type:* number\n\nThe slot index to use to inject this into the execution pipeline.\n\nFor more information on slotting, refer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#extend-amplify-generated-resolvers\n\n---\n\n##### `slotName`Required \n\n```typescript\npublic readonly slotName: string;\n```\n\n- *Type:* string\n\nThe slot name to inject this behavior into.\n\nFor more information on slotting, refer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#extend-amplify-generated-resolvers\n\n---\n\n##### `typeName`Required \n\n```typescript\npublic readonly typeName: string;\n```\n\n- *Type:* string\n\nThis slot type applies to the Mutation type on the Api definition.\n\n---\n\n### OIDCAuthorizationConfig \n\nConfiguration for OpenId Connect Authorization on the Graphql Api.\n\n#### Initializer \n\n```typescript\nimport { OIDCAuthorizationConfig } from '@aws-amplify/graphql-api-construct'\n\nconst oIDCAuthorizationConfig: OIDCAuthorizationConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| oidcIssuerUrl | string | Url for the OIDC token issuer. |\n| oidcProviderName | string | The issuer for the OIDC configuration. |\n| tokenExpiryFromAuth | aws-cdk-lib.Duration | The duration an OIDC token is valid after being authenticated by OIDC provider. |\n| tokenExpiryFromIssue | aws-cdk-lib.Duration | The duration an OIDC token is valid after being issued to a user. |\n| clientId | string | The client identifier of the Relying party at the OpenID identity provider. |\n\n---\n\n##### `oidcIssuerUrl`Required \n\n```typescript\npublic readonly oidcIssuerUrl: string;\n```\n\n- *Type:* string\n\nUrl for the OIDC token issuer.\n\n---\n\n##### `oidcProviderName`Required \n\n```typescript\npublic readonly oidcProviderName: string;\n```\n\n- *Type:* string\n\nThe issuer for the OIDC configuration.\n\n---\n\n##### `tokenExpiryFromAuth`Required \n\n```typescript\npublic readonly tokenExpiryFromAuth: Duration;\n```\n\n- *Type:* aws-cdk-lib.Duration\n\nThe duration an OIDC token is valid after being authenticated by OIDC provider.\n\nauth_time claim in OIDC token is required for this validation to work.\n\n---\n\n##### `tokenExpiryFromIssue`Required \n\n```typescript\npublic readonly tokenExpiryFromIssue: Duration;\n```\n\n- *Type:* aws-cdk-lib.Duration\n\nThe duration an OIDC token is valid after being issued to a user.\n\nThis validation uses iat claim of OIDC token.\n\n---\n\n##### `clientId`Optional \n\n```typescript\npublic readonly clientId: string;\n```\n\n- *Type:* string\n\nThe client identifier of the Relying party at the OpenID identity provider.\n\nA regular expression can be specified so AppSync can validate against multiple client identifiers at a time. Example\n\n---\n\n### OptimisticConflictResolutionStrategy \n\nEnable automerge on the project.\n\n#### Initializer \n\n```typescript\nimport { OptimisticConflictResolutionStrategy } from '@aws-amplify/graphql-api-construct'\n\nconst optimisticConflictResolutionStrategy: OptimisticConflictResolutionStrategy = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| detectionType | string | The conflict detection type used for resolution. |\n| handlerType | string | This conflict resolution strategy the _version to perform optimistic concurrency. |\n\n---\n\n##### `detectionType`Required \n\n```typescript\npublic readonly detectionType: string;\n```\n\n- *Type:* string\n\nThe conflict detection type used for resolution.\n\n---\n\n##### `handlerType`Required \n\n```typescript\npublic readonly handlerType: string;\n```\n\n- *Type:* string\n\nThis conflict resolution strategy the _version to perform optimistic concurrency.\n\nFor more information, refer to https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html#conflict-detection-and-resolution\n\n---\n\n### PartialTranslationBehavior \n\nA utility interface equivalent to Partial.\n\n#### Initializer \n\n```typescript\nimport { PartialTranslationBehavior } from '@aws-amplify/graphql-api-construct'\n\nconst partialTranslationBehavior: PartialTranslationBehavior = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| allowDestructiveGraphqlSchemaUpdates | boolean | The following schema updates require replacement of the underlying DynamoDB table:. |\n| disableResolverDeduping | boolean | Disable resolver deduping, this can sometimes cause problems because dedupe ordering isn't stable today, which can lead to circular dependencies across stacks if models are reordered. |\n| enableAutoIndexQueryNames | boolean | Automate generation of query names, and as a result attaching all indexes as queries to the generated Api. |\n| enableSearchNodeToNodeEncryption | boolean | If enabled, set nodeToNodeEncryption on the searchable domain (if one exists). |\n| enableTransformerCfnOutputs | boolean | When enabled, internal cfn outputs which existed in Amplify-generated apps will continue to be emitted. |\n| populateOwnerFieldForStaticGroupAuth | boolean | Ensure that the owner field is still populated even if a static iam or group authorization applies. |\n| replaceTableUponGsiUpdate | boolean | This behavior will only come into effect when both \"allowDestructiveGraphqlSchemaUpdates\" and this value are set to true. |\n| respectPrimaryKeyAttributesOnConnectionField | boolean | Enable custom primary key support, there's no good reason to disable this unless trying not to update a legacy app. |\n| sandboxModeEnabled | boolean | Enabling sandbox mode will enable api key auth on all models in the transformed schema. |\n| secondaryKeyAsGSI | boolean | If disabled, generated. |\n| shouldDeepMergeDirectiveConfigDefaults | boolean | Restore parity w/ GQLv1. |\n| suppressApiKeyGeneration | boolean | If enabled, disable api key resource generation even if specified as an auth rule on the construct. |\n| useSubUsernameForDefaultIdentityClaim | boolean | Ensure that oidc and userPool auth use the `sub` field in the for the username field, which disallows new users with the same id to access data from a deleted user in the pool. |\n\n---\n\n##### `allowDestructiveGraphqlSchemaUpdates`Optional \n\n```typescript\npublic readonly allowDestructiveGraphqlSchemaUpdates: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nThe following schema updates require replacement of the underlying DynamoDB table:.\n\nRemoving or renaming a model\n - Modifying the primary key of a model\n - Modifying a Local Secondary Index of a model (only applies to projects with secondaryKeyAsGSI turned off)\n\nALL DATA WILL BE LOST when the table replacement happens. When enabled, destructive updates are allowed.\nThis will only affect DynamoDB tables with provision strategy \"AMPLIFY_TABLE\".\n\n---\n\n##### `disableResolverDeduping`Optional \n\n```typescript\npublic readonly disableResolverDeduping: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nDisable resolver deduping, this can sometimes cause problems because dedupe ordering isn't stable today, which can lead to circular dependencies across stacks if models are reordered.\n\n---\n\n##### `enableAutoIndexQueryNames`Optional \n\n```typescript\npublic readonly enableAutoIndexQueryNames: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nAutomate generation of query names, and as a result attaching all indexes as queries to the generated Api.\n\nIf enabled,\n\n---\n\n##### `enableSearchNodeToNodeEncryption`Optional \n\n```typescript\npublic readonly enableSearchNodeToNodeEncryption: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nIf enabled, set nodeToNodeEncryption on the searchable domain (if one exists).\n\nNot recommended for use, prefer\nto use `Object.values(resources.additionalResources['AWS::Elasticsearch::Domain']).forEach((domain: CfnDomain) => {\n domain.NodeToNodeEncryptionOptions = { Enabled: True };\n});\n\n---\n\n##### `enableTransformerCfnOutputs`Optional \n\n```typescript\npublic readonly enableTransformerCfnOutputs: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nWhen enabled, internal cfn outputs which existed in Amplify-generated apps will continue to be emitted.\n\n---\n\n##### `populateOwnerFieldForStaticGroupAuth`Optional \n\n```typescript\npublic readonly populateOwnerFieldForStaticGroupAuth: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nEnsure that the owner field is still populated even if a static iam or group authorization applies.\n\n---\n\n##### `replaceTableUponGsiUpdate`Optional \n\n```typescript\npublic readonly replaceTableUponGsiUpdate: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nThis behavior will only come into effect when both \"allowDestructiveGraphqlSchemaUpdates\" and this value are set to true.\n\nWhen enabled, any global secondary index update operation will replace the table instead of iterative deployment, which will WIPE ALL\nEXISTING DATA but cost much less time for deployment This will only affect DynamoDB tables with provision strategy \"AMPLIFY_TABLE\".\n\n---\n\n##### `respectPrimaryKeyAttributesOnConnectionField`Optional \n\n```typescript\npublic readonly respectPrimaryKeyAttributesOnConnectionField: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nEnable custom primary key support, there's no good reason to disable this unless trying not to update a legacy app.\n\n---\n\n##### `sandboxModeEnabled`Optional \n\n```typescript\npublic readonly sandboxModeEnabled: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nEnabling sandbox mode will enable api key auth on all models in the transformed schema.\n\n---\n\n##### `secondaryKeyAsGSI`Optional \n\n```typescript\npublic readonly secondaryKeyAsGSI: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nIf disabled, generated.\n\n---\n\n##### `shouldDeepMergeDirectiveConfigDefaults`Optional \n\n```typescript\npublic readonly shouldDeepMergeDirectiveConfigDefaults: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nRestore parity w/ GQLv1.\n\n---\n\n##### `suppressApiKeyGeneration`Optional \n\n```typescript\npublic readonly suppressApiKeyGeneration: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nIf enabled, disable api key resource generation even if specified as an auth rule on the construct.\n\nThis is a legacy parameter from the Graphql Transformer existing in Amplify CLI, not recommended to change.\n\n---\n\n##### `useSubUsernameForDefaultIdentityClaim`Optional \n\n```typescript\npublic readonly useSubUsernameForDefaultIdentityClaim: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nEnsure that oidc and userPool auth use the `sub` field in the for the username field, which disallows new users with the same id to access data from a deleted user in the pool.\n\n---\n\n### ProvisionedConcurrencyConfig \n\nThe configuration for the provisioned concurrency of the Lambda.\n\n#### Initializer \n\n```typescript\nimport { ProvisionedConcurrencyConfig } from '@aws-amplify/graphql-api-construct'\n\nconst provisionedConcurrencyConfig: ProvisionedConcurrencyConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| provisionedConcurrentExecutions | number | The amount of provisioned concurrency to allocate. |\n\n---\n\n##### `provisionedConcurrentExecutions`Required \n\n```typescript\npublic readonly provisionedConcurrentExecutions: number;\n```\n\n- *Type:* number\n\nThe amount of provisioned concurrency to allocate.\n\n*\n\n---\n\n### ProvisionedThroughput \n\nWrapper for provisioned throughput config in DDB.\n\n#### Initializer \n\n```typescript\nimport { ProvisionedThroughput } from '@aws-amplify/graphql-api-construct'\n\nconst provisionedThroughput: ProvisionedThroughput = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| readCapacityUnits | number | The read capacity units on the table or index. |\n| writeCapacityUnits | number | The write capacity units on the table or index. |\n\n---\n\n##### `readCapacityUnits`Required \n\n```typescript\npublic readonly readCapacityUnits: number;\n```\n\n- *Type:* number\n\nThe read capacity units on the table or index.\n\n---\n\n##### `writeCapacityUnits`Required \n\n```typescript\npublic readonly writeCapacityUnits: number;\n```\n\n- *Type:* number\n\nThe write capacity units on the table or index.\n\n---\n\n### QueryFunctionSlot \n\nSlot types for Query Resolvers.\n\n#### Initializer \n\n```typescript\nimport { QueryFunctionSlot } from '@aws-amplify/graphql-api-construct'\n\nconst queryFunctionSlot: QueryFunctionSlot = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| fieldName | string | The field to attach this function to on the Api definition. |\n| function | FunctionSlotOverride | The overridden behavior for this slot. |\n| slotIndex | number | The slot index to use to inject this into the execution pipeline. |\n| slotName | string | The slot name to inject this behavior into. |\n| typeName | string | This slot type applies to the Query type on the Api definition. |\n\n---\n\n##### `fieldName`Required \n\n```typescript\npublic readonly fieldName: string;\n```\n\n- *Type:* string\n\nThe field to attach this function to on the Api definition.\n\n---\n\n##### `function`Required \n\n```typescript\npublic readonly function: FunctionSlotOverride;\n```\n\n- *Type:* FunctionSlotOverride\n\nThe overridden behavior for this slot.\n\n---\n\n##### `slotIndex`Required \n\n```typescript\npublic readonly slotIndex: number;\n```\n\n- *Type:* number\n\nThe slot index to use to inject this into the execution pipeline.\n\nFor more information on slotting, refer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#extend-amplify-generated-resolvers\n\n---\n\n##### `slotName`Required \n\n```typescript\npublic readonly slotName: string;\n```\n\n- *Type:* string\n\nThe slot name to inject this behavior into.\n\nFor more information on slotting, refer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#extend-amplify-generated-resolvers\n\n---\n\n##### `typeName`Required \n\n```typescript\npublic readonly typeName: string;\n```\n\n- *Type:* string\n\nThis slot type applies to the Query type on the Api definition.\n\n---\n\n### SQLLambdaModelDataSourceStrategy \n\nA strategy that creates a Lambda to connect to a pre-existing SQL table to resolve model data.\n\n#### Initializer \n\n```typescript\nimport { SQLLambdaModelDataSourceStrategy } from '@aws-amplify/graphql-api-construct'\n\nconst sQLLambdaModelDataSourceStrategy: SQLLambdaModelDataSourceStrategy = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| dbConnectionConfig | SqlModelDataSourceSecretsManagerDbConnectionConfig \\| SqlModelDataSourceSsmDbConnectionConfig | The parameters the Lambda data source will use to connect to the database. |\n| dbType | string | The type of the SQL database used to process model operations for this definition. |\n| name | string | The name of the strategy. |\n| customSqlStatements | {[ key: string ]: string} | Custom SQL statements. |\n| sqlLambdaProvisionedConcurrencyConfig | ProvisionedConcurrencyConfig | The configuration for the provisioned concurrency of the Lambda. |\n| vpcConfiguration | VpcConfig | The configuration of the VPC into which to install the Lambda. |\n\n---\n\n##### `dbConnectionConfig`Required \n\n```typescript\npublic readonly dbConnectionConfig: SqlModelDataSourceSecretsManagerDbConnectionConfig | SqlModelDataSourceSsmDbConnectionConfig;\n```\n\n- *Type:* SqlModelDataSourceSecretsManagerDbConnectionConfig | SqlModelDataSourceSsmDbConnectionConfig\n\nThe parameters the Lambda data source will use to connect to the database.\n\n---\n\n##### `dbType`Required \n\n```typescript\npublic readonly dbType: string;\n```\n\n- *Type:* string\n\nThe type of the SQL database used to process model operations for this definition.\n\n---\n\n##### `name`Required \n\n```typescript\npublic readonly name: string;\n```\n\n- *Type:* string\n\nThe name of the strategy.\n\nThis will be used to name the AppSync DataSource itself, plus any associated resources like resolver Lambdas.\nThis name must be unique across all schema definitions in a GraphQL API.\n\n---\n\n##### `customSqlStatements`Optional \n\n```typescript\npublic readonly customSqlStatements: {[ key: string ]: string};\n```\n\n- *Type:* {[ key: string ]: string}\n\nCustom SQL statements.\n\nThe key is the value of the `references` attribute of the `@sql` directive in the `schema`; the value is the SQL\nto be executed.\n\n---\n\n##### `sqlLambdaProvisionedConcurrencyConfig`Optional \n\n```typescript\npublic readonly sqlLambdaProvisionedConcurrencyConfig: ProvisionedConcurrencyConfig;\n```\n\n- *Type:* ProvisionedConcurrencyConfig\n\nThe configuration for the provisioned concurrency of the Lambda.\n\n---\n\n##### `vpcConfiguration`Optional \n\n```typescript\npublic readonly vpcConfiguration: VpcConfig;\n```\n\n- *Type:* VpcConfig\n\nThe configuration of the VPC into which to install the Lambda.\n\n---\n\n### SqlModelDataSourceSecretsManagerDbConnectionConfig \n\nThe credentials stored in Secrets Manager that the lambda data source will use to connect to the database.\n\nThe managed secret should be in the same region as the lambda.\n\n#### Initializer \n\n```typescript\nimport { SqlModelDataSourceSecretsManagerDbConnectionConfig } from '@aws-amplify/graphql-api-construct'\n\nconst sqlModelDataSourceSecretsManagerDbConnectionConfig: SqlModelDataSourceSecretsManagerDbConnectionConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| databaseName | string | The database name. |\n| hostname | string | The hostame of the database. |\n| port | number | The port number of the database proxy, cluster, or instance. |\n| secretArn | string | The ARN of the managed secret with username, password, and hostname to use when connecting to the database. |\n| keyArn | string | The ARN of the customer managed encryption key for the secret. |\n\n---\n\n##### `databaseName`Required \n\n```typescript\npublic readonly databaseName: string;\n```\n\n- *Type:* string\n\nThe database name.\n\n---\n\n##### `hostname`Required \n\n```typescript\npublic readonly hostname: string;\n```\n\n- *Type:* string\n\nThe hostame of the database.\n\n---\n\n##### `port`Required \n\n```typescript\npublic readonly port: number;\n```\n\n- *Type:* number\n\nThe port number of the database proxy, cluster, or instance.\n\n---\n\n##### `secretArn`Required \n\n```typescript\npublic readonly secretArn: string;\n```\n\n- *Type:* string\n\nThe ARN of the managed secret with username, password, and hostname to use when connecting to the database.\n\n*\n\n---\n\n##### `keyArn`Optional \n\n```typescript\npublic readonly keyArn: string;\n```\n\n- *Type:* string\n\nThe ARN of the customer managed encryption key for the secret.\n\nIf not supplied, the secret is expected to be encrypted with the default AWS-managed key. *\n\n---\n\n### SqlModelDataSourceSsmDbConnectionConfig \n\nThe Secure Systems Manager parameter paths the Lambda data source will use to connect to the database.\n\nThese parameters are retrieved from Secure Systems Manager in the same region as the Lambda.\n\n#### Initializer \n\n```typescript\nimport { SqlModelDataSourceSsmDbConnectionConfig } from '@aws-amplify/graphql-api-construct'\n\nconst sqlModelDataSourceSsmDbConnectionConfig: SqlModelDataSourceSsmDbConnectionConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| databaseNameSsmPath | string | The Secure Systems Manager parameter containing the database name. |\n| hostnameSsmPath | string | The Secure Systems Manager parameter containing the hostname of the database. |\n| passwordSsmPath | string | The Secure Systems Manager parameter containing the password to use when connecting to the database. |\n| portSsmPath | string | The Secure Systems Manager parameter containing the port number of the database proxy, cluster, or instance. |\n| usernameSsmPath | string | The Secure Systems Manager parameter containing the username to use when connecting to the database. |\n\n---\n\n##### `databaseNameSsmPath`Required \n\n```typescript\npublic readonly databaseNameSsmPath: string;\n```\n\n- *Type:* string\n\nThe Secure Systems Manager parameter containing the database name.\n\n---\n\n##### `hostnameSsmPath`Required \n\n```typescript\npublic readonly hostnameSsmPath: string;\n```\n\n- *Type:* string\n\nThe Secure Systems Manager parameter containing the hostname of the database.\n\nFor RDS-based SQL data sources, this can be the hostname\nof a database proxy, cluster, or instance.\n\n---\n\n##### `passwordSsmPath`Required \n\n```typescript\npublic readonly passwordSsmPath: string;\n```\n\n- *Type:* string\n\nThe Secure Systems Manager parameter containing the password to use when connecting to the database.\n\n---\n\n##### `portSsmPath`Required \n\n```typescript\npublic readonly portSsmPath: string;\n```\n\n- *Type:* string\n\nThe Secure Systems Manager parameter containing the port number of the database proxy, cluster, or instance.\n\n---\n\n##### `usernameSsmPath`Required \n\n```typescript\npublic readonly usernameSsmPath: string;\n```\n\n- *Type:* string\n\nThe Secure Systems Manager parameter containing the username to use when connecting to the database.\n\n---\n\n### SSESpecification \n\nRepresents the settings used to enable server-side encryption.\n\n#### Initializer \n\n```typescript\nimport { SSESpecification } from '@aws-amplify/graphql-api-construct'\n\nconst sSESpecification: SSESpecification = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| sseEnabled | boolean | Indicates whether server-side encryption is done using an AWS managed key or an AWS owned key. |\n| kmsMasterKeyId | string | The AWS KMS key that should be used for the AWS KMS encryption. |\n| sseType | SSEType | Server-side encryption type. |\n\n---\n\n##### `sseEnabled`Required \n\n```typescript\npublic readonly sseEnabled: boolean;\n```\n\n- *Type:* boolean\n\nIndicates whether server-side encryption is done using an AWS managed key or an AWS owned key.\n\nIf enabled (true), server-side encryption type is set to `KMS` and an AWS managed key is used ( AWS KMS charges apply).\nIf disabled (false) or not specified, server-side encryption is set to AWS owned key.\n\n---\n\n##### `kmsMasterKeyId`Optional \n\n```typescript\npublic readonly kmsMasterKeyId: string;\n```\n\n- *Type:* string\n\nThe AWS KMS key that should be used for the AWS KMS encryption.\n\nTo specify a key, use its key ID, Amazon Resource Name (ARN), alias name, or alias ARN. Note that you should only provide\nthis parameter if the key is different from the default DynamoDB key `alias/aws/dynamodb` .\n\n---\n\n##### `sseType`Optional \n\n```typescript\npublic readonly sseType: SSEType;\n```\n\n- *Type:* SSEType\n\nServer-side encryption type.\n\nThe only supported value is:\n`KMS` Server-side encryption that uses AWS Key Management Service.\n The key is stored in your account and is managed by AWS KMS ( AWS KMS charges apply).\n\n---\n\n### StreamSpecification \n\nRepresents the DynamoDB Streams configuration for a table in DynamoDB.\n\n#### Initializer \n\n```typescript\nimport { StreamSpecification } from '@aws-amplify/graphql-api-construct'\n\nconst streamSpecification: StreamSpecification = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| streamViewType | aws-cdk-lib.aws_dynamodb.StreamViewType | When an item in the table is modified, `StreamViewType` determines what information is written to the stream for this table. |\n\n---\n\n##### `streamViewType`Required \n\n```typescript\npublic readonly streamViewType: StreamViewType;\n```\n\n- *Type:* aws-cdk-lib.aws_dynamodb.StreamViewType\n\nWhen an item in the table is modified, `StreamViewType` determines what information is written to the stream for this table.\n\nValid values for `StreamViewType` are:\n- `KEYS_ONLY` - Only the key attributes of the modified item are written to the stream.\n- `NEW_IMAGE` - The entire item, as it appears after it was modified, is written to the stream.\n- `OLD_IMAGE` - The entire item, as it appeared before it was modified, is written to the stream.\n- `NEW_AND_OLD_IMAGES` - Both the new and the old item images of the item are written to the stream.\n\n---\n\n### SubnetAvailabilityZone \n\nSubnet configuration for VPC endpoints used by a Lambda resolver for a SQL-based data source.\n\nAlthough it is possible to create multiple\nsubnets in a single availability zone, VPC service endpoints may only be deployed to a single subnet in a given availability zone. This\nstructure ensures that the Lambda function and VPC service endpoints are mutually consistent.\n\n#### Initializer \n\n```typescript\nimport { SubnetAvailabilityZone } from '@aws-amplify/graphql-api-construct'\n\nconst subnetAvailabilityZone: SubnetAvailabilityZone = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| availabilityZone | string | The availability zone of the subnet. |\n| subnetId | string | The subnet ID to install the Lambda data source in. |\n\n---\n\n##### `availabilityZone`Required \n\n```typescript\npublic readonly availabilityZone: string;\n```\n\n- *Type:* string\n\nThe availability zone of the subnet.\n\n---\n\n##### `subnetId`Required \n\n```typescript\npublic readonly subnetId: string;\n```\n\n- *Type:* string\n\nThe subnet ID to install the Lambda data source in.\n\n---\n\n### SubscriptionFunctionSlot \n\nSlot types for Subscription Resolvers.\n\n#### Initializer \n\n```typescript\nimport { SubscriptionFunctionSlot } from '@aws-amplify/graphql-api-construct'\n\nconst subscriptionFunctionSlot: SubscriptionFunctionSlot = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| fieldName | string | The field to attach this function to on the Api definition. |\n| function | FunctionSlotOverride | The overridden behavior for this slot. |\n| slotIndex | number | The slot index to use to inject this into the execution pipeline. |\n| slotName | string | The slot name to inject this behavior into. |\n| typeName | string | This slot type applies to the Subscription type on the Api definition. |\n\n---\n\n##### `fieldName`Required \n\n```typescript\npublic readonly fieldName: string;\n```\n\n- *Type:* string\n\nThe field to attach this function to on the Api definition.\n\n---\n\n##### `function`Required \n\n```typescript\npublic readonly function: FunctionSlotOverride;\n```\n\n- *Type:* FunctionSlotOverride\n\nThe overridden behavior for this slot.\n\n---\n\n##### `slotIndex`Required \n\n```typescript\npublic readonly slotIndex: number;\n```\n\n- *Type:* number\n\nThe slot index to use to inject this into the execution pipeline.\n\nFor more information on slotting, refer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#extend-amplify-generated-resolvers\n\n---\n\n##### `slotName`Required \n\n```typescript\npublic readonly slotName: string;\n```\n\n- *Type:* string\n\nThe slot name to inject this behavior into.\n\nFor more information on slotting, refer to https://docs.amplify.aws/cli/graphql/custom-business-logic/#extend-amplify-generated-resolvers\n\n---\n\n##### `typeName`Required \n\n```typescript\npublic readonly typeName: string;\n```\n\n- *Type:* string\n\nThis slot type applies to the Subscription type on the Api definition.\n\n---\n\n### TimeToLiveSpecification \n\nShape for TTL config.\n\n#### Initializer \n\n```typescript\nimport { TimeToLiveSpecification } from '@aws-amplify/graphql-api-construct'\n\nconst timeToLiveSpecification: TimeToLiveSpecification = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| enabled | boolean | Boolean determining if the ttl is enabled or not. |\n| attributeName | string | Attribute name to apply to the ttl spec. |\n\n---\n\n##### `enabled`Required \n\n```typescript\npublic readonly enabled: boolean;\n```\n\n- *Type:* boolean\n\nBoolean determining if the ttl is enabled or not.\n\n---\n\n##### `attributeName`Optional \n\n```typescript\npublic readonly attributeName: string;\n```\n\n- *Type:* string\n\nAttribute name to apply to the ttl spec.\n\n---\n\n### TranslationBehavior \n\nStrongly typed set of shared parameters for all transformers, and core layer.\n\nThis is intended to replace feature flags, to ensure param coercion happens in\na single location, and isn't spread around the transformers, where they can\nhave different default behaviors.\n\n#### Initializer \n\n```typescript\nimport { TranslationBehavior } from '@aws-amplify/graphql-api-construct'\n\nconst translationBehavior: TranslationBehavior = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| allowDestructiveGraphqlSchemaUpdates | boolean | The following schema updates require replacement of the underlying DynamoDB table:. |\n| disableResolverDeduping | boolean | Disable resolver deduping, this can sometimes cause problems because dedupe ordering isn't stable today, which can lead to circular dependencies across stacks if models are reordered. |\n| enableAutoIndexQueryNames | boolean | Automate generation of query names, and as a result attaching all indexes as queries to the generated Api. |\n| enableSearchNodeToNodeEncryption | boolean | *No description.* |\n| enableTransformerCfnOutputs | boolean | When enabled, internal cfn outputs which existed in Amplify-generated apps will continue to be emitted. |\n| populateOwnerFieldForStaticGroupAuth | boolean | Ensure that the owner field is still populated even if a static iam or group authorization applies. |\n| replaceTableUponGsiUpdate | boolean | This behavior will only come into effect when both \"allowDestructiveGraphqlSchemaUpdates\" and this value are set to true. |\n| respectPrimaryKeyAttributesOnConnectionField | boolean | Enable custom primary key support, there's no good reason to disable this unless trying not to update a legacy app. |\n| sandboxModeEnabled | boolean | Enabling sandbox mode will enable api key auth on all models in the transformed schema. |\n| secondaryKeyAsGSI | boolean | If disabled, generated. |\n| shouldDeepMergeDirectiveConfigDefaults | boolean | Restore parity w/ GQLv1. |\n| suppressApiKeyGeneration | boolean | If enabled, disable api key resource generation even if specified as an auth rule on the construct. |\n| useSubUsernameForDefaultIdentityClaim | boolean | Ensure that oidc and userPool auth use the `sub` field in the for the username field, which disallows new users with the same id to access data from a deleted user in the pool. |\n\n---\n\n##### `allowDestructiveGraphqlSchemaUpdates`Required \n\n```typescript\npublic readonly allowDestructiveGraphqlSchemaUpdates: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nThe following schema updates require replacement of the underlying DynamoDB table:.\n\nRemoving or renaming a model\n - Modifying the primary key of a model\n - Modifying a Local Secondary Index of a model (only applies to projects with secondaryKeyAsGSI turned off)\n\nALL DATA WILL BE LOST when the table replacement happens. When enabled, destructive updates are allowed.\nThis will only affect DynamoDB tables with provision strategy \"AMPLIFY_TABLE\".\n\n---\n\n##### `disableResolverDeduping`Required \n\n```typescript\npublic readonly disableResolverDeduping: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nDisable resolver deduping, this can sometimes cause problems because dedupe ordering isn't stable today, which can lead to circular dependencies across stacks if models are reordered.\n\n---\n\n##### `enableAutoIndexQueryNames`Required \n\n```typescript\npublic readonly enableAutoIndexQueryNames: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nAutomate generation of query names, and as a result attaching all indexes as queries to the generated Api.\n\nIf enabled,\n\n---\n\n##### `enableSearchNodeToNodeEncryption`Required \n\n```typescript\npublic readonly enableSearchNodeToNodeEncryption: boolean;\n```\n\n- *Type:* boolean\n\n---\n\n##### `enableTransformerCfnOutputs`Required \n\n```typescript\npublic readonly enableTransformerCfnOutputs: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nWhen enabled, internal cfn outputs which existed in Amplify-generated apps will continue to be emitted.\n\n---\n\n##### `populateOwnerFieldForStaticGroupAuth`Required \n\n```typescript\npublic readonly populateOwnerFieldForStaticGroupAuth: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nEnsure that the owner field is still populated even if a static iam or group authorization applies.\n\n---\n\n##### `replaceTableUponGsiUpdate`Required \n\n```typescript\npublic readonly replaceTableUponGsiUpdate: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nThis behavior will only come into effect when both \"allowDestructiveGraphqlSchemaUpdates\" and this value are set to true.\n\nWhen enabled, any GSI update operation will replace the table instead of iterative deployment, which will WIPE ALL EXISTING DATA but\ncost much less time for deployment This will only affect DynamoDB tables with provision strategy \"AMPLIFY_TABLE\".\n\n---\n\n##### `respectPrimaryKeyAttributesOnConnectionField`Required \n\n```typescript\npublic readonly respectPrimaryKeyAttributesOnConnectionField: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nEnable custom primary key support, there's no good reason to disable this unless trying not to update a legacy app.\n\n---\n\n##### `sandboxModeEnabled`Required \n\n```typescript\npublic readonly sandboxModeEnabled: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nEnabling sandbox mode will enable api key auth on all models in the transformed schema.\n\n---\n\n##### `secondaryKeyAsGSI`Required \n\n```typescript\npublic readonly secondaryKeyAsGSI: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nIf disabled, generated.\n\n---\n\n##### `shouldDeepMergeDirectiveConfigDefaults`Required \n\n```typescript\npublic readonly shouldDeepMergeDirectiveConfigDefaults: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nRestore parity w/ GQLv1.\n\n---\n\n##### `suppressApiKeyGeneration`Required \n\n```typescript\npublic readonly suppressApiKeyGeneration: boolean;\n```\n\n- *Type:* boolean\n- *Default:* false\n\nIf enabled, disable api key resource generation even if specified as an auth rule on the construct.\n\nThis is a legacy parameter from the Graphql Transformer existing in Amplify CLI, not recommended to change.\n\n---\n\n##### `useSubUsernameForDefaultIdentityClaim`Required \n\n```typescript\npublic readonly useSubUsernameForDefaultIdentityClaim: boolean;\n```\n\n- *Type:* boolean\n- *Default:* true\n\nEnsure that oidc and userPool auth use the `sub` field in the for the username field, which disallows new users with the same id to access data from a deleted user in the pool.\n\n---\n\n### UserPoolAuthorizationConfig \n\nConfiguration for Cognito UserPool Authorization on the Graphql Api.\n\n#### Initializer \n\n```typescript\nimport { UserPoolAuthorizationConfig } from '@aws-amplify/graphql-api-construct'\n\nconst userPoolAuthorizationConfig: UserPoolAuthorizationConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| userPool | aws-cdk-lib.aws_cognito.IUserPool | The Cognito User Pool which is used to authenticated JWT tokens, and vends group and user information. |\n\n---\n\n##### `userPool`Required \n\n```typescript\npublic readonly userPool: IUserPool;\n```\n\n- *Type:* aws-cdk-lib.aws_cognito.IUserPool\n\nThe Cognito User Pool which is used to authenticated JWT tokens, and vends group and user information.\n\n---\n\n### VpcConfig \n\nConfiguration of the VPC in which to install a Lambda to resolve queries against a SQL-based data source.\n\nThe SQL Lambda will be deployed\ninto the specified VPC, subnets, and security groups. The specified subnets and security groups must be in the same VPC. The VPC must\nhave at least one subnet. The construct will also create VPC service endpoints in the specified subnets, as well as inbound security\nrules, to allow traffic on port 443 within each security group. This allows the Lambda to read database connection information from\nSecure Systems Manager.\n\n#### Initializer \n\n```typescript\nimport { VpcConfig } from '@aws-amplify/graphql-api-construct'\n\nconst vpcConfig: VpcConfig = { ... }\n```\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| securityGroupIds | string[] | The security groups to install the Lambda data source in. |\n| subnetAvailabilityZoneConfig | SubnetAvailabilityZone[] | The subnets to install the Lambda data source in, one per availability zone. |\n| vpcId | string | The VPC to install the Lambda data source in. |\n\n---\n\n##### `securityGroupIds`Required \n\n```typescript\npublic readonly securityGroupIds: string[];\n```\n\n- *Type:* string[]\n\nThe security groups to install the Lambda data source in.\n\n---\n\n##### `subnetAvailabilityZoneConfig`Required \n\n```typescript\npublic readonly subnetAvailabilityZoneConfig: SubnetAvailabilityZone[];\n```\n\n- *Type:* SubnetAvailabilityZone[]\n\nThe subnets to install the Lambda data source in, one per availability zone.\n\n---\n\n##### `vpcId`Required \n\n```typescript\npublic readonly vpcId: string;\n```\n\n- *Type:* string\n\nThe VPC to install the Lambda data source in.\n\n---\n\n## Classes \n\n### AmplifyDynamoDbTableWrapper \n\nWrapper class around Custom::AmplifyDynamoDBTable custom resource, to simplify the override experience a bit.\n\nThis is NOT a construct, just an easier way to access\nthe generated construct.\nThis is a wrapper intended to mimic the `aws_cdk_lib.aws_dynamodb.Table` functionality more-or-less.\nNotable differences is the addition of TKTK properties, to account for the fact that they're constructor props\nin the CDK construct, as well as the removal of all from*, grant*, and metric* methods implemented by Table.\n\n#### Initializers \n\n```typescript\nimport { AmplifyDynamoDbTableWrapper } from '@aws-amplify/graphql-api-construct'\n\nnew AmplifyDynamoDbTableWrapper(resource: CfnResource)\n```\n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| resource | aws-cdk-lib.CfnResource | the Cfn resource. |\n\n---\n\n##### `resource`Required \n\n- *Type:* aws-cdk-lib.CfnResource\n\nthe Cfn resource.\n\n---\n\n#### Methods \n\n| **Name** | **Description** |\n| --- | --- |\n| applyRemovalPolicy | Set the deletion policy of the resource based on the removal policy specified. |\n| setGlobalSecondaryIndexProvisionedThroughput | Set the provisionedThroughtput for a specified GSI by name. |\n\n---\n\n##### `applyRemovalPolicy` \n\n```typescript\npublic applyRemovalPolicy(policy: RemovalPolicy): void\n```\n\nSet the deletion policy of the resource based on the removal policy specified.\n\n###### `policy`Required \n\n- *Type:* aws-cdk-lib.RemovalPolicy\n\nremoval policy to set.\n\n---\n\n##### `setGlobalSecondaryIndexProvisionedThroughput` \n\n```typescript\npublic setGlobalSecondaryIndexProvisionedThroughput(indexName: string, provisionedThroughput: ProvisionedThroughput): void\n```\n\nSet the provisionedThroughtput for a specified GSI by name.\n\n###### `indexName`Required \n\n- *Type:* string\n\nthe index to specify a provisionedThroughput config for.\n\n---\n\n###### `provisionedThroughput`Required \n\n- *Type:* ProvisionedThroughput\n\nthe config to set.\n\n---\n\n#### Static Functions \n\n| **Name** | **Description** |\n| --- | --- |\n| isAmplifyDynamoDbTableResource | Return true and perform type narrowing if a given input appears to be capable of. |\n\n---\n\n##### `isAmplifyDynamoDbTableResource` \n\n```typescript\nimport { AmplifyDynamoDbTableWrapper } from '@aws-amplify/graphql-api-construct'\n\nAmplifyDynamoDbTableWrapper.isAmplifyDynamoDbTableResource(x: any)\n```\n\nReturn true and perform type narrowing if a given input appears to be capable of.\n\n###### `x`Required \n\n- *Type:* any\n\nthe object to check.\n\n---\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| billingMode | aws-cdk-lib.aws_dynamodb.BillingMode | Specify how you are charged for read and write throughput and how you manage capacity. |\n| deletionProtectionEnabled | boolean | Set table deletion protection. |\n| pointInTimeRecoveryEnabled | boolean | Whether point-in-time recovery is enabled. |\n| provisionedThroughput | ProvisionedThroughput | Update the provisioned throughput for the base table. |\n| sseSpecification | SSESpecification | Set the ddb server-side encryption specification on the table. |\n| streamSpecification | StreamSpecification | Set the ddb stream specification on the table. |\n| timeToLiveAttribute | TimeToLiveSpecification | The name of TTL attribute. |\n\n---\n\n##### `billingMode`Required \n\n```typescript\npublic readonly billingMode: BillingMode;\n```\n\n- *Type:* aws-cdk-lib.aws_dynamodb.BillingMode\n\nSpecify how you are charged for read and write throughput and how you manage capacity.\n\n---\n\n##### `deletionProtectionEnabled`Required \n\n```typescript\npublic readonly deletionProtectionEnabled: boolean;\n```\n\n- *Type:* boolean\n\nSet table deletion protection.\n\n---\n\n##### `pointInTimeRecoveryEnabled`Required \n\n```typescript\npublic readonly pointInTimeRecoveryEnabled: boolean;\n```\n\n- *Type:* boolean\n\nWhether point-in-time recovery is enabled.\n\n---\n\n##### `provisionedThroughput`Required \n\n```typescript\npublic readonly provisionedThroughput: ProvisionedThroughput;\n```\n\n- *Type:* ProvisionedThroughput\n\nUpdate the provisioned throughput for the base table.\n\n---\n\n##### `sseSpecification`Required \n\n```typescript\npublic readonly sseSpecification: SSESpecification;\n```\n\n- *Type:* SSESpecification\n\nSet the ddb server-side encryption specification on the table.\n\n---\n\n##### `streamSpecification`Required \n\n```typescript\npublic readonly streamSpecification: StreamSpecification;\n```\n\n- *Type:* StreamSpecification\n\nSet the ddb stream specification on the table.\n\n---\n\n##### `timeToLiveAttribute`Required \n\n```typescript\npublic readonly timeToLiveAttribute: TimeToLiveSpecification;\n```\n\n- *Type:* TimeToLiveSpecification\n\nThe name of TTL attribute.\n\n---\n\n\n### AmplifyGraphqlDefinition \n\nClass exposing utilities to produce IAmplifyGraphqlDefinition objects given various inputs.\n\n#### Initializers \n\n```typescript\nimport { AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct'\n\nnew AmplifyGraphqlDefinition()\n```\n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n\n---\n\n\n#### Static Functions \n\n| **Name** | **Description** |\n| --- | --- |\n| combine | Combines multiple IAmplifyGraphqlDefinitions into a single definition. |\n| fromFiles | Convert one or more appsync SchemaFile objects into an Amplify Graphql Schema, binding them to a DynamoDB data source. |\n| fromFilesAndStrategy | Convert one or more appsync SchemaFile objects into an Amplify Graphql Schema. |\n| fromString | Produce a schema definition from a string input. |\n\n---\n\n##### `combine` \n\n```typescript\nimport { AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct'\n\nAmplifyGraphqlDefinition.combine(definitions: IAmplifyGraphqlDefinition[])\n```\n\nCombines multiple IAmplifyGraphqlDefinitions into a single definition.\n\n###### `definitions`Required \n\n- *Type:* IAmplifyGraphqlDefinition[]\n\nthe definitions to combine.\n\n---\n\n##### `fromFiles` \n\n```typescript\nimport { AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct'\n\nAmplifyGraphqlDefinition.fromFiles(filePaths: string)\n```\n\nConvert one or more appsync SchemaFile objects into an Amplify Graphql Schema, binding them to a DynamoDB data source.\n\n###### `filePaths`Required \n\n- *Type:* string\n\none or more paths to the graphql files to process.\n\n---\n\n##### `fromFilesAndStrategy` \n\n```typescript\nimport { AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct'\n\nAmplifyGraphqlDefinition.fromFilesAndStrategy(filePaths: string | string[], dataSourceStrategy?: DefaultDynamoDbModelDataSourceStrategy | AmplifyDynamoDbModelDataSourceStrategy | SQLLambdaModelDataSourceStrategy)\n```\n\nConvert one or more appsync SchemaFile objects into an Amplify Graphql Schema.\n\n###### `filePaths`Required \n\n- *Type:* string | string[]\n\none or more paths to the graphql files to process.\n\n---\n\n###### `dataSourceStrategy`Optional \n\n- *Type:* DefaultDynamoDbModelDataSourceStrategy | AmplifyDynamoDbModelDataSourceStrategy | SQLLambdaModelDataSourceStrategy\n\nthe provisioning definition for datasources that resolve `@model`s in this schema.\n\nThe DynamoDB from\nCloudFormation will be used by default.\n\n---\n\n##### `fromString` \n\n```typescript\nimport { AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct'\n\nAmplifyGraphqlDefinition.fromString(schema: string, dataSourceStrategy?: DefaultDynamoDbModelDataSourceStrategy | AmplifyDynamoDbModelDataSourceStrategy | SQLLambdaModelDataSourceStrategy)\n```\n\nProduce a schema definition from a string input.\n\n###### `schema`Required \n\n- *Type:* string\n\nthe graphql input as a string.\n\n---\n\n###### `dataSourceStrategy`Optional \n\n- *Type:* DefaultDynamoDbModelDataSourceStrategy | AmplifyDynamoDbModelDataSourceStrategy | SQLLambdaModelDataSourceStrategy\n\nthe provisioning definition for datasources that resolve `@model`s and custom SQL statements in this schema.\n\nThe DynamoDB from CloudFormation will be used by default.\n\n---\n\n\n\n### SQLLambdaModelDataSourceStrategyFactory \n\nClass exposing utilities to produce SQLLambdaModelDataSourceStrategy objects given various inputs.\n\n#### Initializers \n\n```typescript\nimport { SQLLambdaModelDataSourceStrategyFactory } from '@aws-amplify/graphql-api-construct'\n\nnew SQLLambdaModelDataSourceStrategyFactory()\n```\n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n\n---\n\n\n#### Static Functions \n\n| **Name** | **Description** |\n| --- | --- |\n| fromCustomSqlFiles | Creates a SQLLambdaModelDataSourceStrategy where the binding's `customSqlStatements` are populated from `sqlFiles`. |\n\n---\n\n##### `fromCustomSqlFiles` \n\n```typescript\nimport { SQLLambdaModelDataSourceStrategyFactory } from '@aws-amplify/graphql-api-construct'\n\nSQLLambdaModelDataSourceStrategyFactory.fromCustomSqlFiles(sqlFiles: string[], options: SQLLambdaModelDataSourceStrategy)\n```\n\nCreates a SQLLambdaModelDataSourceStrategy where the binding's `customSqlStatements` are populated from `sqlFiles`.\n\nThe key\nof the `customSqlStatements` record is the file's base name (that is, the name of the file minus the directory and extension).\n\n###### `sqlFiles`Required \n\n- *Type:* string[]\n\nthe list of files to load SQL statements from.\n\n---\n\n###### `options`Required \n\n- *Type:* SQLLambdaModelDataSourceStrategy\n\nthe remaining SQLLambdaModelDataSourceStrategy options.\n\n---\n\n\n\n## Protocols \n\n### IAmplifyGraphqlDefinition \n\n- *Implemented By:* IAmplifyGraphqlDefinition\n\nGraphql Api definition, which can be implemented in multiple ways.\n\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| dataSourceStrategies | {[ key: string ]: DefaultDynamoDbModelDataSourceStrategy \\| AmplifyDynamoDbModelDataSourceStrategy \\| SQLLambdaModelDataSourceStrategy} | Retrieve the datasource strategy mapping. |\n| functionSlots | MutationFunctionSlot \\| QueryFunctionSlot \\| SubscriptionFunctionSlot[] | Retrieve any function slots defined explicitly in the Api definition. |\n| schema | string | Return the schema definition as a graphql string, with amplify directives allowed. |\n| customSqlDataSourceStrategies | CustomSqlDataSourceStrategy[] | An array of custom Query or Mutation SQL commands to the data sources that resolves them. |\n| referencedLambdaFunctions | {[ key: string ]: aws-cdk-lib.aws_lambda.IFunction} | Retrieve the references to any lambda functions used in the definition. |\n\n---\n\n##### `dataSourceStrategies`Required \n\n```typescript\npublic readonly dataSourceStrategies: {[ key: string ]: DefaultDynamoDbModelDataSourceStrategy | AmplifyDynamoDbModelDataSourceStrategy | SQLLambdaModelDataSourceStrategy};\n```\n\n- *Type:* {[ key: string ]: DefaultDynamoDbModelDataSourceStrategy | AmplifyDynamoDbModelDataSourceStrategy | SQLLambdaModelDataSourceStrategy}\n\nRetrieve the datasource strategy mapping.\n\nThe default strategy is to use DynamoDB from CloudFormation.\n\n---\n\n##### `functionSlots`Required \n\n```typescript\npublic readonly functionSlots: MutationFunctionSlot | QueryFunctionSlot | SubscriptionFunctionSlot[];\n```\n\n- *Type:* MutationFunctionSlot | QueryFunctionSlot | SubscriptionFunctionSlot[]\n\nRetrieve any function slots defined explicitly in the Api definition.\n\n---\n\n##### `schema`Required \n\n```typescript\npublic readonly schema: string;\n```\n\n- *Type:* string\n\nReturn the schema definition as a graphql string, with amplify directives allowed.\n\n---\n\n##### `customSqlDataSourceStrategies`Optional \n\n```typescript\npublic readonly customSqlDataSourceStrategies: CustomSqlDataSourceStrategy[];\n```\n\n- *Type:* CustomSqlDataSourceStrategy[]\n\nAn array of custom Query or Mutation SQL commands to the data sources that resolves them.\n\n---\n\n##### `referencedLambdaFunctions`Optional \n\n```typescript\npublic readonly referencedLambdaFunctions: {[ key: string ]: IFunction};\n```\n\n- *Type:* {[ key: string ]: aws-cdk-lib.aws_lambda.IFunction}\n\nRetrieve the references to any lambda functions used in the definition.\n\nUseful for wiring through aws_lambda.Function constructs into the definition directly,\nand generated references to invoke them.\n\n---\n\n### IBackendOutputEntry \n\n- *Implemented By:* IBackendOutputEntry\n\nEntry representing the required output from the backend for codegen generate commands to work.\n\n\n#### Properties \n\n| **Name** | **Type** | **Description** |\n| --- | --- | --- |\n| payload | {[ key: string ]: string} | The string-map payload of generated config values. |\n| version | string | The protocol version for this backend output. |\n\n---\n\n##### `payload`Required \n\n```typescript\npublic readonly payload: {[ key: string ]: string};\n```\n\n- *Type:* {[ key: string ]: string}\n\nThe string-map payload of generated config values.\n\n---\n\n##### `version`Required \n\n```typescript\npublic readonly version: string;\n```\n\n- *Type:* string\n\nThe protocol version for this backend output.\n\n---\n\n### IBackendOutputStorageStrategy \n\n- *Implemented By:* IBackendOutputStorageStrategy\n\nBackend output strategy used to write config required for codegen tasks.\n\n#### Methods \n\n| **Name** | **Description** |\n| --- | --- |\n| addBackendOutputEntry | Add an entry to backend output. |\n\n---\n\n##### `addBackendOutputEntry` \n\n```typescript\npublic addBackendOutputEntry(keyName: string, backendOutputEntry: IBackendOutputEntry): void\n```\n\nAdd an entry to backend output.\n\n###### `keyName`Required \n\n- *Type:* string\n\nthe key.\n\n---\n\n###### `backendOutputEntry`Required \n\n- *Type:* IBackendOutputEntry\n\nthe record to store in the backend output.\n\n---\n\n\n## Enums \n\n### SSEType \n\nServer Side Encryption Type Values - `KMS` - Server-side encryption that uses AWS KMS.\n\nThe key is stored in your account and is managed by KMS (AWS KMS charges apply).\n\n#### Members \n\n| **Name** | **Description** |\n| --- | --- |\n| KMS | *No description.* |\n\n---\n\n##### `KMS` \n\n---\n\n" + "markdown": "# Amplify Graphql API Construct\n\n[![View on Construct Hub](https://constructs.dev/badge?package=%40aws-amplify%2Fgraphql-api-construct)](https://constructs.dev/packages/@aws-amplify/graphql-api-construct)\n\nThis package vends an L3 CDK Construct wrapping the behavior of the Amplify GraphQL Transformer. This enables quick development and interation of AppSync APIs which support the Amplify GraphQL Directives. For more information on schema modeling in GraphQL, please refer to the [amplify developer docs](https://docs.amplify.aws/cli/graphql/overview/).\n\nThe primary way to use this construct is to invoke it with a provided schema (either as an inline graphql string, or as one or more `appsync.SchemaFile`) objects, and with authorization config provided. There are 5 supported methods for authorization of an AppSync API, all of which are supported by this construct. For more information on authorization rule definitions in Amplify, refer to the [authorization docs](https://docs.amplify.aws/cli/graphql/authorization-rules/). Note: currently at least one authorization rule is required, and if multiple are specified, a `defaultAuthorizationMode` must be specified on the api as well. Specified authorization modes must be a superset of those configured in the graphql schema.\n\n## Examples\n\n### Simple Todo List With Cognito Userpool-based Owner Authorization\n\nIn this example, we create a single model, which will use `user pool` auth in order to allow logged in users to create and manage their own `todos` privately.\n\nWe create a cdk App and Stack, though you may be deploying this to a custom stack, this is purely illustrative for a concise demo.\n\nWe then wire this through to import a user pool which was already deployed (creating and deploying is out of scope for this example).\n\n```ts\nimport { App, Stack } from 'aws-cdk-lib';\nimport { UserPool } from 'aws-cdk-lib/aws-cognito';\nimport { AmplifyGraphqlApi, AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct';\n\nconst app = new App();\nconst stack = new Stack(app, 'TodoStack');\n\nnew AmplifyGraphqlApi(stack, 'TodoApp', {\n definition: AmplifyGraphqlDefinition.fromString(/* GraphQL */ `\n type Todo @model @auth(rules: [{ allow: owner }]) {\n description: String!\n completed: Boolean\n }\n `),\n authorizationModes: {\n userPoolConfig: {\n userPool: UserPool.fromUserPoolId(stack, 'ImportedUserPool', ''),\n },\n },\n});\n```\n\n### Multiple related models, with public read access, and admin read/write access\n\nIn this example, we create a two related models, which will use which logged in users in the 'Author' and 'Admin' user groups will have\nfull access to, and customers requesting with api key will only have read permissions on.\n\n```ts\nimport { App, Stack } from 'aws-cdk-lib';\nimport { UserPool } from 'aws-cdk-lib/aws-cognito';\nimport { AmplifyGraphqlApi, AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct';\n\nconst app = new App();\nconst stack = new Stack(app, 'BlogStack');\n\nnew AmplifyGraphqlApi(stack, 'BlogApp', {\n definition: AmplifyGraphqlDefinition.fromString(/* GraphQL */ `\n type Blog @model @auth(rules: [{ allow: public, operations: [read] }, { allow: groups, groups: [\"Author\", \"Admin\"] }]) {\n title: String!\n description: String\n posts: [Post] @hasMany\n }\n\n type Post @model @auth(rules: [{ allow: public, operations: [read] }, { allow: groups, groups: [\"Author\", \"Admin\"] }]) {\n title: String!\n content: [String]\n blog: Blog @belongsTo\n }\n `),\n authorizationModes: {\n defaultAuthorizationMode: 'API_KEY',\n apiKeyConfig: {\n description: 'Api Key for public access',\n expires: cdk.Duration.days(7),\n },\n userPoolConfig: {\n userPool: UserPool.fromUserPoolId(stack, 'ImportedUserPool', ''),\n },\n },\n});\n```\n\n### Import GraphQL Schema from files, instead of inline\n\nIn this example, we import the schema definition itself from one or more local files, rather than an inline graphql string.\n\n```graphql\n# todo.graphql\ntype Todo @model @auth(rules: [{ allow: owner }]) {\n content: String!\n done: Boolean\n}\n```\n\n```graphql\n# blog.graphql\ntype Blog @model @auth(rules: [{ allow: owner }, { allow: public, operations: [read] }]) {\n title: String!\n description: String\n posts: [Post] @hasMany\n}\n\ntype Post @model @auth(rules: [{ allow: owner }, { allow: public, operations: [read] }]) {\n title: String!\n content: [String]\n blog: Blog @belongsTo\n}\n```\n\n```ts\n// app.ts\nimport { App, Stack } from 'aws-cdk-lib';\nimport { UserPool } from 'aws-cdk-lib/aws-cognito';\nimport { AmplifyGraphqlApi, AmplifyGraphqlDefinition } from '@aws-amplify/graphql-api-construct';\n\nconst app = new App();\nconst stack = new Stack(app, 'MultiFileStack');\n\nnew AmplifyGraphqlApi(stack, 'MultiFileDefinition', {\n definition: AmplifyGraphqlDefinition.fromFiles(path.join(__dirname, 'todo.graphql'), path.join(__dirname, 'blog.graphql')),\n authorizationModes: {\n defaultAuthorizationMode: 'API_KEY',\n apiKeyConfig: {\n description: 'Api Key for public access',\n expires: cdk.Duration.days(7),\n },\n userPoolConfig: {\n userPool: UserPool.fromUserPoolId(stack, 'ImportedUserPool', ''),\n },\n },\n});\n```\n" }, "repository": { "directory": "packages/amplify-graphql-api-construct", @@ -9201,7 +9201,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 992 + "line": 1008 }, "name": "AddFunctionProps", "properties": [ @@ -9214,7 +9214,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 996 + "line": 1012 }, "name": "dataSource", "type": { @@ -9230,7 +9230,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1001 + "line": 1017 }, "name": "name", "type": { @@ -9247,7 +9247,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1036 + "line": 1052 }, "name": "code", "optional": true, @@ -9265,7 +9265,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1008 + "line": 1024 }, "name": "description", "optional": true, @@ -9283,7 +9283,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1015 + "line": 1031 }, "name": "requestMappingTemplate", "optional": true, @@ -9301,7 +9301,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1022 + "line": 1038 }, "name": "responseMappingTemplate", "optional": true, @@ -9319,7 +9319,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1029 + "line": 1045 }, "name": "runtime", "optional": true, @@ -10278,7 +10278,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 891 + "line": 907 }, "name": "AmplifyGraphqlApiCfnResources", "properties": [ @@ -10291,7 +10291,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 945 + "line": 961 }, "name": "additionalCfnResources", "type": { @@ -10312,7 +10312,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 930 + "line": 946 }, "name": "amplifyDynamoDbTables", "type": { @@ -10333,7 +10333,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 920 + "line": 936 }, "name": "cfnDataSources", "type": { @@ -10354,7 +10354,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 915 + "line": 931 }, "name": "cfnFunctionConfigurations", "type": { @@ -10375,7 +10375,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 940 + "line": 956 }, "name": "cfnFunctions", "type": { @@ -10396,7 +10396,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 895 + "line": 911 }, "name": "cfnGraphqlApi", "type": { @@ -10412,7 +10412,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 900 + "line": 916 }, "name": "cfnGraphqlSchema", "type": { @@ -10428,7 +10428,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 910 + "line": 926 }, "name": "cfnResolvers", "type": { @@ -10449,7 +10449,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 935 + "line": 951 }, "name": "cfnRoles", "type": { @@ -10470,7 +10470,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 925 + "line": 941 }, "name": "cfnTables", "type": { @@ -10491,7 +10491,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 905 + "line": 921 }, "name": "cfnApiKey", "optional": true, @@ -10514,7 +10514,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 801 + "line": 817 }, "name": "AmplifyGraphqlApiProps", "properties": [ @@ -10528,7 +10528,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 818 + "line": 834 }, "name": "authorizationModes", "type": { @@ -10545,7 +10545,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 806 + "line": 822 }, "name": "definition", "type": { @@ -10562,7 +10562,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 812 + "line": 828 }, "name": "apiName", "optional": true, @@ -10581,7 +10581,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 833 + "line": 849 }, "name": "conflictResolution", "optional": true, @@ -10599,7 +10599,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 877 + "line": 893 }, "name": "dataStoreConfiguration", "optional": true, @@ -10619,7 +10619,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 826 + "line": 842 }, "name": "functionNameMap", "optional": true, @@ -10642,7 +10642,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 848 + "line": 864 }, "name": "functionSlots", "optional": true, @@ -10676,7 +10676,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 882 + "line": 898 }, "name": "logging", "optional": true, @@ -10703,7 +10703,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 871 + "line": 887 }, "name": "outputStorageStrategy", "optional": true, @@ -10720,7 +10720,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 860 + "line": 876 }, "name": "predictionsBucket", "optional": true, @@ -10738,7 +10738,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 842 + "line": 858 }, "name": "stackMappings", "optional": true, @@ -10764,7 +10764,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 855 + "line": 871 }, "name": "transformerPlugins", "optional": true, @@ -10786,7 +10786,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 866 + "line": 882 }, "name": "translationBehavior", "optional": true, @@ -10809,7 +10809,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 954 + "line": 970 }, "name": "AmplifyGraphqlApiResources", "properties": [ @@ -10822,7 +10822,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 978 + "line": 994 }, "name": "cfnResources", "type": { @@ -10838,7 +10838,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 973 + "line": 989 }, "name": "functions", "type": { @@ -10859,7 +10859,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 958 + "line": 974 }, "name": "graphqlApi", "type": { @@ -10875,7 +10875,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 983 + "line": 999 }, "name": "nestedStacks", "type": { @@ -10896,7 +10896,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 968 + "line": 984 }, "name": "roles", "type": { @@ -10917,7 +10917,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 963 + "line": 979 }, "name": "tables", "type": { @@ -12014,7 +12014,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 729 + "line": 745 }, "name": "IAmplifyGraphqlDefinition", "properties": [ @@ -12029,7 +12029,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 754 + "line": 770 }, "name": "dataSourceStrategies", "type": { @@ -12066,7 +12066,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 740 + "line": 756 }, "name": "functionSlots", "type": { @@ -12100,7 +12100,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 734 + "line": 750 }, "name": "schema", "type": { @@ -12117,7 +12117,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 760 + "line": 776 }, "name": "customSqlDataSourceStrategies", "optional": true, @@ -12141,7 +12141,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 748 + "line": 764 }, "name": "referencedLambdaFunctions", "optional": true, @@ -12167,7 +12167,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 768 + "line": 784 }, "name": "IBackendOutputEntry", "properties": [ @@ -12180,7 +12180,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 777 + "line": 793 }, "name": "payload", "type": { @@ -12201,7 +12201,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 772 + "line": 788 }, "name": "version", "type": { @@ -12221,7 +12221,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 785 + "line": 801 }, "methods": [ { @@ -12232,7 +12232,7 @@ }, "locationInModule": { "filename": "src/types.ts", - "line": 792 + "line": 808 }, "name": "addBackendOutputEntry", "parameters": [ @@ -12724,7 +12724,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 605 + "line": 613 }, "name": "PartialTranslationBehavior", "properties": [ @@ -12739,7 +12739,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 702 + "line": 718 }, "name": "allowDestructiveGraphqlSchemaUpdates", "optional": true, @@ -12757,7 +12757,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 617 + "line": 625 }, "name": "disableResolverDeduping", "optional": true, @@ -12779,7 +12779,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 662 + "line": 670 }, "name": "enableAutoIndexQueryNames", "optional": true, @@ -12797,7 +12797,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 682 + "line": 698 }, "name": "enableSearchEncryptionAtRest", "optional": true, @@ -12815,7 +12815,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 675 + "line": 691 }, "name": "enableSearchNodeToNodeEncryption", "optional": true, @@ -12833,7 +12833,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 688 + "line": 704 }, "name": "enableTransformerCfnOutputs", "optional": true, @@ -12841,6 +12841,25 @@ "primitive": "boolean" } }, + { + "abstract": true, + "docs": { + "default": "false", + "remarks": "When enabled, only the `ssm` interface VPC endpoint - the\nsole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When\ndisabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC.", + "stability": "stable", + "summary": "Opt-in optimization for SQL data sources backed by an RDS instance in a VPC." + }, + "immutable": true, + "locationInModule": { + "filename": "src/types.ts", + "line": 684 + }, + "name": "minimizeRdsVpcEndpoints", + "optional": true, + "type": { + "primitive": "boolean" + } + }, { "abstract": true, "docs": { @@ -12851,7 +12870,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 642 + "line": 650 }, "name": "populateOwnerFieldForStaticGroupAuth", "optional": true, @@ -12870,7 +12889,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 712 + "line": 728 }, "name": "replaceTableUponGsiUpdate", "optional": true, @@ -12888,7 +12907,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 668 + "line": 676 }, "name": "respectPrimaryKeyAttributesOnConnectionField", "optional": true, @@ -12906,7 +12925,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 623 + "line": 631 }, "name": "sandboxModeEnabled", "optional": true, @@ -12927,7 +12946,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 655 + "line": 663 }, "name": "secondaryKeyAsGSI", "optional": true, @@ -12948,7 +12967,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 610 + "line": 618 }, "name": "shouldDeepMergeDirectiveConfigDefaults", "optional": true, @@ -12966,7 +12985,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 636 + "line": 644 }, "name": "subscriptionsInheritPrimaryAuth", "optional": true, @@ -12985,7 +13004,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 649 + "line": 657 }, "name": "suppressApiKeyGeneration", "optional": true, @@ -13003,7 +13022,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 630 + "line": 638 }, "name": "useSubUsernameForDefaultIdentityClaim", "optional": true, @@ -14267,7 +14286,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 583 + "line": 591 }, "name": "allowDestructiveGraphqlSchemaUpdates", "type": { @@ -14322,7 +14341,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 563 + "line": 571 }, "name": "enableSearchEncryptionAtRest", "type": { @@ -14339,7 +14358,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 556 + "line": 564 }, "name": "enableSearchNodeToNodeEncryption", "type": { @@ -14356,13 +14375,31 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 569 + "line": 577 }, "name": "enableTransformerCfnOutputs", "type": { "primitive": "boolean" } }, + { + "abstract": true, + "docs": { + "default": "false", + "remarks": "When enabled, only the `ssm` interface VPC endpoint - the\nsole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When\ndisabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC.", + "stability": "stable", + "summary": "Opt-in optimization for SQL data sources backed by an RDS instance in a VPC." + }, + "immutable": true, + "locationInModule": { + "filename": "src/types.ts", + "line": 557 + }, + "name": "minimizeRdsVpcEndpoints", + "type": { + "primitive": "boolean" + } + }, { "abstract": true, "docs": { @@ -14391,7 +14428,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 593 + "line": 601 }, "name": "replaceTableUponGsiUpdate", "type": { diff --git a/packages/amplify-graphql-api-construct/API.md b/packages/amplify-graphql-api-construct/API.md index f0320a1fe8..b6862c6baf 100644 --- a/packages/amplify-graphql-api-construct/API.md +++ b/packages/amplify-graphql-api-construct/API.md @@ -347,6 +347,7 @@ export interface PartialTranslationBehavior { readonly enableSearchEncryptionAtRest?: boolean; readonly enableSearchNodeToNodeEncryption?: boolean; readonly enableTransformerCfnOutputs?: boolean; + readonly minimizeRdsVpcEndpoints?: boolean; readonly populateOwnerFieldForStaticGroupAuth?: boolean; // @internal readonly _provisionHotswapFriendlyResources?: boolean; @@ -482,6 +483,7 @@ export interface TranslationBehavior { readonly enableSearchEncryptionAtRest: boolean; readonly enableSearchNodeToNodeEncryption: boolean; readonly enableTransformerCfnOutputs: boolean; + readonly minimizeRdsVpcEndpoints: boolean; readonly populateOwnerFieldForStaticGroupAuth: boolean; readonly replaceTableUponGsiUpdate: boolean; readonly respectPrimaryKeyAttributesOnConnectionField: boolean; diff --git a/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts b/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts index 1736faa067..94f239de40 100644 --- a/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts +++ b/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts @@ -1,6 +1,7 @@ import * as cdk from 'aws-cdk-lib'; import * as cognito from 'aws-cdk-lib/aws-cognito'; import { CfnFunction, CfnAlias } from 'aws-cdk-lib/aws-lambda'; +import { CfnVPCEndpoint } from 'aws-cdk-lib/aws-ec2'; import { mockSqlDataSourceStrategy } from '@aws-amplify/graphql-transformer-test-utils'; import { getResourceNamesForStrategy } from '@aws-amplify/graphql-transformer-core'; import { AmplifyGraphqlApi } from '../../amplify-graphql-api'; @@ -97,8 +98,50 @@ describe('sql-bound API generated resource access', () => { (resource) => resource.cfnResourceType === 'AWS::EC2::VPCEndpoint', ); - // Only the `ssm` endpoint is created per SQL Lambda function. Update this test accordingly as we add additional data sources bound to separate functions. + // 5 endpoints per SQL Lambda function. Update this test accordingly as we add additional data sources bound to separate functions. + expect(endpoints.length).toBe(5); + }); + + it('ssm as credential store with minimizeRdsVpcEndpoints enabled', () => { + const strategy = mockSqlDataSourceStrategy({ + vpcConfiguration: { + vpcId: 'vpc-123abc', + securityGroupIds: ['sg-123abc'], + subnetAvailabilityZoneConfig: [{ subnetId: 'subnet-123abc', availabilityZone: 'us-east-1a' }], + }, + }); + + const stack = new cdk.Stack(); + const userPool = cognito.UserPool.fromUserPoolId(stack, 'ImportedUserPool', 'ImportedUserPoolId'); + const api = new AmplifyGraphqlApi(stack, 'TestSqlBoundApi', { + definition: AmplifyGraphqlDefinition.fromString(defaultSchema, strategy), + authorizationModes: { + userPoolConfig: { userPool }, + }, + translationBehavior: { + minimizeRdsVpcEndpoints: true, + }, + }); + + const { + resources: { + cfnResources: { additionalCfnResources }, + }, + } = api; + + expect(additionalCfnResources).toBeDefined(); + const endpoints = Object.values(additionalCfnResources).filter( + (resource) => resource.cfnResourceType === 'AWS::EC2::VPCEndpoint', + ); + + // With minimizeRdsVpcEndpoints enabled, only the `ssm` endpoint is provisioned. expect(endpoints.length).toBe(1); + const [ssmEndpoint] = endpoints as CfnVPCEndpoint[]; + const resolvedServiceName = JSON.stringify(cdk.Stack.of(ssmEndpoint).resolve(ssmEndpoint.serviceName)); + expect(resolvedServiceName).toContain('ssm'); + expect(resolvedServiceName).not.toContain('ssmmessages'); + expect(resolvedServiceName).not.toContain('ec2'); + expect(resolvedServiceName).not.toContain('kms'); }); it('secrets manager as credentials store', () => { diff --git a/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts b/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts index 5dbab6f8dc..f0d30fcd21 100644 --- a/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts +++ b/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts @@ -16,6 +16,7 @@ export const defaultTranslationBehavior: TranslationBehavior = { secondaryKeyAsGSI: true, enableAutoIndexQueryNames: true, respectPrimaryKeyAttributesOnConnectionField: true, + minimizeRdsVpcEndpoints: false, enableSearchNodeToNodeEncryption: false, enableSearchEncryptionAtRest: false, enableTransformerCfnOutputs: false, diff --git a/packages/amplify-graphql-api-construct/src/types.ts b/packages/amplify-graphql-api-construct/src/types.ts index c1b6a6e429..4adaaf8bb8 100644 --- a/packages/amplify-graphql-api-construct/src/types.ts +++ b/packages/amplify-graphql-api-construct/src/types.ts @@ -548,6 +548,14 @@ export interface TranslationBehavior { */ readonly respectPrimaryKeyAttributesOnConnectionField: boolean; + /** + * Opt-in optimization for SQL data sources backed by an RDS instance in a VPC. When enabled, only the `ssm` interface VPC endpoint - the + * sole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When + * disabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC. + * @default false + */ + readonly minimizeRdsVpcEndpoints: boolean; + /** * Whether Node to Node encryption is enabled on the ElasticSearch cluster * @@ -667,6 +675,14 @@ export interface PartialTranslationBehavior { */ readonly respectPrimaryKeyAttributesOnConnectionField?: boolean; + /** + * Opt-in optimization for SQL data sources backed by an RDS instance in a VPC. When enabled, only the `ssm` interface VPC endpoint - the + * sole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When + * disabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC. + * @default false + */ + readonly minimizeRdsVpcEndpoints?: boolean; + /** * Whether Node to Node encryption is enabled on the ElasticSearch cluster * diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts index bff2264a1c..b8f218e191 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts @@ -497,4 +497,57 @@ describe('ModelTransformer with SQL data sources:', () => { expect(envVars.SSL_CERT_SSM_PATH).toBeDefined(); expect(envVars.SSL_CERT_SSM_PATH).toEqual('["/test/sslCert/1","/test/sslCert/2"]'); }); + + describe('VPC endpoint minimization (minimizeRdsVpcEndpoints)', () => { + const mysqlVpcStrategy: SQLLambdaModelDataSourceStrategy = { + ...mysqlStrategy, + name: 'mysqlVpcStrategy', + vpcConfiguration: { + vpcId: 'vpc-123abc', + securityGroupIds: ['sg-123abc'], + subnetAvailabilityZoneConfig: [{ subnetId: 'subnet-123abc', availabilityZone: 'us-east-1a' }], + }, + }; + + const getVpcEndpointResources = (out: ReturnType): any[] => { + const resourceNames = getResourceNamesForStrategy(mysqlVpcStrategy); + const sqlApiStack = out.stacks[resourceNames.sqlStack]; + expect(sqlApiStack).toBeDefined(); + return Object.values(sqlApiStack.Resources!).filter((resource: any) => resource.Type === 'AWS::EC2::VPCEndpoint'); + }; + + it('provisions all five VPC endpoints by default (minimizeRdsVpcEndpoints defaults to false)', () => { + const out = testTransform({ + schema: validSchema, + transformers: [new ModelTransformer(), new PrimaryKeyTransformer()], + dataSourceStrategies: constructDataSourceStrategies(validSchema, mysqlVpcStrategy), + }); + expect(out).toBeDefined(); + const endpoints = getVpcEndpointResources(out); + expect(endpoints.length).toEqual(5); + const serviceNames = JSON.stringify(endpoints.map((resource: any) => resource.Properties.ServiceName)); + ['ssm', 'ssmmessages', 'ec2', 'ec2messages', 'kms'].forEach((service) => { + expect(serviceNames).toContain(service); + }); + }); + + it('provisions only the ssm VPC endpoint when minimizeRdsVpcEndpoints is enabled', () => { + const out = testTransform({ + schema: validSchema, + transformers: [new ModelTransformer(), new PrimaryKeyTransformer()], + dataSourceStrategies: constructDataSourceStrategies(validSchema, mysqlVpcStrategy), + transformParameters: { + minimizeRdsVpcEndpoints: true, + }, + }); + expect(out).toBeDefined(); + const endpoints = getVpcEndpointResources(out); + expect(endpoints.length).toEqual(1); + const serviceName = JSON.stringify(endpoints[0].Properties.ServiceName); + expect(serviceName).toContain('ssm'); + expect(serviceName).not.toContain('ssmmessages'); + expect(serviceName).not.toContain('ec2'); + expect(serviceName).not.toContain('kms'); + }); + }); }); diff --git a/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts b/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts index 517311b70b..d65503ef63 100644 --- a/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts +++ b/packages/amplify-graphql-model-transformer/src/resolvers/rds/resolver.ts @@ -91,15 +91,26 @@ export const setRDSSNSTopicMappings = (scope: Construct, mapping: RDSSNSTopicMap * Returns an SSM Endpoint if needed by the current configuration, undefined otherwise. If the current configuration includes a VPC, the SSM * endpoint will be a VPC service endpoint, otherwise it will be the standard regionalized endpoint for the service. SSM Endpoints are * required if the DB connection information is stored in SSM, or if the configuration uses a custom SSL certificate. + * @param scope Construct + * @param resourceNames the SQL Lambda resource names + * @param sqlLambdaVpcConfig the VPC configuration for the SQL Lambda, if any + * @param minimizeRdsVpcEndpoints when true, only the `ssm` interface VPC endpoint is provisioned. Defaults to false, which provisions the + * full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) for backward compatibility. */ -export const getSsmEndpoint = (scope: Construct, resourceNames: SQLLambdaResourceNames, sqlLambdaVpcConfig?: VpcConfig): string => { +export const getSsmEndpoint = ( + scope: Construct, + resourceNames: SQLLambdaResourceNames, + sqlLambdaVpcConfig?: VpcConfig, + minimizeRdsVpcEndpoints = false, +): string => { if (!sqlLambdaVpcConfig) { // Default, non-VPC SSM endpoint return Fn.join('', ['ssm.', Fn.ref('AWS::Region'), '.amazonaws.com']); } - // Only the SSM VPC endpoint is needed for Lambda to access Parameter Store - const services = ['ssm']; + // Only the `ssm` endpoint is consumed at runtime to read the DB connection secret from Parameter Store. The full set is provisioned by + // default to preserve existing stacks; opting in to `minimizeRdsVpcEndpoints` provisions only the `ssm` endpoint. + const services = minimizeRdsVpcEndpoints ? ['ssm'] : ['ssm', 'ssmmessages', 'ec2', 'ec2messages', 'kms']; const endpoints = addVpcEndpoints(scope, sqlLambdaVpcConfig, resourceNames, services); const endpointEntries = endpoints.find((endpoint) => endpoint.service === 'ssm')?.endpoint.attrDnsEntries; if (!endpointEntries) { @@ -115,6 +126,8 @@ export const getSsmEndpoint = (scope: Construct, resourceNames: SQLLambdaResourc * @param scope Construct * @param apiGraphql GraphQLAPIProvider * @param lambdaRole IRole + * @param minimizeRdsVpcEndpoints when true, only the `ssm` interface VPC endpoint is provisioned for the SQL Lambda's VPC. Defaults to + * false, which provisions the full set for backward compatibility. */ export const createRdsLambda = ( scope: Construct, @@ -126,6 +139,7 @@ export const createRdsLambda = ( environment?: { [key: string]: string }, sqlLambdaVpcConfig?: VpcConfig, sqlLambdaProvisionedConcurrencyConfig?: ProvisionedConcurrencyConfig, + minimizeRdsVpcEndpoints = false, ): IFunction => { const lambdaEnvironment = { ...environment, @@ -134,7 +148,7 @@ export const createRdsLambda = ( if (credentialStorageMethod === CredentialStorageMethod.SSM) { lambdaEnvironment.CREDENTIAL_STORAGE_METHOD = CredentialStorageMethod.SSM; if (!lambdaEnvironment.SSM_ENDPOINT) { - lambdaEnvironment.SSM_ENDPOINT = getSsmEndpoint(scope, resourceNames, sqlLambdaVpcConfig); + lambdaEnvironment.SSM_ENDPOINT = getSsmEndpoint(scope, resourceNames, sqlLambdaVpcConfig, minimizeRdsVpcEndpoints); } } else if (credentialStorageMethod === CredentialStorageMethod.SECRETS_MANAGER) { // Default Secrets Manager endpoint @@ -300,7 +314,7 @@ const addVpcEndpoint = ( ): CfnVPCEndpoint => { const serviceEndpointPrefix = 'com.amazonaws'; const endpoint = new CfnVPCEndpoint(scope, `${resourceNames.sqlVpcEndpointPrefix}${serviceSuffix}`, { - serviceName: Fn.join('', [serviceEndpointPrefix, '.', Fn.ref('AWS::Region'), '.', serviceSuffix]), // Sample: com.amazonaws.us-east-1.ssm + serviceName: Fn.join('', [serviceEndpointPrefix, '.', Fn.ref('AWS::Region'), '.', serviceSuffix]), // Sample: com.amazonaws.us-east-1.ssmmessages vpcEndpointType: 'Interface', vpcId: sqlLambdaVpcConfig.vpcId, subnetIds: extractSubnetForVpcEndpoint(sqlLambdaVpcConfig.subnetAvailabilityZoneConfig), diff --git a/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts b/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts index b0888c3393..70b22c73c6 100644 --- a/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts +++ b/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts @@ -154,7 +154,12 @@ export class RdsModelResourceGenerator extends ModelResourceGenerator { // cert, even if the rest of the DB configuration is stored in Secrets Manager. if (sslCertSsmPath) { environment.SSL_CERT_SSM_PATH = JSON.stringify(sslCertSsmPath); - environment.SSM_ENDPOINT = getSsmEndpoint(lambdaScope, resourceNames, strategy.vpcConfiguration); + environment.SSM_ENDPOINT = getSsmEndpoint( + lambdaScope, + resourceNames, + strategy.vpcConfiguration, + context.transformParameters.minimizeRdsVpcEndpoints, + ); } const lambda = createRdsLambda( @@ -167,6 +172,7 @@ export class RdsModelResourceGenerator extends ModelResourceGenerator { environment, strategy.vpcConfiguration, strategy.sqlLambdaProvisionedConcurrencyConfig, + context.transformParameters.minimizeRdsVpcEndpoints, ); // Note that this tag will be added to either the bare function, or the alias created to handle provisioned concurrency diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts index fbe353dd06..d53666faab 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts @@ -25,6 +25,9 @@ export const defaultTransformParameters: TransformParameters = { // Relational Params respectPrimaryKeyAttributesOnConnectionField: true, + // SQL Params + minimizeRdsVpcEndpoints: false, + // Search Params enableSearchNodeToNodeEncryption: false, enableSearchEncryptionAtRest: false, diff --git a/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts b/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts index 2dcc783aa8..e383dddff0 100644 --- a/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts +++ b/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts @@ -29,6 +29,14 @@ export type TransformParameters = { // Relational Params respectPrimaryKeyAttributesOnConnectionField: boolean; + // SQL Params + /** + * Opt-in optimization for RDS-in-VPC SQL APIs. When enabled, the SQL Lambda's VPC is provisioned with only the `ssm` interface VPC + * endpoint (the sole endpoint consumed at runtime to read the database connection secret). When disabled (the default), the full set of + * endpoints (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned, preserving the existing behavior. + */ + minimizeRdsVpcEndpoints: boolean; + // Search Params enableSearchNodeToNodeEncryption: boolean; enableSearchEncryptionAtRest: boolean; From de5d4fd730fdea12b26998aca9bc2e19dcd93453 Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Tue, 7 Jul 2026 23:06:48 +0000 Subject: [PATCH 7/8] feat: scope minimizeRdsVpcEndpoints to the SQL data source strategy --- packages/amplify-graphql-api-construct/.jsii | 272 ++++++++---------- packages/amplify-graphql-api-construct/API.md | 3 +- .../sql-model-definition.test.ts | 4 +- .../src/internal/default-parameters.ts | 1 - .../src/model-datasource-strategy-types.ts | 10 + .../src/types.ts | 16 -- .../amplify-sql-resource-generator.test.ts | 9 +- .../resources/rds-model-resource-generator.ts | 9 +- .../transform-parameters.ts | 3 - .../src/model-datasource/types.ts | 10 + .../transform-parameters.ts | 8 - .../src/datasource-utils/utils.ts | 4 + 12 files changed, 160 insertions(+), 189 deletions(-) diff --git a/packages/amplify-graphql-api-construct/.jsii b/packages/amplify-graphql-api-construct/.jsii index b7b5b99ffb..0c858e5882 100644 --- a/packages/amplify-graphql-api-construct/.jsii +++ b/packages/amplify-graphql-api-construct/.jsii @@ -9201,7 +9201,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 1008 + "line": 992 }, "name": "AddFunctionProps", "properties": [ @@ -9214,7 +9214,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1012 + "line": 996 }, "name": "dataSource", "type": { @@ -9230,7 +9230,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1017 + "line": 1001 }, "name": "name", "type": { @@ -9247,7 +9247,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1052 + "line": 1036 }, "name": "code", "optional": true, @@ -9265,7 +9265,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1024 + "line": 1008 }, "name": "description", "optional": true, @@ -9283,7 +9283,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1031 + "line": 1015 }, "name": "requestMappingTemplate", "optional": true, @@ -9301,7 +9301,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1038 + "line": 1022 }, "name": "responseMappingTemplate", "optional": true, @@ -9319,7 +9319,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 1045 + "line": 1029 }, "name": "runtime", "optional": true, @@ -10278,7 +10278,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 907 + "line": 891 }, "name": "AmplifyGraphqlApiCfnResources", "properties": [ @@ -10291,7 +10291,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 961 + "line": 945 }, "name": "additionalCfnResources", "type": { @@ -10312,7 +10312,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 946 + "line": 930 }, "name": "amplifyDynamoDbTables", "type": { @@ -10333,7 +10333,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 936 + "line": 920 }, "name": "cfnDataSources", "type": { @@ -10354,7 +10354,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 931 + "line": 915 }, "name": "cfnFunctionConfigurations", "type": { @@ -10375,7 +10375,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 956 + "line": 940 }, "name": "cfnFunctions", "type": { @@ -10396,7 +10396,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 911 + "line": 895 }, "name": "cfnGraphqlApi", "type": { @@ -10412,7 +10412,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 916 + "line": 900 }, "name": "cfnGraphqlSchema", "type": { @@ -10428,7 +10428,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 926 + "line": 910 }, "name": "cfnResolvers", "type": { @@ -10449,7 +10449,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 951 + "line": 935 }, "name": "cfnRoles", "type": { @@ -10470,7 +10470,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 941 + "line": 925 }, "name": "cfnTables", "type": { @@ -10491,7 +10491,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 921 + "line": 905 }, "name": "cfnApiKey", "optional": true, @@ -10514,7 +10514,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 817 + "line": 801 }, "name": "AmplifyGraphqlApiProps", "properties": [ @@ -10528,7 +10528,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 834 + "line": 818 }, "name": "authorizationModes", "type": { @@ -10545,7 +10545,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 822 + "line": 806 }, "name": "definition", "type": { @@ -10562,7 +10562,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 828 + "line": 812 }, "name": "apiName", "optional": true, @@ -10581,7 +10581,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 849 + "line": 833 }, "name": "conflictResolution", "optional": true, @@ -10599,7 +10599,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 893 + "line": 877 }, "name": "dataStoreConfiguration", "optional": true, @@ -10619,7 +10619,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 842 + "line": 826 }, "name": "functionNameMap", "optional": true, @@ -10642,7 +10642,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 864 + "line": 848 }, "name": "functionSlots", "optional": true, @@ -10676,7 +10676,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 898 + "line": 882 }, "name": "logging", "optional": true, @@ -10703,7 +10703,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 887 + "line": 871 }, "name": "outputStorageStrategy", "optional": true, @@ -10720,7 +10720,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 876 + "line": 860 }, "name": "predictionsBucket", "optional": true, @@ -10738,7 +10738,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 858 + "line": 842 }, "name": "stackMappings", "optional": true, @@ -10764,7 +10764,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 871 + "line": 855 }, "name": "transformerPlugins", "optional": true, @@ -10786,7 +10786,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 882 + "line": 866 }, "name": "translationBehavior", "optional": true, @@ -10809,7 +10809,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 970 + "line": 954 }, "name": "AmplifyGraphqlApiResources", "properties": [ @@ -10822,7 +10822,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 994 + "line": 978 }, "name": "cfnResources", "type": { @@ -10838,7 +10838,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 989 + "line": 973 }, "name": "functions", "type": { @@ -10859,7 +10859,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 974 + "line": 958 }, "name": "graphqlApi", "type": { @@ -10875,7 +10875,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 999 + "line": 983 }, "name": "nestedStacks", "type": { @@ -10896,7 +10896,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 984 + "line": 968 }, "name": "roles", "type": { @@ -10917,7 +10917,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 979 + "line": 963 }, "name": "tables", "type": { @@ -11518,7 +11518,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 256 + "line": 266 }, "name": "CustomSqlDataSourceStrategy", "properties": [ @@ -11531,7 +11531,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 261 + "line": 271 }, "name": "fieldName", "type": { @@ -11547,7 +11547,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 264 + "line": 274 }, "name": "strategy", "type": { @@ -11563,7 +11563,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 258 + "line": 268 }, "name": "typeName", "type": { @@ -12014,7 +12014,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 745 + "line": 729 }, "name": "IAmplifyGraphqlDefinition", "properties": [ @@ -12029,7 +12029,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 770 + "line": 754 }, "name": "dataSourceStrategies", "type": { @@ -12066,7 +12066,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 756 + "line": 740 }, "name": "functionSlots", "type": { @@ -12100,7 +12100,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 750 + "line": 734 }, "name": "schema", "type": { @@ -12117,7 +12117,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 776 + "line": 760 }, "name": "customSqlDataSourceStrategies", "optional": true, @@ -12141,7 +12141,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 764 + "line": 748 }, "name": "referencedLambdaFunctions", "optional": true, @@ -12167,7 +12167,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 784 + "line": 768 }, "name": "IBackendOutputEntry", "properties": [ @@ -12180,7 +12180,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 793 + "line": 777 }, "name": "payload", "type": { @@ -12201,7 +12201,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 788 + "line": 772 }, "name": "version", "type": { @@ -12221,7 +12221,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 801 + "line": 785 }, "methods": [ { @@ -12232,7 +12232,7 @@ }, "locationInModule": { "filename": "src/types.ts", - "line": 808 + "line": 792 }, "name": "addBackendOutputEntry", "parameters": [ @@ -12724,7 +12724,7 @@ "kind": "interface", "locationInModule": { "filename": "src/types.ts", - "line": 613 + "line": 605 }, "name": "PartialTranslationBehavior", "properties": [ @@ -12739,7 +12739,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 718 + "line": 702 }, "name": "allowDestructiveGraphqlSchemaUpdates", "optional": true, @@ -12757,7 +12757,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 625 + "line": 617 }, "name": "disableResolverDeduping", "optional": true, @@ -12779,7 +12779,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 670 + "line": 662 }, "name": "enableAutoIndexQueryNames", "optional": true, @@ -12797,7 +12797,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 698 + "line": 682 }, "name": "enableSearchEncryptionAtRest", "optional": true, @@ -12815,7 +12815,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 691 + "line": 675 }, "name": "enableSearchNodeToNodeEncryption", "optional": true, @@ -12833,7 +12833,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 704 + "line": 688 }, "name": "enableTransformerCfnOutputs", "optional": true, @@ -12841,25 +12841,6 @@ "primitive": "boolean" } }, - { - "abstract": true, - "docs": { - "default": "false", - "remarks": "When enabled, only the `ssm` interface VPC endpoint - the\nsole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When\ndisabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC.", - "stability": "stable", - "summary": "Opt-in optimization for SQL data sources backed by an RDS instance in a VPC." - }, - "immutable": true, - "locationInModule": { - "filename": "src/types.ts", - "line": 684 - }, - "name": "minimizeRdsVpcEndpoints", - "optional": true, - "type": { - "primitive": "boolean" - } - }, { "abstract": true, "docs": { @@ -12870,7 +12851,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 650 + "line": 642 }, "name": "populateOwnerFieldForStaticGroupAuth", "optional": true, @@ -12889,7 +12870,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 728 + "line": 712 }, "name": "replaceTableUponGsiUpdate", "optional": true, @@ -12907,7 +12888,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 676 + "line": 668 }, "name": "respectPrimaryKeyAttributesOnConnectionField", "optional": true, @@ -12925,7 +12906,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 631 + "line": 623 }, "name": "sandboxModeEnabled", "optional": true, @@ -12946,7 +12927,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 663 + "line": 655 }, "name": "secondaryKeyAsGSI", "optional": true, @@ -12967,7 +12948,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 618 + "line": 610 }, "name": "shouldDeepMergeDirectiveConfigDefaults", "optional": true, @@ -12985,7 +12966,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 644 + "line": 636 }, "name": "subscriptionsInheritPrimaryAuth", "optional": true, @@ -13004,7 +12985,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 657 + "line": 649 }, "name": "suppressApiKeyGeneration", "optional": true, @@ -13022,7 +13003,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 638 + "line": 630 }, "name": "useSubUsernameForDefaultIdentityClaim", "optional": true, @@ -13096,7 +13077,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 122 + "line": 132 }, "name": "ProvisionedConcurrencyConfig", "properties": [ @@ -13110,7 +13091,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 124 + "line": 134 }, "name": "provisionedConcurrentExecutions", "type": { @@ -13488,7 +13469,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 93 + "line": 103 }, "name": "customSqlStatements", "optional": true, @@ -13501,6 +13482,25 @@ } } }, + { + "abstract": true, + "docs": { + "default": "false", + "remarks": "When enabled, only the\n`ssm` interface VPC endpoint - the sole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is\nprovisioned. When disabled (the default), the full set of endpoints (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned,\npreserving the existing behavior. This setting only takes effect when `vpcConfiguration` is set; it has no effect for SQL data sources\nthat are not installed into a VPC.", + "stability": "stable", + "summary": "Opt-in optimization that minimizes the interface VPC endpoints provisioned for this SQL data source's Lambda." + }, + "immutable": true, + "locationInModule": { + "filename": "src/model-datasource-strategy-types.ts", + "line": 97 + }, + "name": "minimizeRdsVpcEndpoints", + "optional": true, + "type": { + "primitive": "boolean" + } + }, { "abstract": true, "docs": { @@ -13510,7 +13510,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 98 + "line": 108 }, "name": "sqlLambdaProvisionedConcurrencyConfig", "optional": true, @@ -13710,7 +13710,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 197 + "line": 207 }, "name": "SqlModelDataSourceSecretsManagerDbConnectionConfig", "properties": [ @@ -13723,7 +13723,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 211 + "line": 221 }, "name": "databaseName", "type": { @@ -13739,7 +13739,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 214 + "line": 224 }, "name": "hostname", "type": { @@ -13755,7 +13755,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 208 + "line": 218 }, "name": "port", "type": { @@ -13772,7 +13772,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 199 + "line": 209 }, "name": "secretArn", "type": { @@ -13789,7 +13789,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 205 + "line": 215 }, "name": "keyArn", "optional": true, @@ -13806,7 +13806,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 219 + "line": 229 }, "name": "sslCertConfig", "optional": true, @@ -13829,7 +13829,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 227 + "line": 237 }, "name": "SqlModelDataSourceSsmDbConnectionConfig", "properties": [ @@ -13842,7 +13842,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 243 + "line": 253 }, "name": "databaseNameSsmPath", "type": { @@ -13859,7 +13859,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 231 + "line": 241 }, "name": "hostnameSsmPath", "type": { @@ -13875,7 +13875,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 240 + "line": 250 }, "name": "passwordSsmPath", "type": { @@ -13891,7 +13891,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 234 + "line": 244 }, "name": "portSsmPath", "type": { @@ -13907,7 +13907,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 237 + "line": 247 }, "name": "usernameSsmPath", "type": { @@ -13923,7 +13923,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 248 + "line": 258 }, "name": "sslCertConfig", "optional": true, @@ -13945,7 +13945,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 176 + "line": 186 }, "name": "SqlModelDataSourceSsmDbConnectionStringConfig", "properties": [ @@ -13959,7 +13959,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 183 + "line": 193 }, "name": "connectionUriSsmPath", "type": { @@ -13989,7 +13989,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 188 + "line": 198 }, "name": "sslCertConfig", "optional": true, @@ -14012,7 +14012,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 155 + "line": 165 }, "name": "SslCertConfig", "symbolId": "src/model-datasource-strategy-types:SslCertConfig" @@ -14030,7 +14030,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 157 + "line": 167 }, "name": "SslCertSsmPathConfig", "properties": [ @@ -14044,7 +14044,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 169 + "line": 179 }, "name": "ssmPath", "type": { @@ -14115,7 +14115,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 132 + "line": 142 }, "name": "SubnetAvailabilityZone", "properties": [ @@ -14128,7 +14128,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 137 + "line": 147 }, "name": "availabilityZone", "type": { @@ -14144,7 +14144,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 134 + "line": 144 }, "name": "subnetId", "type": { @@ -14286,7 +14286,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 591 + "line": 583 }, "name": "allowDestructiveGraphqlSchemaUpdates", "type": { @@ -14341,7 +14341,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 571 + "line": 563 }, "name": "enableSearchEncryptionAtRest", "type": { @@ -14358,7 +14358,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 564 + "line": 556 }, "name": "enableSearchNodeToNodeEncryption", "type": { @@ -14375,31 +14375,13 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 577 + "line": 569 }, "name": "enableTransformerCfnOutputs", "type": { "primitive": "boolean" } }, - { - "abstract": true, - "docs": { - "default": "false", - "remarks": "When enabled, only the `ssm` interface VPC endpoint - the\nsole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When\ndisabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC.", - "stability": "stable", - "summary": "Opt-in optimization for SQL data sources backed by an RDS instance in a VPC." - }, - "immutable": true, - "locationInModule": { - "filename": "src/types.ts", - "line": 557 - }, - "name": "minimizeRdsVpcEndpoints", - "type": { - "primitive": "boolean" - } - }, { "abstract": true, "docs": { @@ -14428,7 +14410,7 @@ "immutable": true, "locationInModule": { "filename": "src/types.ts", - "line": 601 + "line": 593 }, "name": "replaceTableUponGsiUpdate", "type": { @@ -14610,7 +14592,7 @@ "kind": "interface", "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 108 + "line": 118 }, "name": "VpcConfig", "properties": [ @@ -14623,7 +14605,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 113 + "line": 123 }, "name": "securityGroupIds", "type": { @@ -14644,7 +14626,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 116 + "line": 126 }, "name": "subnetAvailabilityZoneConfig", "type": { @@ -14665,7 +14647,7 @@ "immutable": true, "locationInModule": { "filename": "src/model-datasource-strategy-types.ts", - "line": 110 + "line": 120 }, "name": "vpcId", "type": { diff --git a/packages/amplify-graphql-api-construct/API.md b/packages/amplify-graphql-api-construct/API.md index b6862c6baf..eca40eeba5 100644 --- a/packages/amplify-graphql-api-construct/API.md +++ b/packages/amplify-graphql-api-construct/API.md @@ -347,7 +347,6 @@ export interface PartialTranslationBehavior { readonly enableSearchEncryptionAtRest?: boolean; readonly enableSearchNodeToNodeEncryption?: boolean; readonly enableTransformerCfnOutputs?: boolean; - readonly minimizeRdsVpcEndpoints?: boolean; readonly populateOwnerFieldForStaticGroupAuth?: boolean; // @internal readonly _provisionHotswapFriendlyResources?: boolean; @@ -391,6 +390,7 @@ export interface SQLLambdaModelDataSourceStrategy { readonly customSqlStatements?: Record; readonly dbConnectionConfig: SqlModelDataSourceDbConnectionConfig; readonly dbType: ModelDataSourceStrategySqlDbType; + readonly minimizeRdsVpcEndpoints?: boolean; readonly name: string; readonly sqlLambdaProvisionedConcurrencyConfig?: ProvisionedConcurrencyConfig; readonly vpcConfiguration?: VpcConfig; @@ -483,7 +483,6 @@ export interface TranslationBehavior { readonly enableSearchEncryptionAtRest: boolean; readonly enableSearchNodeToNodeEncryption: boolean; readonly enableTransformerCfnOutputs: boolean; - readonly minimizeRdsVpcEndpoints: boolean; readonly populateOwnerFieldForStaticGroupAuth: boolean; readonly replaceTableUponGsiUpdate: boolean; readonly respectPrimaryKeyAttributesOnConnectionField: boolean; diff --git a/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts b/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts index 94f239de40..266403e300 100644 --- a/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts +++ b/packages/amplify-graphql-api-construct/src/__tests__/__functional__/sql-model-definition.test.ts @@ -109,6 +109,7 @@ describe('sql-bound API generated resource access', () => { securityGroupIds: ['sg-123abc'], subnetAvailabilityZoneConfig: [{ subnetId: 'subnet-123abc', availabilityZone: 'us-east-1a' }], }, + minimizeRdsVpcEndpoints: true, }); const stack = new cdk.Stack(); @@ -118,9 +119,6 @@ describe('sql-bound API generated resource access', () => { authorizationModes: { userPoolConfig: { userPool }, }, - translationBehavior: { - minimizeRdsVpcEndpoints: true, - }, }); const { diff --git a/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts b/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts index f0d30fcd21..5dbab6f8dc 100644 --- a/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts +++ b/packages/amplify-graphql-api-construct/src/internal/default-parameters.ts @@ -16,7 +16,6 @@ export const defaultTranslationBehavior: TranslationBehavior = { secondaryKeyAsGSI: true, enableAutoIndexQueryNames: true, respectPrimaryKeyAttributesOnConnectionField: true, - minimizeRdsVpcEndpoints: false, enableSearchNodeToNodeEncryption: false, enableSearchEncryptionAtRest: false, enableTransformerCfnOutputs: false, diff --git a/packages/amplify-graphql-api-construct/src/model-datasource-strategy-types.ts b/packages/amplify-graphql-api-construct/src/model-datasource-strategy-types.ts index b798efddb2..6ad62f8a9a 100644 --- a/packages/amplify-graphql-api-construct/src/model-datasource-strategy-types.ts +++ b/packages/amplify-graphql-api-construct/src/model-datasource-strategy-types.ts @@ -86,6 +86,16 @@ export interface SQLLambdaModelDataSourceStrategy { */ readonly vpcConfiguration?: VpcConfig; + /** + * Opt-in optimization that minimizes the interface VPC endpoints provisioned for this SQL data source's Lambda. When enabled, only the + * `ssm` interface VPC endpoint - the sole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is + * provisioned. When disabled (the default), the full set of endpoints (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned, + * preserving the existing behavior. This setting only takes effect when `vpcConfiguration` is set; it has no effect for SQL data sources + * that are not installed into a VPC. + * @default false + */ + readonly minimizeRdsVpcEndpoints?: boolean; + /** * Custom SQL statements. The key is the value of the `references` attribute of the `@sql` directive in the `schema`; the value is the SQL * to be executed. diff --git a/packages/amplify-graphql-api-construct/src/types.ts b/packages/amplify-graphql-api-construct/src/types.ts index 4adaaf8bb8..c1b6a6e429 100644 --- a/packages/amplify-graphql-api-construct/src/types.ts +++ b/packages/amplify-graphql-api-construct/src/types.ts @@ -548,14 +548,6 @@ export interface TranslationBehavior { */ readonly respectPrimaryKeyAttributesOnConnectionField: boolean; - /** - * Opt-in optimization for SQL data sources backed by an RDS instance in a VPC. When enabled, only the `ssm` interface VPC endpoint - the - * sole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When - * disabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC. - * @default false - */ - readonly minimizeRdsVpcEndpoints: boolean; - /** * Whether Node to Node encryption is enabled on the ElasticSearch cluster * @@ -675,14 +667,6 @@ export interface PartialTranslationBehavior { */ readonly respectPrimaryKeyAttributesOnConnectionField?: boolean; - /** - * Opt-in optimization for SQL data sources backed by an RDS instance in a VPC. When enabled, only the `ssm` interface VPC endpoint - the - * sole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is provisioned for the SQL Lambda's VPC. When - * disabled, the full set (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned. Only affects SQL APIs configured with a VPC. - * @default false - */ - readonly minimizeRdsVpcEndpoints?: boolean; - /** * Whether Node to Node encryption is enabled on the ElasticSearch cluster * diff --git a/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts b/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts index b8f218e191..35cf3af3e3 100644 --- a/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts +++ b/packages/amplify-graphql-model-transformer/src/__tests__/amplify-sql-resource-generator.test.ts @@ -532,13 +532,14 @@ describe('ModelTransformer with SQL data sources:', () => { }); it('provisions only the ssm VPC endpoint when minimizeRdsVpcEndpoints is enabled', () => { + const minimizedVpcStrategy: SQLLambdaModelDataSourceStrategy = { + ...mysqlVpcStrategy, + minimizeRdsVpcEndpoints: true, + }; const out = testTransform({ schema: validSchema, transformers: [new ModelTransformer(), new PrimaryKeyTransformer()], - dataSourceStrategies: constructDataSourceStrategies(validSchema, mysqlVpcStrategy), - transformParameters: { - minimizeRdsVpcEndpoints: true, - }, + dataSourceStrategies: constructDataSourceStrategies(validSchema, minimizedVpcStrategy), }); expect(out).toBeDefined(); const endpoints = getVpcEndpointResources(out); diff --git a/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts b/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts index 70b22c73c6..965a483413 100644 --- a/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts +++ b/packages/amplify-graphql-model-transformer/src/resources/rds-model-resource-generator.ts @@ -154,12 +154,7 @@ export class RdsModelResourceGenerator extends ModelResourceGenerator { // cert, even if the rest of the DB configuration is stored in Secrets Manager. if (sslCertSsmPath) { environment.SSL_CERT_SSM_PATH = JSON.stringify(sslCertSsmPath); - environment.SSM_ENDPOINT = getSsmEndpoint( - lambdaScope, - resourceNames, - strategy.vpcConfiguration, - context.transformParameters.minimizeRdsVpcEndpoints, - ); + environment.SSM_ENDPOINT = getSsmEndpoint(lambdaScope, resourceNames, strategy.vpcConfiguration, strategy.minimizeRdsVpcEndpoints); } const lambda = createRdsLambda( @@ -172,7 +167,7 @@ export class RdsModelResourceGenerator extends ModelResourceGenerator { environment, strategy.vpcConfiguration, strategy.sqlLambdaProvisionedConcurrencyConfig, - context.transformParameters.minimizeRdsVpcEndpoints, + strategy.minimizeRdsVpcEndpoints, ); // Note that this tag will be added to either the bare function, or the alias created to handle provisioned concurrency diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts index d53666faab..fbe353dd06 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/transform-parameters.ts @@ -25,9 +25,6 @@ export const defaultTransformParameters: TransformParameters = { // Relational Params respectPrimaryKeyAttributesOnConnectionField: true, - // SQL Params - minimizeRdsVpcEndpoints: false, - // Search Params enableSearchNodeToNodeEncryption: false, enableSearchEncryptionAtRest: false, diff --git a/packages/amplify-graphql-transformer-interfaces/src/model-datasource/types.ts b/packages/amplify-graphql-transformer-interfaces/src/model-datasource/types.ts index f91066f09e..4f56b485b5 100644 --- a/packages/amplify-graphql-transformer-interfaces/src/model-datasource/types.ts +++ b/packages/amplify-graphql-transformer-interfaces/src/model-datasource/types.ts @@ -80,6 +80,16 @@ export interface SQLLambdaModelDataSourceStrategy extends ModelDataSourceStrateg */ readonly vpcConfiguration?: VpcConfig; + /** + * Opt-in optimization that minimizes the interface VPC endpoints provisioned for this SQL data source's Lambda. When enabled, only the + * `ssm` interface VPC endpoint - the sole endpoint the SQL Lambda consumes at runtime to read the database connection secret - is + * provisioned. When disabled (the default), the full set of endpoints (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned, + * preserving the existing behavior. This setting only takes effect when `vpcConfiguration` is set; it has no effect for SQL data sources + * that are not installed into a VPC. + * @default false + */ + readonly minimizeRdsVpcEndpoints?: boolean; + /** * The configuration for the provisioned concurrency of the Lambda. */ diff --git a/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts b/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts index e383dddff0..2dcc783aa8 100644 --- a/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts +++ b/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts @@ -29,14 +29,6 @@ export type TransformParameters = { // Relational Params respectPrimaryKeyAttributesOnConnectionField: boolean; - // SQL Params - /** - * Opt-in optimization for RDS-in-VPC SQL APIs. When enabled, the SQL Lambda's VPC is provisioned with only the `ssm` interface VPC - * endpoint (the sole endpoint consumed at runtime to read the database connection secret). When disabled (the default), the full set of - * endpoints (`ssm`, `ssmmessages`, `ec2`, `ec2messages`, `kms`) is provisioned, preserving the existing behavior. - */ - minimizeRdsVpcEndpoints: boolean; - // Search Params enableSearchNodeToNodeEncryption: boolean; enableSearchEncryptionAtRest: boolean; diff --git a/packages/amplify-graphql-transformer-test-utils/src/datasource-utils/utils.ts b/packages/amplify-graphql-transformer-test-utils/src/datasource-utils/utils.ts index cf8794a3e9..2c9215f883 100644 --- a/packages/amplify-graphql-transformer-test-utils/src/datasource-utils/utils.ts +++ b/packages/amplify-graphql-transformer-test-utils/src/datasource-utils/utils.ts @@ -12,6 +12,7 @@ export interface MakeSqlDataSourceStrategyOptions { dbType?: ModelDataSourceStrategySqlDbType; dbConnectionConfig?: SqlModelDataSourceDbConnectionConfig; vpcConfiguration?: VpcConfig; + minimizeRdsVpcEndpoints?: boolean; sqlLambdaProvisionedConcurrencyConfig?: ProvisionedConcurrencyConfig; // Note: this is only supported in the CDK Construct flavor of the SQLLambdaModelDataSourceStrategy customSqlStatements?: Record; @@ -39,6 +40,7 @@ export const MOCK_DB_CONNECTION_CONFIG: SqlModelDataSourceDbConnectionConfig = { * - name: `${dbType}MockStrategy` * - dbConnectionConfig: MOCK_DB_CONNECTION_CONFIG * - vpcConfiguration: undefined + * - minimizeRdsVpcEndpoints: undefined * - sqlLambdaProvisionedConcurrencyConfig: undefined * - customSqlStatements: undefined */ @@ -51,6 +53,7 @@ export const mockSqlDataSourceStrategy = ( const name = options?.name ?? `${dbType}MockStrategy`; const dbConnectionConfig = options?.dbConnectionConfig ?? MOCK_DB_CONNECTION_CONFIG; const vpcConfiguration = options?.vpcConfiguration; + const minimizeRdsVpcEndpoints = options?.minimizeRdsVpcEndpoints; const sqlLambdaProvisionedConcurrencyConfig = options?.sqlLambdaProvisionedConcurrencyConfig; const customSqlStatements = options?.customSqlStatements; return { @@ -58,6 +61,7 @@ export const mockSqlDataSourceStrategy = ( dbType, dbConnectionConfig, vpcConfiguration, + minimizeRdsVpcEndpoints, sqlLambdaProvisionedConcurrencyConfig, customSqlStatements, }; From eda5033fddc1337d1439d94ff66844e70624b90b Mon Sep 17 00:00:00 2001 From: Simone Zhang Date: Thu, 9 Jul 2026 11:19:30 +0000 Subject: [PATCH 8/8] chore: regenerate API report for minimizeRdsVpcEndpoints --- packages/amplify-graphql-transformer-interfaces/API.md | 2 ++ packages/amplify-graphql-transformer-test-utils/API.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/amplify-graphql-transformer-interfaces/API.md b/packages/amplify-graphql-transformer-interfaces/API.md index e5efd0f4c3..adb0291e3a 100644 --- a/packages/amplify-graphql-transformer-interfaces/API.md +++ b/packages/amplify-graphql-transformer-interfaces/API.md @@ -425,6 +425,8 @@ export interface SQLLambdaModelDataSourceStrategy extends ModelDataSourceStrateg // (undocumented) readonly dbType: ModelDataSourceStrategySqlDbType; // (undocumented) + readonly minimizeRdsVpcEndpoints?: boolean; + // (undocumented) readonly name: string; // (undocumented) readonly sqlLambdaProvisionedConcurrencyConfig?: ProvisionedConcurrencyConfig; diff --git a/packages/amplify-graphql-transformer-test-utils/API.md b/packages/amplify-graphql-transformer-test-utils/API.md index a605de9905..2317719043 100644 --- a/packages/amplify-graphql-transformer-test-utils/API.md +++ b/packages/amplify-graphql-transformer-test-utils/API.md @@ -86,6 +86,8 @@ export interface MakeSqlDataSourceStrategyOptions { // (undocumented) dbType?: ModelDataSourceStrategySqlDbType; // (undocumented) + minimizeRdsVpcEndpoints?: boolean; + // (undocumented) name?: string; // (undocumented) sqlLambdaProvisionedConcurrencyConfig?: ProvisionedConcurrencyConfig;