Skip to content

Commit d108a80

Browse files
authored
feat(ec2-alpha): adding imports for SubnetV2 and VpcV2(WIP) (#31765)
### Issue # (if applicable) Tracking #30762. ### Reason for this change Allow users to define imports for a VPC or subnet defined outside current stack definition. ### Description of changes - Added new methods under VpcV2 and Subnet `VpcV2.fromVpcV2Attributes()` and `SubnetV2.fromSubnetV2Attributes()` - Added new L2 for VPCCidrBlock to allow import of secondary addresses. `VPCCidrBlock` - Added new integration test and unit test file to check import related functionality. - Updated Readme. - Fixed an earlier issue with subnet range check, fixed to include IPAM defined IPv4 address as well ### Description of how you validated changes Deployed and tested for below scenarios in account: 1. Import a VPC with primary IPv4 2. Import a subnet with primary IPv4 3. Import a VPC with multiple secondary IPv4 4. Import a VPC with Amazon provided IPV6 5. Import a VPC with Ipam provided IPv6/IPv4 7. Import subnet individually using fromSubnetV2attributes 8. Imported different type of multiple subnets 9. Add gateways/endpoint to imported vpc ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) BREAKING CHANGE: The new `VpcCidrBlock` L2 construct replaces `CfnVPCCidrBlock`. This change alters the logical ID of `AWS::EC2::VPCCidrBlock` resources in CloudFormation templates. Existing deployments will see errors like `CIDR range conflicts with x.xx.xx.xx/xx with association ID vpc-cidr-assoc-ABCD`. To resolve this, you must recreate your existing stacks to use the new module. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
2 parents 06678a3 + f80fefa commit d108a80

File tree

72 files changed

+3023
-700
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+3023
-700
lines changed

packages/@aws-cdk/aws-ec2-alpha/README.md

+132-4
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ new VpcV2(this, 'Vpc', {
3737

3838
`VpcV2` does not automatically create subnets or allocate IP addresses, which is different from the `Vpc` construct.
3939

40-
Importing existing VPC in an account into CDK as a `VpcV2` is not yet supported.
41-
4240
## SubnetV2
4341

4442
`SubnetV2` is a re-write of the [`ec2.Subnet`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Subnet.html) construct.
@@ -62,8 +60,6 @@ new SubnetV2(this, 'subnetA', {
6260
})
6361
```
6462

65-
Same as `VpcV2`, importing existing subnets is not yet supported.
66-
6763
## IP Addresses Management
6864

6965
By default `VpcV2` uses `10.0.0.0/16` as the primary CIDR if none is defined.
@@ -366,3 +362,135 @@ myVpc.addInternetGateway({
366362
ipv4Destination: '192.168.0.0/16',
367363
});
368364
```
365+
366+
## Importing an existing VPC
367+
368+
You can import an existing VPC and its subnets using the `VpcV2.fromVpcV2Attributes()` method or an individual subnet using `SubnetV2.fromSubnetV2Attributes()` method.
369+
370+
### Importing a VPC
371+
372+
To import an existing VPC, use the `VpcV2.fromVpcV2Attributes()` method. You'll need to provide the VPC ID, primary CIDR block, and information about the subnets. You can import secondary address as well created through IPAM, BYOIP(IPv4) or enabled through Amazon Provided IPv6. You must provide VPC Id and its primary CIDR block for importing it.
373+
374+
If you wish to add a new subnet to imported VPC, new subnet's IP range(IPv4) will be validated against provided secondary and primary address block to confirm that it is within the the range of VPC.
375+
376+
Here's an example of importing a VPC with only the required parameters
377+
378+
``` ts
379+
380+
const stack = new Stack();
381+
382+
const importedVpc = VpcV2.fromVpcV2Attributes(stack, 'ImportedVpc', {
383+
vpcId: 'mockVpcID',
384+
vpcCidrBlock: '10.0.0.0/16',
385+
});
386+
387+
```
388+
389+
In case of cross account or cross region VPC, its recommended to provide region and ownerAccountId so that these values for the VPC can be used to populate correct arn value for the VPC. If a VPC region and account ID is not provided, then region and account configured in the stack will be used. Furthermore, these fields will be referenced later while setting up VPC peering connection, so its necessary to set these fields to a correct value.
390+
391+
Below is an example of importing a cross region and cross acount VPC, VPC arn for this case would be 'arn:aws:ec2:us-west-2:123456789012:vpc/mockVpcID'
392+
393+
``` ts
394+
395+
const stack = new Stack();
396+
397+
//Importing a cross acount or cross region VPC
398+
const importedVpc = VpcV2.fromVpcV2Attributes(stack, 'ImportedVpc', {
399+
vpcId: 'mockVpcID',
400+
vpcCidrBlock: '10.0.0.0/16',
401+
ownerAccountId: '123456789012',
402+
region: 'us-west-2',
403+
});
404+
405+
```
406+
407+
Here's an example of how to import a VPC with multiple CIDR blocks, IPv6 support, and different subnet types:
408+
409+
In this example, we're importing a VPC with:
410+
411+
- A primary CIDR block (10.1.0.0/16)
412+
- One secondary IPv4 CIDR block (10.2.0.0/16)
413+
- Two secondary address using IPAM pool (IPv4 and IPv6)
414+
- VPC has Amazon-provided IPv6 CIDR enabled
415+
- An isolated subnet in us-west-2a
416+
- A public subnet in us-west-2b
417+
418+
```ts
419+
420+
const stack = new Stack();
421+
422+
const importedVpc = VpcV2.fromVpcV2Attributes(this, 'ImportedVPC', {
423+
vpcId: 'vpc-XXX',
424+
vpcCidrBlock: '10.1.0.0/16',
425+
secondaryCidrBlocks: [
426+
{
427+
cidrBlock: '10.2.0.0/16',
428+
cidrBlockName: 'ImportedBlock1',
429+
},
430+
{
431+
ipv6IpamPoolId: 'ipam-pool-XXX',
432+
ipv6NetmaskLength: 52,
433+
cidrBlockName: 'ImportedIpamIpv6',
434+
},
435+
{
436+
ipv4IpamPoolId: 'ipam-pool-XXX',
437+
ipv4IpamProvisionedCidrs: ['10.2.0.0/16'],
438+
cidrBlockName: 'ImportedIpamIpv4',
439+
},
440+
{
441+
amazonProvidedIpv6CidrBlock: true,
442+
}
443+
],
444+
subnets: [{
445+
subnetName: 'IsolatedSubnet2',
446+
subnetId: 'subnet-03cd773c0fe08ed26',
447+
subnetType: SubnetType.PRIVATE_ISOLATED,
448+
availabilityZone: 'us-west-2a',
449+
ipv4CidrBlock: '10.2.0.0/24',
450+
routeTableId: 'rtb-0871c310f98da2cbb',
451+
},
452+
{
453+
subnetId: 'subnet-0fa477e01db27d820',
454+
subnetType: SubnetType.PUBLIC,
455+
availabilityZone: 'us-west-2b',
456+
ipv4CidrBlock: '10.3.0.0/24',
457+
routeTableId: 'rtb-014f3043098fe4b96',
458+
}],
459+
});
460+
461+
// You can now use the imported VPC in your stack
462+
463+
// Adding a new subnet to the imported VPC
464+
const importedSubnet = new SubnetV2(this, 'NewSubnet', {
465+
availabilityZone: 'us-west-2a',
466+
ipv4CidrBlock: new IpCidr('10.2.2.0/24'),
467+
vpc: importedVpc,
468+
subnetType: SubnetType.PUBLIC,
469+
});
470+
471+
// Adding gateways to the imported VPC
472+
importedVpc.addInternetGateway();
473+
importedVpc.addNatGateway({ subnet: importedSubnet });
474+
importedVpc.addEgressOnlyInternetGateway();
475+
```
476+
477+
You can add more subnets as needed by including additional entries in the `isolatedSubnets`, `publicSubnets`, or other subnet type arrays (e.g., `privateSubnets`).
478+
479+
### Importing Subnets
480+
481+
You can also import individual subnets using the `SubnetV2.fromSubnetV2Attributes()` method. This is useful when you need to work with specific subnets independently of a VPC.
482+
483+
Here's an example of how to import a subnet:
484+
485+
```ts
486+
487+
SubnetV2.fromSubnetV2Attributes(this, 'ImportedSubnet', {
488+
subnetId: 'subnet-0123456789abcdef0',
489+
availabilityZone: 'us-west-2a',
490+
ipv4CidrBlock: '10.2.0.0/24',
491+
routeTableId: 'rtb-0871c310f98da2cbb',
492+
subnetType: SubnetType.PRIVATE_ISOLATED,
493+
});
494+
```
495+
496+
By importing existing VPCs and subnets, you can easily integrate your existing AWS infrastructure with new resources created through CDK. This is particularly useful when you need to work with pre-existing network configurations or when you're migrating existing infrastructure to CDK.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
{
22
"exclude": [
3-
"from-method:@aws-cdk/aws-ec2-alpha.VpcV2",
43
"attribute-tag:@aws-cdk/aws-ec2-alpha.RouteTable.routeTableId",
5-
"from-method:@aws-cdk/aws-ec2-alpha.SubnetV2",
64
"from-method:@aws-cdk/aws-ec2-alpha.Route"
75
]
86
}

packages/@aws-cdk/aws-ec2-alpha/lib/ipam.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export enum IpamScopeType {
9292
*
9393
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html
9494
*/
95-
export interface PoolOptions{
95+
export interface PoolOptions {
9696

9797
/**
9898
* addressFamily - The address family of the pool (ipv4 or ipv6).
@@ -180,7 +180,7 @@ export interface IpamPoolCidrProvisioningOptions {
180180
/**
181181
* Definition used to add or create a new IPAM pool
182182
*/
183-
export interface IIpamPool{
183+
export interface IIpamPool {
184184
/**
185185
* Pool ID to be passed to the VPC construct
186186
* @attribute IpamPoolId
@@ -192,6 +192,12 @@ export interface IIpamPool{
192192
*/
193193
readonly ipamCidrs: CfnIPAMPoolCidr[];
194194

195+
/**
196+
* Pool CIDR for IPv4 to be provisioned using IPAM
197+
* Required to check for subnet IP range is within the VPC range
198+
*/
199+
readonly ipamIpv4Cidrs?: string[];
200+
195201
/**
196202
* Function to associate a IPv6 address with IPAM pool
197203
*/
@@ -315,6 +321,12 @@ class IpamPool extends Resource implements IIpamPool {
315321
*/
316322
public readonly ipamCidrs: CfnIPAMPoolCidr[] = []
317323

324+
/**
325+
* Pool CIDR for IPv4 to be provisioned using IPAM
326+
* Required to check for subnet IP range is within the VPC range
327+
*/
328+
public readonly ipamIpv4Cidrs: string[] = []
329+
318330
/**
319331
* Reference to ipamPool resource created in this class
320332
*/
@@ -340,6 +352,9 @@ class IpamPool extends Resource implements IIpamPool {
340352
awsService: props.awsService,
341353
});
342354
this.ipamPoolId = this._ipamPool.attrIpamPoolId;
355+
356+
// Populating to check for subnet range against all IPv4 ranges assigned to VPC including IPAM
357+
props.ipv4ProvisionedCidrs?.map(cidr => (this.ipamIpv4Cidrs.push(cidr)));
343358
this.node.defaultChild = this._ipamPool;
344359
}
345360

0 commit comments

Comments
 (0)