aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.37k stars 3.77k forks source link

ClientVpnEndpoint: Integration with IPAM for CIDR selection #22889

Open hscheib opened 1 year ago

hscheib commented 1 year ago

Describe the feature

I would like to request the ability to use IPAM for generating a CIDR for a ClientVpnEndpoint. This would be similar to how VPC has integrated with IPAM and can just pick a netmask length and you don't have to create an allocation separately

Use Case

Our team is utilizing AWS IPAM fully and want to automate all CIDR generation. We want to include our VPN client address space in IPAM and ideally its automatically provisioned by just setting a netmask length.

Proposed Solution

Recently VPC with IPAM integration Issue was merged allowing VPC creation to set an IPAM poolID and masks to auto allocate unused range to a VPC as seen below.

    const vpc = new ec2.Vpc(this, "vpc", {
      ipAddresses: ec2.IpAddresses.awsIpamAllocation({
        ipv4IpamPoolId: props.poolId,
        ipv4NetmaskLength: props.netmaskLength,
      }),
     ...
    });

I would like the ability to do the same for ClientVpnEndpoint, instead of passing in a cidr(that my team has to lookup/calculate manually). So the proposed solution would almost be a duplicate of the VPC implementation where I give it a pool ID and a mask and say just give me a range that isn't allocated

    const vpnEndpoint = new ec2.ClientVpnEndpoint(this, "vpn-endpoint", {
      ipAddresses: ec2.IpAddresses.awsIpamAllocation({
        ipv4IpamPoolId: props.poolId,
        ipv4NetmaskLength: props.netmaskLength,
      }),
      ...
    });

Other Information

I have tried creating an IPAM allocation and setting the cidr on the ClientEndPoint with that object but it fails because the cidr is empty.

const allocation = new ec2.CfnIPAMAllocation(this, 'ipam-allocation', {
    ipamPoolId: props.poolId,
    description: 'Client VPN IPAM allocation',
    netmaskLength: props.netmaskLength,
});

const vpnEndpoint = new ec2.ClientVpnEndpoint(this, "vpn-endpoint", {
  cidr: allocation.cidr
  ...
});

Acknowledgements

CDK version used

2.48.0

Environment details (OS name and version, etc.)

macOS 12.5.1

peterwoodworth commented 1 year ago

I'm not sure how possible this is. The Cloudformation VPC resource has some properties that allow for IPAM configuration, however the ClientVpnEndpoint resource only has CIDR configuration with a specific CIDR block. We might need support from CloudFormation here

Regarding your Other Information section - the properties on the CloudFormation resource after creation will be 1:1 with the properties of the same name that you pass in. So, since you can pass in cidr, it will be undefined as there was no value passed in. You could potentially use an AwsCustomResource to make an API call to get the CIDR of the IPAM allocation instead?

sbstjn commented 1 week ago

From the CloudFormation docs about AWS::EC2::IPAMAllocation it reads:

When you pass the logical ID of this resource to the intrinsic Ref function, Ref returns the pool ID, allocation ID, and CIDR joined with "|" as a separator.

So, allocating IP addresses first and then getting the CIDR from the returned Ref should do the trick to create a AWS::EC2::ClientVpnEndpoint with IPAM connection.

const vpnAllocation = new aws_ec2.CfnIPAMAllocation(this, 'allocation', {
  description: 'VPN',
  ipamPoolId: 'Your-IPAM-PoolId',
  netmaskLength: 18,
})

this.vpn = new aws_ec2.ClientVpnEndpoint(this, 'vpn', {
  cidr: Fn.select(2, Fn.split('|', vpnAllocation.ref)),
  ...
})