diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/manifest.json index 8e59a9d1095a1..617ebfcf6f9f4 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/manifest.json @@ -19,7 +19,7 @@ "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-us-west-2", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-us-west-2", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2/8bcc09e4eceabfb397695075b581f1f4e8f8a03b61ec24651ebe38d9da4f754e.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2/10cbe304a3bd42e3465787e1f8f7f9ab051a9af6b83f2eeb56422e7e3c6e60b1.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -53,24 +53,12 @@ "data": "ImportedNewVPCImportedPublicSubnetDefaultRoute56DCABA4" } ], - "/vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet-DefaultIPv6Route/Route": [ - { - "type": "aws:cdk:logicalId", - "data": "ImportedNewVPCAddnewImportedSubnetDefaultIPv6Route98D952A0" - } - ], "/vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet-DefaultRoute/Route": [ { "type": "aws:cdk:logicalId", "data": "ImportedNewVPCAddnewImportedSubnetDefaultRoute40344A0C" } ], - "/vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet2-DefaultIPv6Route/Route": [ - { - "type": "aws:cdk:logicalId", - "data": "ImportedNewVPCAddnewImportedSubnet2DefaultIPv6Route1EBC364B" - } - ], "/vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet2-DefaultRoute/Route": [ { "type": "aws:cdk:logicalId", @@ -98,7 +86,10 @@ "/vpcv2-import-integ-test/AddnewImportedSubnet/Subnet": [ { "type": "aws:cdk:logicalId", - "data": "AddnewImportedSubnet53655C69" + "data": "AddnewImportedSubnet53655C69", + "trace": [ + "!!DESTRUCTIVE_CHANGES: MAY_REPLACE" + ] } ], "/vpcv2-import-integ-test/AddnewImportedSubnet/RouteTable/RouteTable": [ @@ -116,7 +107,10 @@ "/vpcv2-import-integ-test/AddnewImportedSubnet2/Subnet": [ { "type": "aws:cdk:logicalId", - "data": "AddnewImportedSubnet2SubnetD9533DC5" + "data": "AddnewImportedSubnet2SubnetD9533DC5", + "trace": [ + "!!DESTRUCTIVE_CHANGES: MAY_REPLACE" + ] } ], "/vpcv2-import-integ-test/AddnewImportedSubnet2/RouteTable/RouteTable": [ @@ -140,10 +134,7 @@ "/vpcv2-import-integ-test/AddnewSubnettoImportedIpam/Subnet": [ { "type": "aws:cdk:logicalId", - "data": "AddnewSubnettoImportedIpamSubnet0F5C302A", - "trace": [ - "!!DESTRUCTIVE_CHANGES: MAY_REPLACE" - ] + "data": "AddnewSubnettoImportedIpamSubnet0F5C302A" } ], "/vpcv2-import-integ-test/AddnewSubnettoImportedIpam/RouteTable/RouteTable": [ @@ -169,6 +160,24 @@ "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } + ], + "ImportedNewVPCAddnewImportedSubnetDefaultIPv6Route98D952A0": [ + { + "type": "aws:cdk:logicalId", + "data": "ImportedNewVPCAddnewImportedSubnetDefaultIPv6Route98D952A0", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } + ], + "ImportedNewVPCAddnewImportedSubnet2DefaultIPv6Route1EBC364B": [ + { + "type": "aws:cdk:logicalId", + "data": "ImportedNewVPCAddnewImportedSubnet2DefaultIPv6Route1EBC364B", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" + ] + } ] }, "displayName": "vpcv2-import-integ-test" diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/tree.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/tree.json index 07667e1059825..9bb101833e472 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/tree.json @@ -85,42 +85,6 @@ "version": "0.0.0" } }, - "AddnewImportedSubnet-DefaultIPv6Route": { - "id": "AddnewImportedSubnet-DefaultIPv6Route", - "path": "vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet-DefaultIPv6Route", - "children": { - "Route": { - "id": "Route", - "path": "vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet-DefaultIPv6Route/Route", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::Route", - "aws:cdk:cloudformation:props": { - "destinationIpv6CidrBlock": "::/0", - "gatewayId": { - "Fn::GetAtt": [ - "ImportedNewVPCInternetGatewayIGWA7EB1B6C", - "InternetGatewayId" - ] - }, - "routeTableId": { - "Fn::GetAtt": [ - "AddnewImportedSubnetRouteTable73C1E1B7", - "RouteTableId" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.Route", - "version": "0.0.0" - } - }, "AddnewImportedSubnet-DefaultRoute": { "id": "AddnewImportedSubnet-DefaultRoute", "path": "vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet-DefaultRoute", @@ -157,42 +121,6 @@ "version": "0.0.0" } }, - "AddnewImportedSubnet2-DefaultIPv6Route": { - "id": "AddnewImportedSubnet2-DefaultIPv6Route", - "path": "vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet2-DefaultIPv6Route", - "children": { - "Route": { - "id": "Route", - "path": "vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet2-DefaultIPv6Route/Route", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::EC2::Route", - "aws:cdk:cloudformation:props": { - "destinationIpv6CidrBlock": "::/0", - "gatewayId": { - "Fn::GetAtt": [ - "ImportedNewVPCInternetGatewayIGWA7EB1B6C", - "InternetGatewayId" - ] - }, - "routeTableId": { - "Fn::GetAtt": [ - "AddnewImportedSubnet2RouteTable2F07FB4F", - "RouteTableId" - ] - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-ec2-alpha.Route", - "version": "0.0.0" - } - }, "AddnewImportedSubnet2-DefaultRoute": { "id": "AddnewImportedSubnet2-DefaultRoute", "path": "vpcv2-import-integ-test/ImportedNewVPC/AddnewImportedSubnet2-DefaultRoute", @@ -356,7 +284,6 @@ "assignIpv6AddressOnCreation": false, "availabilityZone": "us-west-2a", "cidrBlock": "10.2.2.0/24", - "ipv6CidrBlock": "2600:1f14:b1d:6500::/64", "vpcId": "vpc-08193db3ccc4f909f" } }, @@ -438,7 +365,6 @@ "assignIpv6AddressOnCreation": false, "availabilityZone": "us-west-2a", "cidrBlock": "10.3.2.0/24", - "ipv6CidrBlock": "2600:1f14:b1d:6501::/64", "vpcId": "vpc-08193db3ccc4f909f" } }, diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.assets.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.assets.json index 58c63d91d0496..7286ed241f470 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.assets.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "8bcc09e4eceabfb397695075b581f1f4e8f8a03b61ec24651ebe38d9da4f754e": { + "10cbe304a3bd42e3465787e1f8f7f9ab051a9af6b83f2eeb56422e7e3c6e60b1": { "source": { "path": "vpcv2-import-integ-test.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-us-west-2": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2", - "objectKey": "8bcc09e4eceabfb397695075b581f1f4e8f8a03b61ec24651ebe38d9da4f754e.json", + "objectKey": "10cbe304a3bd42e3465787e1f8f7f9ab051a9af6b83f2eeb56422e7e3c6e60b1.json", "region": "us-west-2", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-west-2" } diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.template.json b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.template.json index 0b60ec6faaba1..9b92be0a64da2 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.template.json +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.js.snapshot/vpcv2-import-integ-test.template.json @@ -32,28 +32,6 @@ "ImportedNewVPCInternetGatewayIGWA7EB1B6C" ] }, - "ImportedNewVPCAddnewImportedSubnetDefaultIPv6Route98D952A0": { - "Type": "AWS::EC2::Route", - "Properties": { - "DestinationIpv6CidrBlock": "::/0", - "GatewayId": { - "Fn::GetAtt": [ - "ImportedNewVPCInternetGatewayIGWA7EB1B6C", - "InternetGatewayId" - ] - }, - "RouteTableId": { - "Fn::GetAtt": [ - "AddnewImportedSubnetRouteTable73C1E1B7", - "RouteTableId" - ] - } - }, - "DependsOn": [ - "ImportedNewVPCInternetGatewayGWAttachment5928F3D0", - "ImportedNewVPCInternetGatewayIGWA7EB1B6C" - ] - }, "ImportedNewVPCAddnewImportedSubnetDefaultRoute40344A0C": { "Type": "AWS::EC2::Route", "Properties": { @@ -76,28 +54,6 @@ "ImportedNewVPCInternetGatewayIGWA7EB1B6C" ] }, - "ImportedNewVPCAddnewImportedSubnet2DefaultIPv6Route1EBC364B": { - "Type": "AWS::EC2::Route", - "Properties": { - "DestinationIpv6CidrBlock": "::/0", - "GatewayId": { - "Fn::GetAtt": [ - "ImportedNewVPCInternetGatewayIGWA7EB1B6C", - "InternetGatewayId" - ] - }, - "RouteTableId": { - "Fn::GetAtt": [ - "AddnewImportedSubnet2RouteTable2F07FB4F", - "RouteTableId" - ] - } - }, - "DependsOn": [ - "ImportedNewVPCInternetGatewayGWAttachment5928F3D0", - "ImportedNewVPCInternetGatewayIGWA7EB1B6C" - ] - }, "ImportedNewVPCAddnewImportedSubnet2DefaultRouteE8630009": { "Type": "AWS::EC2::Route", "Properties": { @@ -150,7 +106,6 @@ "AssignIpv6AddressOnCreation": false, "AvailabilityZone": "us-west-2a", "CidrBlock": "10.2.2.0/24", - "Ipv6CidrBlock": "2600:1f14:b1d:6500::/64", "VpcId": "vpc-08193db3ccc4f909f" } }, @@ -180,7 +135,6 @@ "AssignIpv6AddressOnCreation": false, "AvailabilityZone": "us-west-2a", "CidrBlock": "10.3.2.0/24", - "Ipv6CidrBlock": "2600:1f14:b1d:6501::/64", "VpcId": "vpc-08193db3ccc4f909f" } }, diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/vpcv2-import.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/vpcv2-import.test.ts new file mode 100644 index 0000000000000..1e130d2c514ce --- /dev/null +++ b/packages/@aws-cdk/aws-ec2-alpha/test/vpcv2-import.test.ts @@ -0,0 +1,190 @@ +import * as cdk from 'aws-cdk-lib'; +import { VpcV2 } from '../lib/vpc-v2'; +import { IpCidr, SubnetV2, VpcV2Base } from '../lib/'; +import { Template } from 'aws-cdk-lib/assertions'; +import { InterfaceVpcEndpointAwsService, SubnetType } from 'aws-cdk-lib/aws-ec2'; + +describe('Vpc V2 with full control', () => { + let stack: cdk.Stack; + + beforeEach(() => { + const app = new cdk.App({ + context: { + '@aws-cdk/core:newStyleStackSynthesis': false, + }, + }); + stack = new cdk.Stack(app); + }); + + test('VpcV2.fromVpcV2attributes creates correct vpcArn', () => { + const importedVpc = VpcV2.fromVpcV2attributes(stack, 'VpcWithArn', { + vpcId: 'vpc-12345', + vpcCidrBlock: '10.0.0.0/16', + }); + expect(importedVpc.vpcArn).toBe(`arn:${cdk.Stack.of(stack).partition}:ec2:${cdk.Stack.of(stack).region}:${cdk.Stack.of(stack).account}:vpc/vpc-12345`); + }); + + test('VpcV2.fromVpcV2attributes returns an instance of IVpcV2', () => { + const importedVpc = VpcV2.fromVpcV2attributes(stack, 'VpcInstance', { + vpcId: 'vpc-12345', + vpcCidrBlock: '10.0.0.0/16', + }); + expect(importedVpc).toBeInstanceOf(VpcV2Base); + }); + + test('Import VPC successfully', () => { + const vpc = VpcV2.fromVpcV2attributes(stack, 'ImportedVpc', { + vpcId: 'XXXXXXXXX', + vpcCidrBlock: '10.1.0.0/16', + publicSubnets: [{ + subnetId: 'subnet-isolated1', + availabilityZone: 'us-east-1a', + ipv4CidrBlock: '10.0.4.0/24', + subnetType: SubnetType.PUBLIC, + routeTableId: 'mockRouteTableId', + }], + }); + vpc.addInterfaceEndpoint('ec2', { + service: InterfaceVpcEndpointAwsService.SNS, + }); + const template = Template.fromStack(stack); + template.resourceCountIs('AWS::EC2::VPCEndpoint', 1); + }); + + test('Import different type of subnets successfully', () => { + const importedVpc = VpcV2.fromVpcV2attributes(stack, 'ImportedVpc', { + vpcId: 'vpc-12345', + vpcCidrBlock: '10.0.0.0/16', + secondaryCidrBlocks: [ + { + amazonProvidedIpv6CidrBlock: true, + }, + ], + isolatedSubnets: [{ + subnetId: 'subnet-isolated1', + subnetName: 'mockisolatedsubnet', + availabilityZone: 'us-east-1a', + ipv4CidrBlock: '10.0.4.0/24', + subnetType: SubnetType.PRIVATE_ISOLATED, + routeTableId: 'mockRouteTableId', + }, { + subnetId: 'subnet-isolated2', + subnetName: 'mockisolatedsubnet2', + availabilityZone: 'us-east-1b', + ipv4CidrBlock: '10.0.5.0/24', + subnetType: SubnetType.PRIVATE_ISOLATED, + routeTableId: 'mockRouteTableId', + }], + }); + + importedVpc.addEgressOnlyInternetGateway({ subnets: [{ subnetType: SubnetType.PRIVATE_ISOLATED }] } ); + + Template.fromStack(stack).hasResourceProperties('AWS::EC2::EgressOnlyInternetGateway', { + VpcId: 'vpc-12345', + }); + + Template.fromStack(stack).hasResourceProperties('AWS::EC2::Route', { + EgressOnlyInternetGatewayId: { 'Fn::GetAtt': ['ImportedVpcEgressOnlyGWEIGW5788B31B', 'Id'] }, + DestinationIpv6CidrBlock: '::/0', + RouteTableId: 'mockRouteTableId', + }); + + expect(importedVpc.isolatedSubnets.length).toBe(2); + }); + + test('Import VPC with secondary address Ipv4 successfully', () => { + const vpc = VpcV2.fromVpcV2attributes(stack, 'ImportedVpc', { + vpcId: 'mockVpcID', + vpcCidrBlock: '10.0.0.0/16', + secondaryCidrBlocks: [ + { + cidrBlock: '10.1.0.0/16', + }, + ], + }); + //Subnet with secondary address + new SubnetV2(stack, 'testsubnet', { + vpc, + availabilityZone: 'us-west-2a', + ipv4CidrBlock: new IpCidr('10.1.0.0/24'), + subnetType: SubnetType.PRIVATE_ISOLATED, + }); + Template.fromStack(stack).hasResourceProperties('AWS::EC2::Subnet', { + CidrBlock: '10.1.0.0/24', + }); + }); + + test('Import VPC with IPAM IPv4', () => { + const vpc = VpcV2.fromVpcV2attributes(stack, 'ImportedVpc', { + vpcId: 'mockVpcID', + vpcCidrBlock: '10.0.0.0/16', + secondaryCidrBlocks: [{ + ipv4IpamPoolId: 'ipam-pool-0d53ae29b3b8ca8de', + ipv4ProvisionedCidrs: ['10.2.0.0/16'], + cidrBlockName: 'ImportedIpamIpv4', + }], + }); + //Subnet with secondary address from IPAM range + new SubnetV2(stack, 'testsubnet', { + vpc, + availabilityZone: 'us-west-2a', + ipv4CidrBlock: new IpCidr('10.2.0.0/24'), + subnetType: SubnetType.PRIVATE_ISOLATED, + }); + Template.fromStack(stack).hasResourceProperties('AWS::EC2::Subnet', { + CidrBlock: '10.2.0.0/24', + }); + }); + + test('Import VPC with IPAM IPv6', () => { + const vpc = VpcV2.fromVpcV2attributes(stack, 'ImportedVpc', { + vpcId: 'mockVpcID', + vpcCidrBlock: '10.0.0.0/16', + secondaryCidrBlocks: [{ + ipv6IpamPoolId: 'ipam-pool-0316c6848898c09e0', + ipv6NetmaskLength: 52, + cidrBlockName: 'ImportedIpamIpv6', + }], + }); + //will throw error if IPv6 not enabled using IPAM ipv6 + vpc.addEgressOnlyInternetGateway(); + + //will throw error if IPv6 not enabled using Amazon Provided IPv6 + new SubnetV2(stack, 'AddnewSubnettoImportedIpam', { + availabilityZone: 'us-west-2a', + ipv4CidrBlock: new IpCidr('10.0.1.0/28'), + //can be uncommented and modified after allocation is done using IPAM - Amazon Provided Ipv6 + ipv6CidrBlock: new IpCidr('2600:1f24:6c:4000::/64'), + vpc: vpc, + subnetType: SubnetType.PUBLIC, + }); + Template.fromStack(stack).hasResourceProperties('AWS::EC2::Subnet', { + Ipv6CidrBlock: '2600:1f24:6c:4000::/64', + }); + }); + + test('Import VPC with secondary address amazon provided Ipv6 successfully', () => { + const vpc = VpcV2.fromVpcV2attributes(stack, 'ImportedVpc', { + vpcId: 'mockVpcID', + vpcCidrBlock: '10.0.0.0/16', + secondaryCidrBlocks: [{ + amazonProvidedIpv6CidrBlock: true, + }], + }); + //will throw error if IPv6 not enabled using Amazon Provided IPv6 + vpc.addEgressOnlyInternetGateway(); + //will throw error if IPv6 not enabled using Amazon Provided IPv6 + new SubnetV2(stack, 'AddnewSubnettoImportedIpam', { + availabilityZone: 'us-west-2a', + ipv4CidrBlock: new IpCidr('10.0.1.0/28'), + //can be uncommented and modified after allocation is done using IPAM - Amazon Provided Ipv6 + ipv6CidrBlock: new IpCidr('2600:1f24:6c:4000::/64'), + vpc: vpc, + subnetType: SubnetType.PUBLIC, + }); + Template.fromStack(stack).hasResourceProperties('AWS::EC2::Subnet', { + Ipv6CidrBlock: '2600:1f24:6c:4000::/64', + }); + }); + +});