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(vpcv2): add BYOIP for IPv6 functionality #32397

Closed
wants to merge 14 commits into from
25 changes: 25 additions & 0 deletions packages/@aws-cdk/aws-ec2-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,31 @@ new VpcV2(this, 'Vpc', {

Since `VpcV2` does not create subnets automatically, users have full control over IP addresses allocation across subnets.

### Bring your own IPv6 addresses (BYOIP)

If you have your own IP address that you would like to use with EC2, you can set up an IPv6 pool via the AWS CLI, and use that pool ID in your application.

Once you have certified your IP address block with an ROA and have an X509 certificate, you can run the following command to provision your CIDR block with AWS:

```shell
aws ec2 provision-byoip-cidr --region <region> --cidr <your CIDR block> --cidr-authorization-context Message="1|aws|<account>|<your CIDR block>|<expiration date>|SHA256".Signature="<signature>"
```

For more help on setting up your IPv6 address, please review the [EC2 Documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html).

Once you have provisioned your address block, you can use the IPv6 in your VPC as follows:
Leo10Gama marked this conversation as resolved.
Show resolved Hide resolved

```ts
const myVpc = new VpcV2(this, 'Vpc', {
primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'),
secondaryAddressBlocks: [vpc.IpAddresses.ipv6Pool('2001:db8::/32', {
cidrBlockName: 'MyByoipCidrBlock',
ipv6Pool: 'MyByoipPool',
})],
enableDnsHostnames: true,
enableDnsSupport: true,
});
```

## Routing

Expand Down
82 changes: 82 additions & 0 deletions packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ export interface SecondaryAddressProps {
readonly cidrBlockName: string;
}

/**
* Additional props needed for BYOIP IPv6 address props
*/
export interface Ipv6PoolSecondaryAddressProps extends SecondaryAddressProps {
/**
* ID of the IPv6 address pool from which to allocate the IPv6 CIDR block
*
* @default - None
*/
readonly ipv6Pool?: string;
Leo10Gama marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* IpAddress options to define VPC V2
*/
Expand All @@ -29,6 +41,13 @@ export class IpAddresses {
return new ipv4CidrAllocation(ipv4Cidr, props);
}

/**
* A BYOIP IPv6 address pool
*/
public static ipv6Pool(ipv6Cidr: string, props?: Ipv6PoolSecondaryAddressProps): IIpAddresses {
return new Ipv6Pool(ipv6Cidr, props);
}

/**
* An Ipv4 Ipam Pool
*/
Expand Down Expand Up @@ -121,6 +140,20 @@ export interface VpcCidrOptions {
* @default - no IPAM IPv4 CIDR range is provisioned using IPAM
*/
readonly ipv4IpamProvisionedCidrs?: string[];

/**
* IPv6 CIDR block from the IPv6 address pool.
*
* @default - None
*/
readonly ipv6CidrBlock?: string;

/**
* ID of the IPv6 address pool from which to allocate the IPv6 CIDR block
*
* @default - None
*/
readonly ipv6Pool?: string;
}

/**
Expand Down Expand Up @@ -506,6 +539,8 @@ export class VpcV2 extends VpcV2Base {
ipv4NetmaskLength: secondaryVpcOptions.ipv4NetmaskLength,
ipv6NetmaskLength: secondaryVpcOptions.ipv6NetmaskLength,
ipv6IpamPoolId: secondaryVpcOptions.ipv6IpamPool?.ipamPoolId,
ipv6CidrBlock: secondaryVpcOptions?.ipv6CidrBlock,
ipv6Pool: secondaryVpcOptions?.ipv6Pool,
amazonProvidedIpv6CidrBlock: secondaryVpcOptions.amazonProvided,
});
if (secondaryVpcOptions.dependencies) {
Expand Down Expand Up @@ -559,6 +594,23 @@ class ipv4CidrAllocation implements IIpAddresses {
}
}

/**
* Supports assigning IPv6 address to VPC in an address pool
*/
class Ipv6Pool implements IIpAddresses {

constructor(private readonly cidrBlock: string, private readonly props?: Ipv6PoolSecondaryAddressProps) {
}

allocateVpcCidr(): VpcCidrOptions {
return {
ipv6CidrBlock: this.cidrBlock,
ipv6Pool: this.props?.ipv6Pool,
cidrBlockName: this.props?.cidrBlockName,
};
}
}

/**
* Supports Amazon Provided Ipv6 ranges
*/
Expand Down Expand Up @@ -645,6 +697,16 @@ export interface IVPCCidrBlock {
* IPAM pool for IPv4 address type
*/
readonly ipv4IpamPoolId ?: string;

/**
* The IPv6 CIDR block from the specified IPv6 address pool.
*/
readonly ipv6CidrBlock?: string;

/**
* The ID of the IPv6 address pool from which to allocate the IPv6 CIDR block.
*/
readonly ipv6Pool?: string;
}

/**
Expand Down Expand Up @@ -708,6 +770,20 @@ export interface VPCCidrBlockattributes {
* @default - no IPAM IPv4 CIDR range is provisioned using IPAM
*/
readonly ipv4IpamProvisionedCidrs?: string[];

/**
* The IPv6 CIDR block from the specified IPv6 address pool.
*
* @default - None
*/
readonly ipv6CidrBlock?: string;

/**
* The ID of the IPv6 address pool from which to allocate the IPv6 CIDR block.
*
* @default - None
*/
readonly ipv6Pool?: string;
}

/**
Expand Down Expand Up @@ -749,13 +825,19 @@ class VPCCidrBlock extends Resource implements IVPCCidrBlock {

public readonly ipv4IpamPoolId?: string;

public readonly ipv6CidrBlock?: string;

public readonly ipv6Pool?: string;

constructor(scope: Construct, id: string, props: VPCCidrBlockProps) {
super(scope, id);
this.resource = new CfnVPCCidrBlock(this, id, props);
this.node.defaultChild = this.resource;
this.cidrBlock = props.cidrBlock;
this.ipv6IpamPoolId = props.ipv6IpamPoolId;
this.ipv4IpamPoolId = props.ipv4IpamPoolId;
this.ipv6CidrBlock = props.ipv6CidrBlock;
this.ipv6Pool = props.ipv6Pool;
this.amazonProvidedIpv6CidrBlock = props.amazonProvidedIpv6CidrBlock;
}
}
Expand Down
23 changes: 23 additions & 0 deletions packages/@aws-cdk/aws-ec2-alpha/test/vpc-v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Template } from 'aws-cdk-lib/assertions';
import * as cdk from 'aws-cdk-lib';
import * as vpc from '../lib/vpc-v2';
import { AddressFamily, AwsServiceName, Ipam, IpamPoolPublicIpSource } from '../lib';
/* eslint-disable no-console */

describe('Vpc V2 with full control', () => {
let stack: cdk.Stack;
Expand Down Expand Up @@ -69,7 +70,29 @@ describe('Vpc V2 with full control', () => {
},
},
});
});

test('VPC with secondary IPv6 Pool address', () => {
new vpc.VpcV2(stack, 'TestVpc', {
primaryAddressBlock: vpc.IpAddresses.ipv4('10.1.0.0/16'),
secondaryAddressBlocks: [vpc.IpAddresses.ipv6Pool('2001:db8::/32', {
cidrBlockName: 'SecondaryIPv6',
ipv6Pool: 'SecondaryIPv6Pool',
})],
enableDnsHostnames: true,
enableDnsSupport: true,
});

Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCCidrBlock', {
VpcId: {
'Fn::GetAtt': [
'TestVpcE77CE678',
'VpcId',
],
},
Ipv6CidrBlock: '2001:db8::/32',
Ipv6Pool: 'SecondaryIPv6Pool',
});
});

test('VPC throws error with incorrect cidr range (IPv4)', () => {
Expand Down
Loading
Loading