From a438950044662dd1ed5c476422a438cfcb42c85a Mon Sep 17 00:00:00 2001 From: dinsajwa Date: Thu, 17 Oct 2024 11:30:53 -0400 Subject: [PATCH] feat(construct): updated vpc helper to support deaful t setup --- .../custom-resource-provider-helper.ts | 2 +- src/common/helpers/vpc-helper.ts | 21 +++++++++---- .../gen-ai/aws-qa-appsync-opensearch/index.ts | 2 +- .../aws-rag-appsync-stepfn-kendra/index.ts | 4 +-- .../index.ts | 4 +-- .../amazonaurora/aurora-vector-store.test.ts | 4 +-- .../vpc-helper.test.ts | 30 ++++++++++++++----- ...psync-stepfn-opensearch-serverless.test.ts | 7 ++++- .../aws-rag-appsync-stepfn-opensearch.test.ts | 7 ++++- 9 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/common/helpers/custom-resource-provider-helper.ts b/src/common/helpers/custom-resource-provider-helper.ts index cd5f5d00..9fa21c19 100644 --- a/src/common/helpers/custom-resource-provider-helper.ts +++ b/src/common/helpers/custom-resource-provider-helper.ts @@ -122,7 +122,7 @@ export function buildCustomResourceProvider(props: CRProviderProps): ICRProvider timeout: cdk.Duration.minutes(15), memorySize: 128, vpc, - vpcSubnets: vpc ? { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS } : undefined, + vpcSubnets: vpc ? { subnetType: ec2.SubnetType.PRIVATE_ISOLATED } : undefined, securityGroups: vpc && securityGroup ? [securityGroup] : undefined, logRetention: logs.RetentionDays.ONE_WEEK, description: 'Custom Resource Provider', diff --git a/src/common/helpers/vpc-helper.ts b/src/common/helpers/vpc-helper.ts index 02d6013b..56db4562 100644 --- a/src/common/helpers/vpc-helper.ts +++ b/src/common/helpers/vpc-helper.ts @@ -112,7 +112,7 @@ export function buildVpc(scope: Construct, props: BuildVpcProps): IVpc { return props?.existingVpc; } - let defaultVpcProps = createDefaultIsolatedVpcProps(); + let defaultVpcProps = createDefaultVpcProps(); let cumulativeProps: VpcProps = defaultVpcProps; @@ -229,16 +229,27 @@ function AddInterfaceEndpoint(scope: Construct, vpc: IVpc, service: EndpointDefi }); } -export function createDefaultIsolatedVpcProps(): VpcProps { +export function createDefaultVpcProps(): VpcProps { return { - natGateways: 0, subnetConfiguration: [ { - cidrMask: 18, - name: 'isolated', + cidrMask: 24, + name: 'public', + subnetType: SubnetType.PUBLIC, + }, + { + cidrMask: 24, + name: 'private_isolated', subnetType: SubnetType.PRIVATE_ISOLATED, }, + { + cidrMask: 24, + name: 'private_egress', + subnetType: SubnetType.PRIVATE_WITH_EGRESS, + }, ], + ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'), + } as VpcProps; } diff --git a/src/patterns/gen-ai/aws-qa-appsync-opensearch/index.ts b/src/patterns/gen-ai/aws-qa-appsync-opensearch/index.ts index 6ec9313e..da0bd381 100644 --- a/src/patterns/gen-ai/aws-qa-appsync-opensearch/index.ts +++ b/src/patterns/gen-ai/aws-qa-appsync-opensearch/index.ts @@ -212,11 +212,11 @@ export class QaAppsyncOpensearch extends BaseClass { if (props?.existingVpc) { this.vpc = props.existingVpc; } else { - //this.vpc = new ec2.Vpc(this, 'Vpc', props.vpcProps); this.vpc = vpc_helper.buildVpc(scope, { defaultVpcProps: props?.vpcProps, vpcName: 'qaAppSyncOsVpc', }); + //vpc endpoints vpc_helper.AddAwsServiceEndpoint(scope, this.vpc, [ vpc_helper.ServiceEndpointTypeEnum.S3, diff --git a/src/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/index.ts b/src/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/index.ts index c5e3cfcf..26ef00d4 100644 --- a/src/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/index.ts +++ b/src/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/index.ts @@ -41,7 +41,7 @@ import { } from '../../../common/helpers/kendra-helper'; import { buildDockerLambdaFunction } from '../../../common/helpers/lambda-builder-helper'; import { lambdaMemorySizeLimiter } from '../../../common/helpers/utils'; -import { AddAwsServiceEndpoint, buildVpc, createDefaultIsolatedVpcProps, ServiceEndpointTypeEnum } from '../../../common/helpers/vpc-helper'; +import { AddAwsServiceEndpoint, buildVpc, createDefaultVpcProps, ServiceEndpointTypeEnum } from '../../../common/helpers/vpc-helper'; import { DockerLambdaCustomProps } from '../../../common/props/DockerLambdaCustomProps'; /** @@ -243,7 +243,7 @@ export class RagAppsyncStepfnKendra extends BaseClass { if (props.deployVpc || props.existingVpc) { this.vpc = buildVpc(scope, { - defaultVpcProps: createDefaultIsolatedVpcProps(), + defaultVpcProps: createDefaultVpcProps(), existingVpc: props.existingVpc, userVpcProps: props.vpcProps, constructVpcProps: { diff --git a/src/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/index.ts b/src/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/index.ts index c2606490..6091a911 100644 --- a/src/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/index.ts +++ b/src/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/index.ts @@ -257,11 +257,9 @@ export class RagAppsyncStepfnOpensearch extends BaseClass { if (props?.existingVpc) { this.vpc = props.existingVpc; } else { - //this.vpc = new ec2.Vpc(this, 'Vpc', props.vpcProps); - this.vpc = vpc_helper.buildVpc(scope, { defaultVpcProps: props?.vpcProps, - vpcName: 'ragAppSyncStepfnOsVpc', + vpcName: 'ragAppSyncOsVpc', }); //vpc endpoints vpc_helper.AddAwsServiceEndpoint(scope, this.vpc, [ diff --git a/test/cdk-lib/amazonaurora/aurora-vector-store.test.ts b/test/cdk-lib/amazonaurora/aurora-vector-store.test.ts index 458fe663..42755bce 100644 --- a/test/cdk-lib/amazonaurora/aurora-vector-store.test.ts +++ b/test/cdk-lib/amazonaurora/aurora-vector-store.test.ts @@ -38,7 +38,7 @@ describe('Amazon Aurora Vector Store', () => { subnetConfiguration: [ { cidrMask: 18, - name: 'isolated', + name: 'Private', subnetType: SubnetType.PRIVATE_ISOLATED, }, ], @@ -121,7 +121,7 @@ describe('Amazon Aurora Vector Store', () => { }, { cidrMask: 24, - name: 'Isolated', + name: 'Private', subnetType: cdk.aws_ec2.SubnetType.PRIVATE_ISOLATED, }, ], diff --git a/test/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/vpc-helper.test.ts b/test/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/vpc-helper.test.ts index 365ab96a..ea2af6f4 100644 --- a/test/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/vpc-helper.test.ts +++ b/test/patterns/gen-ai/aws-rag-appsync-stepfn-kendra/vpc-helper.test.ts @@ -14,7 +14,7 @@ import { App, Stack, Aspects } from 'aws-cdk-lib'; import { Match, Template } from 'aws-cdk-lib/assertions'; import { Vpc } from 'aws-cdk-lib/aws-ec2'; import { AwsSolutionsChecks } from 'cdk-nag'; -import { buildVpc, AddAwsServiceEndpoint, createDefaultIsolatedVpcProps, ServiceEndpointTypeEnum } from '../../../../src/common/helpers/vpc-helper'; +import { buildVpc, AddAwsServiceEndpoint, createDefaultVpcProps, ServiceEndpointTypeEnum } from '../../../../src/common/helpers/vpc-helper'; describe('VPC Utilities', () => { let app: App; @@ -28,7 +28,7 @@ describe('VPC Utilities', () => { describe('buildVpc', () => { it('creates a VPC with default isolated configuration', () => { - buildVpc(stack, { defaultVpcProps: createDefaultIsolatedVpcProps(), vpcName: 'testVpc' }); + buildVpc(stack, { defaultVpcProps: createDefaultVpcProps(), vpcName: 'testVpc' }); // Assert VPC is created with expected properties const template = Template.fromStack(stack); @@ -39,14 +39,30 @@ describe('VPC Utilities', () => { // Assert subnets are created as expected template.hasResourceProperties('AWS::EC2::Subnet', { - CidrBlock: Match.stringLikeRegexp('^(10\.0\.0\.0|10\.0\.64\.0)\/18$'), - MapPublicIpOnLaunch: false, - VpcId: Match.anyValue(), // Use anyValue if you're not asserting the exact VPC ID - // If you need to assert on Tags, ensure they match the expected structure + CidrBlock: Match.stringLikeRegexp('^10\.0\.[0-5]\.0\/24$'), + VpcId: Match.anyValue(), Tags: Match.arrayWith([ - Match.objectLike({ Key: 'aws-cdk:subnet-name', Value: 'isolated' }), + Match.objectLike({ + Key: 'aws-cdk:subnet-name', + Value: Match.stringLikeRegexp('^(private_isolated|private_egress|public)$'), + }), ]), }); + + // Assert that we have the expected number of subnets + template.resourceCountIs('AWS::EC2::Subnet', 6); + + // Assert that we have subnets with each expected type + ['private_isolated', 'private_egress', 'public'].forEach(subnetType => { + template.hasResourceProperties('AWS::EC2::Subnet', { + Tags: Match.arrayWith([ + Match.objectLike({ + Key: 'aws-cdk:subnet-name', + Value: subnetType, + }), + ]), + }); + }); }); }); diff --git a/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch-serverless.test.ts b/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch-serverless.test.ts index 7ad17b9c..9f763518 100644 --- a/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch-serverless.test.ts +++ b/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch-serverless.test.ts @@ -49,10 +49,15 @@ describe('RAG Appsync Stepfn Open search construct', () => { cidrMask: 24, }, { - name: 'private', + name: 'isolated', subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24, }, + { + name: 'private', + subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, + cidrMask: 24, + }, ], }, ); diff --git a/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts b/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts index f4b5514c..988f3300 100644 --- a/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts +++ b/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts @@ -50,10 +50,15 @@ describe('RAG Appsync Stepfn Open search construct', () => { cidrMask: 24, }, { - name: 'private', + name: 'isolated', subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24, }, + { + name: 'private', + subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, + cidrMask: 24, + }, ], }, );