Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ec2): Add SubnetFilter for CIDR Range #27425

Merged
merged 16 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/aws-cdk-lib/aws-ec2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ Which subnets are selected is evaluated as follows:
* `onePerAz`: chooses at most one subnet per availability zone
* `containsIpAddresses`: chooses a subnet which contains *any* of the listed ip addresses
* `byCidrMask`: chooses subnets that have the provided CIDR netmask
* `byCidrRanges`: chooses subnets which are inside any of the specified CIDR Ranges
AlemanCS marked this conversation as resolved.
Show resolved Hide resolved

### Using NAT instances

Expand Down
37 changes: 37 additions & 0 deletions packages/aws-cdk-lib/aws-ec2/lib/subnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ export abstract class SubnetFilter {
return new CidrMaskSubnetFilter(mask);
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Hey, could you add @params for the function argument here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added this @param cidrs List of CIDR ranges to filter subnets from

* Chooses subnets which are inside any of the specified CIDR Range.
*/
public static byCidrRanges(vpcCidrs: string[]): SubnetFilter {
return new CidrRangesSubnetFilter(vpcCidrs);
}

/**
* Executes the subnet filtering logic, returning a filtered set of subnets.
*/
Expand Down Expand Up @@ -169,3 +176,33 @@ class CidrMaskSubnetFilter extends SubnetFilter {
});
}
}

/**
* Chooses subnets based on the CIDR Range
*/
class CidrRangesSubnetFilter extends SubnetFilter {

private readonly cidrRanges: string[]

constructor(cidrRanges: string[]) {
super();
this.cidrRanges = cidrRanges;
}

/**
* Executes the subnet filtering logic.
*/
public selectSubnets(subnets: ISubnet[]): ISubnet[] {
return this.checkCidrRanges(subnets, this.cidrRanges);
}

private checkCidrRanges(subnets: ISubnet[], cidrRanges: string[]): ISubnet[] {
const vpcCidrs = cidrRanges.map(cidr => {
return new CidrBlock(cidr);
});
AlemanCS marked this conversation as resolved.
Show resolved Hide resolved
return subnets.filter(s => {
const subnetCidrBlock = new CidrBlock(s.ipv4CidrBlock);
return vpcCidrs.some(cidr => cidr.containsCidr(subnetCidrBlock));
});
}
}
40 changes: 40 additions & 0 deletions packages/aws-cdk-lib/aws-ec2/test/vpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2261,6 +2261,46 @@ describe('vpc', () => {

});

test('can filter by multiple CIDR Ranges', () => {
AlemanCS marked this conversation as resolved.
Show resolved Hide resolved
// GIVEN
const stack = getTestStack();

// IP space is split into 6 pieces, one public/one private per AZ
const vpc = new Vpc(stack, 'VPC', {
ipAddresses: IpAddresses.cidr('10.0.0.0/16'),
maxAzs: 3,
});

// WHEN
// We want to place this endpoint in the same subnets as these IPv4
// address.
// WHEN
AlemanCS marked this conversation as resolved.
Show resolved Hide resolved
new InterfaceVpcEndpoint(stack, 'VPC Endpoint', {
vpc,
service: new InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443),
subnets: {
subnetFilters: [SubnetFilter.byCidrRanges(['10.0.0.0/16'])],
},
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', {
ServiceName: 'com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc',
SubnetIds: [
{
Ref: 'VPCPrivateSubnet1Subnet8BCA10E0',
},
{
Ref: 'VPCPrivateSubnet2SubnetCFCDAA7A',
},
{
Ref: 'VPCPrivateSubnet3Subnet3EDCD457',
},
],
});

});

test('tests router types', () => {
// GIVEN
const stack = getTestStack();
Expand Down