Skip to content

Commit

Permalink
feat(vpcv2): implementation of add gateway method (#31224)
Browse files Browse the repository at this point in the history
### Issue # (if applicable)

Tracking  #[30762](#30762).

### Reason for this change

implementing below methods for vpcV2.
`routeTable.addroute(destination, target)`:   Adds a new route to the existing route table of the subnet.

`vpc.enableVpnGatewayV2()`:  added a new function for the customer to add VPNGateway to their VPC. In the options, user can specify list of subnets for VPNRoutePropogation. This is similar to previous implementation, only difference is with VPNGateway L2, it is now creating VPNGatewayV2 which implements IRouteTarget and hence can be used a destination to be set up in route tables.

`addInternetGateway` : adds internetGW to the VPC. 
**Default behaviour:**  add default route with destination set to ‘0.0.0.0’ and ‘::0’(in case of subnet with ipv6). Also a check in place to verify SubnetType is set to public as IGW is meant to be added to public subnets.

`addNatGateway`:  NatGateways are subnet specific and are usually associated with PRIVATE_WITH_EGRESS or PUBLIC subnet. Also, one can’t attach NGW(Public) to subnet if VPC doesn’t have an IGW attached to it. This is validated in method implementation to prevent runtime deployment error.

**No default behaviour** for the routes, it takes in the single subnet option and associates a NATGW with it. 

`vpc.addEgressOnlyInternetGateway()`: Egress Only internet GW are meant for outbound ipv6 traffic which can be custom or all ipv6(::/0).

**Default behaviour:** Associates a EIGW to the vpc and takes optional input for subnets to define a default route in associated route Table, if a destination is not provided, then it is defined as all outbound ipv6 in subnet’s route table.

**Additional changes:**
-> Modify Readme
-> Separate ipam related Tests

### Use Case


Allows user to define gateways in their vpc with a simple method and an optional default route setup on provided subnets.


Note: Breaking change since previously VPNGateway was released under route class,  we’ve modified it to VPNGatewayV2.
`vpc.enableVpnGateway` is marked as deprecated in vpcv2 base class.

### Description of how you validated changes

Added unit tests and integration tests.

### 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)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
shikha372 authored Sep 12, 2024
1 parent 6d91ff3 commit 4b90bfc
Show file tree
Hide file tree
Showing 62 changed files with 4,568 additions and 2,148 deletions.
239 changes: 200 additions & 39 deletions packages/@aws-cdk/aws-ec2-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ To create a VPC with both IPv4 and IPv6 support:
```ts

const stack = new Stack();
new vpc_v2.VpcV2(this, 'Vpc', {
primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.0.0.0/24'),
new VpcV2(this, 'Vpc', {
primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/24'),
secondaryAddressBlocks: [
vpc_v2.IpAddresses.amazonProvidedIpv6({cidrBlockName: 'AmazonProvidedIpv6'}),
IpAddresses.amazonProvidedIpv6({cidrBlockName: 'AmazonProvidedIpv6'}),
],
});
```
Expand All @@ -47,18 +47,18 @@ This new construct can be used to add subnets to a `VpcV2` instance:
```ts

const stack = new Stack();
const myVpc = new vpc_v2.VpcV2(this, 'Vpc', {
const myVpc = new VpcV2(this, 'Vpc', {
secondaryAddressBlocks: [
vpc_v2.IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonProvidedIp'}),
IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonProvidedIp'}),
],
});

new vpc_v2.SubnetV2(this, 'subnetA', {
new SubnetV2(this, 'subnetA', {
vpc: myVpc,
availabilityZone: 'us-east-1a',
ipv4CidrBlock: new vpc_v2.IpCidr('10.0.0.0/24'),
ipv6CidrBlock: new vpc_v2.IpCidr('2a05:d02c:25:4000::/60'),
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
ipv6CidrBlock: new IpCidr('2a05:d02c:25:4000::/60'),
subnetType: SubnetType.PRIVATE_ISOLATED,
})
```

Expand All @@ -77,28 +77,28 @@ const ipam = new Ipam(this, 'Ipam', {
operatingRegion: ['us-west-1']
});
const ipamPublicPool = ipam.publicScope.addPool('PublicPoolA', {
addressFamily: vpc_v2.AddressFamily.IP_V6,
addressFamily: AddressFamily.IP_V6,
awsService: AwsServiceName.EC2,
locale: 'us-west-1',
publicIpSource: vpc_v2.IpamPoolPublicIpSource.AMAZON,
publicIpSource: IpamPoolPublicIpSource.AMAZON,
});
ipamPublicPool.provisionCidr('PublicPoolACidrA', { netmaskLength: 52 } );

const ipamPrivatePool = ipam.privateScope.addPool('PrivatePoolA', {
addressFamily: vpc_v2.AddressFamily.IP_V4,
addressFamily: AddressFamily.IP_V4,
});
ipamPrivatePool.provisionCidr('PrivatePoolACidrA', { netmaskLength: 8 } );

new vpc_v2.VpcV2(this, 'Vpc', {
primaryAddressBlock: vpc_v2.IpAddresses.ipv4('10.0.0.0/24'),
new VpcV2(this, 'Vpc', {
primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/24'),
secondaryAddressBlocks: [
vpc_v2.IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonIpv6' }),
vpc_v2.IpAddresses.ipv6Ipam({
IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonIpv6' }),
IpAddresses.ipv6Ipam({
ipamPool: ipamPublicPool,
netmaskLength: 52,
cidrBlockName: 'ipv6Ipam',
}),
vpc_v2.IpAddresses.ipv4Ipam({
IpAddresses.ipv4Ipam({
ipamPool: ipamPrivatePool,
netmaskLength: 8,
cidrBlockName: 'ipv4Ipam',
Expand All @@ -116,64 +116,88 @@ Since `VpcV2` does not create subnets automatically, users have full control ove

```ts

const myVpc = new vpc_v2.VpcV2(this, 'Vpc');
const routeTable = new vpc_v2.RouteTable(this, 'RouteTable', {
const myVpc = new VpcV2(this, 'Vpc');
const routeTable = new RouteTable(this, 'RouteTable', {
vpc: myVpc,
});
const subnet = new vpc_v2.SubnetV2(this, 'Subnet', {
const subnet = new SubnetV2(this, 'Subnet', {
vpc: myVpc,
routeTable,
availabilityZone: 'eu-west-2a',
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
subnetType: SubnetType.PRIVATE_ISOLATED,
});
```

`Route`s can be created to link subnets to various different AWS services via gateways and endpoints. Each unique route target has its own dedicated construct that can be routed to a given subnet via the `Route` construct. An example using the `InternetGateway` construct can be seen below:
`Routes` can be created to link subnets to various different AWS services via gateways and endpoints. Each unique route target has its own dedicated construct that can be routed to a given subnet via the `Route` construct. An example using the `InternetGateway` construct can be seen below:

```ts
const stack = new Stack();
const myVpc = new vpc_v2.VpcV2(this, 'Vpc');
const routeTable = new vpc_v2.RouteTable(this, 'RouteTable', {
const myVpc = new VpcV2(this, 'Vpc');
const routeTable = new RouteTable(this, 'RouteTable', {
vpc: myVpc,
});
const subnet = new vpc_v2.SubnetV2(this, 'Subnet', {
const subnet = new SubnetV2(this, 'Subnet', {
vpc: myVpc,
availabilityZone: 'eu-west-2a',
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
subnetType: ec2.SubnetType.PRIVATE_ISOLATED });
subnetType: SubnetType.PRIVATE_ISOLATED });

const igw = new vpc_v2.InternetGateway(this, 'IGW', {
const igw = new InternetGateway(this, 'IGW', {
vpc: myVpc,
});
new vpc_v2.Route(this, 'IgwRoute', {
new Route(this, 'IgwRoute', {
routeTable,
destination: '0.0.0.0/0',
target: { gateway: igw },
});
```

Alternatively, `Routes` can also be created via method `addRoute` in the `RouteTable` class. An example using the `EgressOnlyInternetGateway` construct can be seen below:
Note: `EgressOnlyInternetGateway` can only be used to set up outbound IPv6 routing.

```ts

const stack = new Stack();
const myVpc = new VpcV2(this, 'Vpc',{
primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),
secondaryAddressBlocks: [IpAddresses.amazonProvidedIpv6({
cidrBlockName: 'AmazonProvided',
})]
});

const eigw = new EgressOnlyInternetGateway(this, 'EIGW', {
vpc: myVpc,
});

const routeTable = new RouteTable(this, 'RouteTable', {
vpc: myVpc,
});

routeTable.addRoute('EIGW', '::/0', { gateway: eigw });
```

Other route targets may require a deeper set of parameters to set up properly. For instance, the example below illustrates how to set up a `NatGateway`:

```ts

const myVpc = new vpc_v2.VpcV2(this, 'Vpc');
const routeTable = new vpc_v2.RouteTable(this, 'RouteTable', {
const myVpc = new VpcV2(this, 'Vpc');
const routeTable = new RouteTable(this, 'RouteTable', {
vpc: myVpc,
});
const subnet = new vpc_v2.SubnetV2(this, 'Subnet', {
const subnet = new SubnetV2(this, 'Subnet', {
vpc: myVpc,
availabilityZone: 'eu-west-2a',
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
subnetType: ec2.SubnetType.PRIVATE_ISOLATED });
subnetType: SubnetType.PRIVATE_ISOLATED });

const natgw = new vpc_v2.NatGateway(this, 'NatGW', {
const natgw = new NatGateway(this, 'NatGW', {
subnet: subnet,
vpc: myVpc,
connectivityType: NatConnectivityType.PRIVATE,
privateIpAddress: '10.0.0.42',
});
new vpc_v2.Route(this, 'NatGwRoute', {
new Route(this, 'NatGwRoute', {
routeTable,
destination: '0.0.0.0/0',
target: { gateway: natgw },
Expand All @@ -184,24 +208,161 @@ It is also possible to set up endpoints connecting other AWS services. For insta

```ts

const myVpc = new vpc_v2.VpcV2(this, 'Vpc');
const routeTable = new vpc_v2.RouteTable(this, 'RouteTable', {
const stack = new Stack();
const myVpc = new VpcV2(this, 'Vpc');
const routeTable = new RouteTable(this, 'RouteTable', {
vpc: myVpc,
});
const subnet = new vpc_v2.SubnetV2(this, 'Subnet', {
const subnet = new SubnetV2(this, 'Subnet', {
vpc: myVpc,
availabilityZone: 'eu-west-2a',
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
subnetType: ec2.SubnetType.PRIVATE });
subnetType: SubnetType.PRIVATE });

const dynamoEndpoint = new ec2.GatewayVpcEndpoint(this, 'DynamoEndpoint', {
service: ec2.GatewayVpcEndpointAwsService.DYNAMODB,
vpc: myVpc,
subnets: [subnet],
});
new vpc_v2.Route(this, 'DynamoDBRoute', {
new Route(this, 'DynamoDBRoute', {
routeTable,
destination: '0.0.0.0/0',
target: { endpoint: dynamoEndpoint },
});
```

## Adding Egress-Only Internet Gateway to VPC

An egress-only internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows outbound communication over IPv6 from instances in your VPC to the internet, and prevents the internet from initiating an IPv6 connection with your instances.

For more information see [Enable outbound IPv6 traffic using an egress-only internet gateway](https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html).

VpcV2 supports adding an egress only internet gateway to VPC using the `addEgressOnlyInternetGateway` method.

By default, this method sets up a route to all outbound IPv6 address ranges, unless a specific destination is provided by the user. It can only be configured for IPv6-enabled VPCs.
The `Subnets` parameter accepts a `SubnetFilter`, which can be based on a `SubnetType` in VpcV2. A new route will be added to the route tables of all subnets that match this filter.

```ts

const stack = new Stack();
const myVpc = new VpcV2(this, 'Vpc',{
primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),
secondaryAddressBlocks: [IpAddresses.amazonProvidedIpv6({
cidrBlockName: 'AmazonProvided',
})]
});
const routeTable = new RouteTable(this, 'RouteTable', {
vpc: myVpc,
});
const subnet = new SubnetV2(this, 'Subnet', {
vpc: myVpc,
availabilityZone: 'eu-west-2a',
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
ipv6CidrBlock: new IpCidr('2001:db8:1::/64'),
subnetType: SubnetType.PRIVATE });

myVpc.addEgressOnlyInternetGateway({
subnets: [{subnetType: SubnetType.PRIVATE}],
destination: '::/60',
})
```

## Adding NATGateway to the VPC

A NAT gateway is a Network Address Translation (NAT) service.You can use a NAT gateway so that instances in a private subnet can connect to services outside your VPC but external services cannot initiate a connection with those instances.

For more information, see [NAT gateway basics](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html).

When you create a NAT gateway, you specify one of the following connectivity types:

**Public – (Default)**: Instances in private subnets can connect to the internet through a public NAT gateway, but cannot receive unsolicited inbound connections from the internet

**Private**: Instances in private subnets can connect to other VPCs or your on-premises network through a private NAT gateway.

To define the NAT gateway connectivity type as `ConnectivityType.Public`, you need to ensure that there is an IGW(Internet Gateway) attached to the subnet's VPC.
Since a NATGW is associated with a particular subnet, providing `subnet` field in the input props is mandatory.

Additionally, you can set up a route in any route table with the target set to the NAT Gateway. The function `addNatGateway` returns a `NATGateway` object that you can reference later.

The code example below provides the definition for adding a NAT gateway to your subnet:

```ts

const stack = new Stack();
const myVpc = new VpcV2(this, 'Vpc');
const routeTable = new RouteTable(this, 'RouteTable', {
vpc: myVpc,
});
const subnet = new SubnetV2(this, 'Subnet', {
vpc: myVpc,
availabilityZone: 'eu-west-2a',
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
subnetType: SubnetType.PUBLIC });

myVpc.addInternetGateway();
myVpc.addNatGateway({
subnet: subnet,
connectivityType: NatConnectivityType.PUBLIC,
});
```

## Enable VPNGateway for the VPC

A virtual private gateway is the endpoint on the VPC side of your VPN connection.

For more information, see [What is AWS Site-to-Site VPN?](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html).

VPN route propagation is a feature in Amazon Web Services (AWS) that automatically updates route tables in your Virtual Private Cloud (VPC) with routes learned from a VPN connection.

To enable VPN route propogation, use the `vpnRoutePropagation` property to specify the subnets as an input to the function. VPN route propagation will then be enabled for each subnet with the corresponding route table IDs.

Additionally, you can set up a route in any route table with the target set to the VPN Gateway. The function `enableVpnGatewayV2` returns a `VPNGatewayV2` object that you can reference later.

The code example below provides the definition for setting up a VPN gateway with `vpnRoutePropogation` enabled:

```ts

const stack = new Stack();
const myVpc = new VpcV2(this, 'Vpc');
const vpnGateway = myVpc.enableVpnGatewayV2({
vpnRoutePropagation: [{ subnetType: SubnetType.PUBLIC }],
type: VpnConnectionType.IPSEC_1,
});

const routeTable = new RouteTable(stack, 'routeTable', {
vpc: myVpc
} );

new Route(stack, 'route', {
destination: '172.31.0.0/24',
target: { gateway: vpnGateway },
routeTable: routeTable,
});
```

## Adding InternetGateway to the VPC

An internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows communication between your VPC and the internet. It supports both IPv4 and IPv6 traffic.

For more information, see [Enable VPC internet access using internet gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-igw-internet-access.html).

You can add an internet gateway to a VPC using `addInternetGateway` method. By default, this method creates a route in all Public Subnets with outbound destination set to `0.0.0.0` for IPv4 and `::0` for IPv6 enabled VPC.
Instead of using the default settings, you can configure a custom destinatation range by providing an optional input `destination` to the method.

The code example below shows how to add an internet gateway with a custom outbound destination IP range:

```ts

const stack = new Stack();
const myVpc = new VpcV2(this, 'Vpc');

const subnet = new SubnetV2(this, 'Subnet', {
vpc: myVpc,
availabilityZone: 'eu-west-2a',
ipv4CidrBlock: new IpCidr('10.0.0.0/24'),
subnetType: SubnetType.PUBLIC });

myVpc.addInternetGateway({
ipv4Destination: '192.168.0.0/16',
});
```
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-ec2-alpha/awslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"exclude": [
"from-method:@aws-cdk/aws-ec2-alpha.VpcV2",
"attribute-tag:@aws-cdk/aws-ec2-alpha.RouteTable.routeTableId",
"from-method:@aws-cdk/aws-ec2-alpha.SubnetV2"
"from-method:@aws-cdk/aws-ec2-alpha.SubnetV2",
"from-method:@aws-cdk/aws-ec2-alpha.Route"
]
}
Loading

0 comments on commit 4b90bfc

Please sign in to comment.