diff --git a/deployment/cdk/opensearch-service-migration/lib/migration-assistance-stack.ts b/deployment/cdk/opensearch-service-migration/lib/migration-assistance-stack.ts index a9a0042df..9bccebb40 100644 --- a/deployment/cdk/opensearch-service-migration/lib/migration-assistance-stack.ts +++ b/deployment/cdk/opensearch-service-migration/lib/migration-assistance-stack.ts @@ -165,7 +165,8 @@ export class MigrationAssistanceStack extends Stack { const streamingSecurityGroup = new SecurityGroup(this, 'trafficStreamSourceSG', { vpc: props.vpc, - allowAllOutbound: false + allowAllOutbound: false, + allowAllIpv6Outbound: false, }); streamingSecurityGroup.addIngressRule(streamingSecurityGroup, Port.allTraffic()) createMigrationStringParameter(this, streamingSecurityGroup.securityGroupId, { @@ -180,6 +181,7 @@ export class MigrationAssistanceStack extends Stack { const sharedLogsSG = new SecurityGroup(this, 'sharedLogsSG', { vpc: props.vpc, allowAllOutbound: false, + allowAllIpv6Outbound: false, }); sharedLogsSG.addIngressRule(sharedLogsSG, Port.allTraffic()); @@ -205,6 +207,7 @@ export class MigrationAssistanceStack extends Stack { vpc: props.vpc, // Required for retrieving ECR image at service startup allowAllOutbound: true, + allowAllIpv6Outbound: true, }) serviceSecurityGroup.addIngressRule(serviceSecurityGroup, Port.allTraffic()); diff --git a/deployment/cdk/opensearch-service-migration/lib/network-stack.ts b/deployment/cdk/opensearch-service-migration/lib/network-stack.ts index 7e391419b..252a149a9 100644 --- a/deployment/cdk/opensearch-service-migration/lib/network-stack.ts +++ b/deployment/cdk/opensearch-service-migration/lib/network-stack.ts @@ -252,6 +252,7 @@ export class NetworkStack extends Stack { const defaultSecurityGroup = new SecurityGroup(this, 'osClusterAccessSG', { vpc: this.vpc, allowAllOutbound: false, + allowAllIpv6Outbound: false, }); defaultSecurityGroup.addIngressRule(defaultSecurityGroup, Port.allTraffic()); diff --git a/deployment/migration-assistant-solution/lib/solutions-stack.ts b/deployment/migration-assistant-solution/lib/solutions-stack.ts index 1ef51f550..71b64a7e7 100644 --- a/deployment/migration-assistant-solution/lib/solutions-stack.ts +++ b/deployment/migration-assistant-solution/lib/solutions-stack.ts @@ -11,6 +11,9 @@ import {Construct} from 'constructs'; import { BlockDeviceVolume, CloudFormationInit, + GatewayVpcEndpoint, + GatewayVpcEndpointAwsService, + IVpc, GenericLinuxImage, InitCommand, InitElement, @@ -19,11 +22,15 @@ import { InstanceClass, InstanceSize, InstanceType, + InterfaceVpcEndpoint, + InterfaceVpcEndpointAwsService, + IpProtocol, + SecurityGroup, Vpc } from "aws-cdk-lib/aws-ec2"; -import {InstanceProfile, ManagedPolicy, Role, ServicePrincipal} from "aws-cdk-lib/aws-iam"; import {CfnDocument} from "aws-cdk-lib/aws-ssm"; import {Application, AttributeGroup} from "@aws-cdk/aws-servicecatalogappregistry-alpha"; +import { InstanceProfile, ManagedPolicy, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam'; export interface SolutionsInfrastructureStackProps extends StackProps { readonly solutionId: string; @@ -79,7 +86,7 @@ function addParameterLabel(labels: Record, parameter: Cf labels[parameter.logicalId] = {"default": labelName} } -function importVPC(stack: Stack, vpdIdParameter: CfnParameter, availabilityZonesParameter: CfnParameter, privateSubnetIdsParameter: CfnParameter) { +function importVPC(stack: Stack, vpdIdParameter: CfnParameter, availabilityZonesParameter: CfnParameter, privateSubnetIdsParameter: CfnParameter): IVpc { const availabilityZones = availabilityZonesParameter.valueAsList const privateSubnetIds = privateSubnetIdsParameter.valueAsList return Vpc.fromVpcAttributes(stack, 'ImportedVPC', { @@ -95,6 +102,14 @@ function generateExportString(exports: Record): string { .join("; "); } +function getVpcEndpointForEFS(stack: Stack): InterfaceVpcEndpointAwsService { + const isGovRegion = stack.region?.startsWith('us-gov-') + if (isGovRegion) { + return InterfaceVpcEndpointAwsService.ELASTIC_FILESYSTEM_FIPS; + } + return InterfaceVpcEndpointAwsService.ELASTIC_FILESYSTEM; +} + export class SolutionsInfrastructureStack extends Stack { constructor(scope: Construct, id: string, props: SolutionsInfrastructureStackProps) { @@ -162,9 +177,33 @@ export class SolutionsInfrastructureStack extends Stack { role: bootstrapRole }) - let vpc; + let vpc: IVpc; if (props.createVPC) { - vpc = new Vpc(this, 'Vpc', {}); + vpc = new Vpc(this, 'Vpc', { + ipProtocol: IpProtocol.DUAL_STACK + }); + // S3 used for storage and retrieval of snapshot data for backfills + new GatewayVpcEndpoint(this, 'S3VpcEndpoint', { + service: GatewayVpcEndpointAwsService.S3, + vpc: vpc, + }); + + const serviceEndpoints = [ + // Logs and disk usage scales based on total data transfer + InterfaceVpcEndpointAwsService.CLOUDWATCH_LOGS, + getVpcEndpointForEFS(this), + + // Elastic container registry is used for all images in the solution + InterfaceVpcEndpointAwsService.ECR, + InterfaceVpcEndpointAwsService.ECR_DOCKER, + ]; + + serviceEndpoints.forEach(service => { + new InterfaceVpcEndpoint(this, `${service.shortName}VpcEndpoint`, { + service, + vpc: vpc, + }); + }) } else { const vpcIdParameter = new CfnParameter(this, 'VPCId', { @@ -226,6 +265,11 @@ export class SolutionsInfrastructureStack extends Stack { amiMap['us-gov-west-1'] = 'ami-0e46a6a8d36d6f1f2'; amiMap['us-gov-east-1'] = 'ami-0016d10ace091da71'; + const securityGroup = new SecurityGroup(this, 'BootstrapSecurityGroup', { + vpc: vpc, + allowAllOutbound: true, + allowAllIpv6Outbound: true, + }); new Instance(this, 'BootstrapEC2Instance', { vpc: vpc, vpcSubnets: { @@ -245,6 +289,7 @@ export class SolutionsInfrastructureStack extends Stack { initOptions: { printLog: true, }, + securityGroup }); const parameterGroups = []; diff --git a/deployment/migration-assistant-solution/package-lock.json b/deployment/migration-assistant-solution/package-lock.json index 750be932a..b50e3bb7b 100644 --- a/deployment/migration-assistant-solution/package-lock.json +++ b/deployment/migration-assistant-solution/package-lock.json @@ -9,9 +9,9 @@ "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-cdk/aws-servicecatalogappregistry-alpha": "2.105.0-alpha.0", + "@aws-cdk/aws-servicecatalogappregistry-alpha": "2.167.2-alpha.0", "@jest/globals": "^29.7.0", - "cdk": "^2.164.1", + "cdk": "^2.167.2", "globals": "^15.11.0", "source-map-support": "^0.5.21" }, @@ -21,8 +21,8 @@ "@types/eslint__js": "^8.42.3", "@types/jest": "^29.5.5", "@types/node": "^20.9.0", - "aws-cdk": "2.105.0", - "aws-cdk-lib": "2.105.0", + "aws-cdk": "2.167.2", + "aws-cdk-lib": "2.167.2", "constructs": "10.3.0", "eslint": "^9.13.0", "jest": "^29.7.0", @@ -63,16 +63,14 @@ } }, "node_modules/@aws-cdk/asset-awscli-v1": { - "version": "2.2.202", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.202.tgz", - "integrity": "sha512-JqlF0D4+EVugnG5dAsNZMqhu3HW7ehOXm5SDMxMbXNDMdsF0pxtQKNHRl52z1U9igsHmaFpUgSGjbhAJ+0JONg==", - "license": "Apache-2.0" + "version": "2.2.212", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.212.tgz", + "integrity": "sha512-7WqbnWUkBBcAzEdfRrpz6sCOheUPf4JEUdGvzJ4EEufXeT7v7nRbRmTvUBbQ+OQlCv9UrVj9XuFxKPjkvneGMQ==" }, "node_modules/@aws-cdk/asset-kubectl-v20": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz", - "integrity": "sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg==", - "license": "Apache-2.0" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.3.tgz", + "integrity": "sha512-cDG1w3ieM6eOT9mTefRuTypk95+oyD7P5X/wRltwmYxU7nZc3+076YEVS6vrjDKr3ADYbfn0lDKpfB1FBtO9CQ==" }, "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { "version": "2.1.0", @@ -81,14 +79,14 @@ "license": "Apache-2.0" }, "node_modules/@aws-cdk/aws-servicecatalogappregistry-alpha": { - "version": "2.105.0-alpha.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-servicecatalogappregistry-alpha/-/aws-servicecatalogappregistry-alpha-2.105.0-alpha.0.tgz", - "integrity": "sha512-jTtDL18u+pEtKFPQsvoB66cIkp6LxCaAs4DT3eY7v13DgPS8P5MshzAUjs/sDD+r6vtIz6A9ELoiAUZBT6YqHg==", + "version": "2.167.2-alpha.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-servicecatalogappregistry-alpha/-/aws-servicecatalogappregistry-alpha-2.167.2-alpha.0.tgz", + "integrity": "sha512-g10nDQwePk5xKf8fRvF4QcgjfLwvqfjFN8K2eQl7G3qqNOPLGzfO7NFKxE2puPbZ6kyUON5ADjI6Ly81d+XzMQ==", "engines": { "node": ">= 14.15.0" }, "peerDependencies": { - "aws-cdk-lib": "^2.105.0", + "aws-cdk-lib": "^2.167.2", "constructs": "^10.0.0" } }, @@ -102,6 +100,38 @@ "md5": "^2.3.0" } }, + "node_modules/@aws-cdk/cloud-assembly-schema": { + "version": "38.0.1", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-38.0.1.tgz", + "integrity": "sha512-KvPe+NMWAulfNVwY7jenFhzhuLhLqJ/OPy5jx7wUstbjnYnjRVLpUHPU3yCjXFE0J8cuJVdx95BJ4rOs66Pi9w==", + "bundleDependencies": [ + "jsonschema", + "semver" + ], + "dependencies": { + "jsonschema": "^1.4.1", + "semver": "^7.6.3" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { + "version": "1.4.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { + "version": "7.6.3", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@aws-cdk/cloudformation-diff": { "version": "2.68.0", "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-2.68.0.tgz", @@ -886,9 +916,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", - "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", "dev": true, "dependencies": { "levn": "^0.4.1" @@ -1901,10 +1931,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.105.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.105.0.tgz", - "integrity": "sha512-3ji+HNlCJUJ3o9h430gdRhocmeQrpM49fibXpvj3rvzBwuyWSTe2t8uohMPScSMETv59sHOlZpOdAEd+WwkuHQ==", - "dev": true, + "version": "2.167.2", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.167.2.tgz", + "integrity": "sha512-Ot4Wn+e6PBwMdxJPDbWoP1PngrtltflGSR3clCopA26ai33/Qr0AmvayiODrO8RzcM2hDSMVKhw68vv0ebGhgA==", "bin": { "cdk": "bin/cdk" }, @@ -1916,9 +1945,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.105.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.105.0.tgz", - "integrity": "sha512-pByAPfRyOzF+AVz56aLUPLhYiRZzfIjyV9Bf2t0X3cpwVW21zVC+8GrQcQwy+zWgFGg3Gx6IVFNio3t8awHXHA==", + "version": "2.167.2", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.167.2.tgz", + "integrity": "sha512-Izvg4VnuzKe2JPDRBlZtMYnOTe6qymtqU642SPeV8tAoBTQPfhZ0d34mXtxCRc9YQk1SoMPGO5VJ8H4Z2CE8Iw==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -1929,21 +1958,24 @@ "punycode", "semver", "table", - "yaml" + "yaml", + "mime-types" ], "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.200", - "@aws-cdk/asset-kubectl-v20": "^2.1.2", - "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.1", + "@aws-cdk/asset-awscli-v1": "^2.2.208", + "@aws-cdk/asset-kubectl-v20": "^2.1.3", + "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0", + "@aws-cdk/cloud-assembly-schema": "^38.0.1", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", - "fs-extra": "^11.1.1", - "ignore": "^5.2.4", + "fs-extra": "^11.2.0", + "ignore": "^5.3.2", "jsonschema": "^1.4.1", + "mime-types": "^2.1.35", "minimatch": "^3.1.2", - "punycode": "^2.3.0", - "semver": "^7.5.4", - "table": "^6.8.1", + "punycode": "^2.3.1", + "semver": "^7.6.3", + "table": "^6.8.2", "yaml": "1.10.2" }, "engines": { @@ -1959,14 +1991,14 @@ "license": "Apache-2.0" }, "node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.12.0", + "version": "8.17.1", "inBundle": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -2056,8 +2088,13 @@ "inBundle": true, "license": "MIT" }, + "node_modules/aws-cdk-lib/node_modules/fast-uri": { + "version": "3.0.3", + "inBundle": true, + "license": "BSD-3-Clause" + }, "node_modules/aws-cdk-lib/node_modules/fs-extra": { - "version": "11.1.1", + "version": "11.2.0", "inBundle": true, "license": "MIT", "dependencies": { @@ -2075,7 +2112,7 @@ "license": "ISC" }, "node_modules/aws-cdk-lib/node_modules/ignore": { - "version": "5.2.4", + "version": "5.3.2", "inBundle": true, "license": "MIT", "engines": { @@ -2119,15 +2156,23 @@ "inBundle": true, "license": "MIT" }, - "node_modules/aws-cdk-lib/node_modules/lru-cache": { - "version": "6.0.0", + "node_modules/aws-cdk-lib/node_modules/mime-db": { + "version": "1.52.0", "inBundle": true, - "license": "ISC", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/aws-cdk-lib/node_modules/mime-types": { + "version": "2.1.35", + "inBundle": true, + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">=10" + "node": ">= 0.6" } }, "node_modules/aws-cdk-lib/node_modules/minimatch": { @@ -2142,7 +2187,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.3.0", + "version": "2.3.1", "inBundle": true, "license": "MIT", "engines": { @@ -2158,12 +2203,9 @@ } }, "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.5.4", + "version": "7.6.3", "inBundle": true, "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -2212,7 +2254,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.8.1", + "version": "6.8.2", "inBundle": true, "license": "BSD-3-Clause", "dependencies": { @@ -2227,26 +2269,13 @@ } }, "node_modules/aws-cdk-lib/node_modules/universalify": { - "version": "2.0.0", + "version": "2.0.1", "inBundle": true, "license": "MIT", "engines": { "node": ">= 10.0.0" } }, - "node_modules/aws-cdk-lib/node_modules/uri-js": { - "version": "4.4.1", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/yallist": { - "version": "4.0.0", - "inBundle": true, - "license": "ISC" - }, "node_modules/aws-cdk-lib/node_modules/yaml": { "version": "1.10.2", "inBundle": true, @@ -2500,31 +2529,17 @@ "license": "CC-BY-4.0" }, "node_modules/cdk": { - "version": "2.164.1", - "resolved": "https://registry.npmjs.org/cdk/-/cdk-2.164.1.tgz", - "integrity": "sha512-1PVSZA4sjbQFvhkBFT8mlhpvUh/wKYAtrttVzmoYMlnQp0o5i6UpDB6qBO/owSk0/Us2z4QPYVS6WvNDWthoJQ==", + "version": "2.167.2", + "resolved": "https://registry.npmjs.org/cdk/-/cdk-2.167.2.tgz", + "integrity": "sha512-qijvR2+ica1rJyo0xQRZrsWJ0gyqhgt60bJa9iXHmlK7l95Lf+UCDlR1pBiU2Nwou7jmYM3O4Snj9WIZ1yfHCw==", "dependencies": { - "aws-cdk": "2.164.1" - }, - "bin": { - "cdk": "bin/cdk" + "aws-cdk": "2.167.2" }, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/cdk/node_modules/aws-cdk": { - "version": "2.164.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.164.1.tgz", - "integrity": "sha512-dWRViQgHLe7GHkPIQGA+8EQSm8TBcxemyCC3HHW3wbLMWUDbspio9Dktmw5EmWxlFjjWh86Dk1JWf1zKQo8C5g==", "bin": { "cdk": "bin/cdk" }, "engines": { "node": ">= 14.15.0" - }, - "optionalDependencies": { - "fsevents": "2.3.2" } }, "node_modules/chalk": { @@ -2686,11 +2701,10 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", diff --git a/deployment/migration-assistant-solution/package.json b/deployment/migration-assistant-solution/package.json index 0ee1cfc84..3f0cc7f5f 100644 --- a/deployment/migration-assistant-solution/package.json +++ b/deployment/migration-assistant-solution/package.json @@ -22,8 +22,8 @@ "@types/eslint__js": "^8.42.3", "@types/jest": "^29.5.5", "@types/node": "^20.9.0", - "aws-cdk": "2.105.0", - "aws-cdk-lib": "2.105.0", + "aws-cdk": "2.167.2", + "aws-cdk-lib": "2.167.2", "constructs": "10.3.0", "eslint": "^9.13.0", "jest": "^29.7.0", @@ -33,9 +33,9 @@ "typescript-eslint": "^8.11.0" }, "dependencies": { - "@aws-cdk/aws-servicecatalogappregistry-alpha": "2.105.0-alpha.0", + "@aws-cdk/aws-servicecatalogappregistry-alpha": "2.167.2-alpha.0", "@jest/globals": "^29.7.0", - "cdk": "^2.164.1", + "cdk": "^2.167.2", "globals": "^15.11.0", "source-map-support": "^0.5.21" } diff --git a/deployment/migration-assistant-solution/test/solutions-stack.test.ts b/deployment/migration-assistant-solution/test/solutions-stack.test.ts index e14594e83..d6352c082 100644 --- a/deployment/migration-assistant-solution/test/solutions-stack.test.ts +++ b/deployment/migration-assistant-solution/test/solutions-stack.test.ts @@ -4,42 +4,58 @@ import { App } from 'aws-cdk-lib'; import { SolutionsInfrastructureStack } from '../lib/solutions-stack'; describe('Solutions stack', () => { + const defaultProperties = { + solutionId: 'SO0000', + solutionName: 'test-solution', + solutionVersion: '0.0.1', + codeBucket: 'test-bucket', + createVPC: true, + env: { + region: 'us-west-1' + } + }; + test('Generate migration assistant stack with create VPC', () => { - const app = new App(); - const stack = new SolutionsInfrastructureStack(app, 'TestMigrationAssistantStack', { - solutionId: 'SO0000', - solutionName: 'test-solution', - solutionVersion: '0.0.1', - codeBucket: 'test-bucket', - createVPC: true, + const stack = new SolutionsInfrastructureStack(new App(), 'TestMigrationAssistantStack', defaultProperties); + const template = Template.fromStack(stack); + verifyResources(template, { + vpcCount: 1, + vpcEndpointCount: 5 + }); + }); + + test('Generate migration assistant stack with create VPC in Gov Region', () => { + const stack = new SolutionsInfrastructureStack(new App(), 'TestMigrationAssistantStack', { + ...defaultProperties, env: { - region: 'us-west-1' - } + region : "us-gov-east-1", + }, }); const template = Template.fromStack(stack); - template.resourceCountIs('AWS::EC2::VPC', 1) - template.resourceCountIs('AWS::ServiceCatalogAppRegistry::Application', 1) - template.hasResourceProperties('AWS::EC2::Instance', { - InstanceType: "t3.large" + verifyResources(template, { + vpcCount: 1, + vpcEndpointCount: 5 }); }); + test('Generate migration assistant stack with imported VPC', () => { - const app = new App(); - const stack = new SolutionsInfrastructureStack(app, 'TestMigrationAssistantStack', { - solutionId: 'SO0000', - solutionName: 'test-solution', - solutionVersion: '0.0.1', - codeBucket: 'test-bucket', - createVPC: false, - env: { - region: 'us-west-1' - } + const stack = new SolutionsInfrastructureStack(new App(), 'TestMigrationAssistantStack', { + ...defaultProperties, + createVPC: false }); const template = Template.fromStack(stack); - template.resourceCountIs('AWS::EC2::VPC', 0) - template.resourceCountIs('AWS::ServiceCatalogAppRegistry::Application', 1) + verifyResources(template, { + vpcCount: 0, + vpcEndpointCount: 0 + }); + }); + + function verifyResources(template: Template, props: { vpcCount: number, vpcEndpointCount: number }) { + template.resourceCountIs('AWS::EC2::VPC', props.vpcCount); + template.resourceCountIs('AWS::EC2::VPCEndpoint', props.vpcEndpointCount); + template.resourceCountIs('AWS::ServiceCatalogAppRegistry::Application', 1); template.hasResourceProperties('AWS::EC2::Instance', { InstanceType: "t3.large" }); - }); + } });