Open
Description
Describe the feature
The L2 construct Subnet
currently does not support IPAM CIDR allocation, while the L1 construct CfnSubnet
already supports it. This feature request proposes to add IPAM support to the L2 construct to provide a more consistent and user-friendly experience.
Current Behavior
- L1 construct (
CfnSubnet
) supports IPAM CIDR allocation - L2 construct (
Subnet
) only supports direct CIDR specification - VPC level IPAM support exists but subnet level support is missing
Proposed Solution
The L2 Subnet
construct should be enhanced to support IPAM allocation through a new property in SubnetProps
:
new ec2.Subnet(stack, 'MySubnet', {
vpcId: vpc.vpcId,
availabilityZone: 'us-east-1a',
ipamAllocation: {
ipamPoolId: 'ipam-pool-123',
netmaskLength: 24
}
});
Implementation Details
- Add
ipamAllocation
property toSubnetProps
interface - Update
Subnet
construct to handle IPAM configuration - Add validation for IPAM and CIDR mutual exclusivity
- Add integration with VPC-level IPAM settings
- Add comprehensive test coverage
- Update documentation
Use Case
I'm always frustrated when trying to use IPAM for subnet CIDR allocation in a CDK application. While the VPC construct supports IPAM, individual subnets do not, forcing us to:
- Either use L1 constructs directly, losing the benefits of L2 abstractions
- Or manually manage CIDR blocks, defeating the purpose of using IPAM
This feature would allow us to:
- Maintain consistent IP address management across our infrastructure
- Leverage IPAM's centralized control at both VPC and subnet levels
- Keep using the convenient L2 constructs while benefiting from IPAM features
Proposed Solution
Proposed Solution
The implementation will involve the following changes:
- Update
SubnetProps
interface inpackages/aws-cdk-lib/aws-ec2/lib/subnet.ts
:
export interface SubnetProps {
// ... existing properties ...
/**
* IPAM allocation configuration
* If specified, cidrBlock must not be set
* @default - no IPAM allocation
*/
readonly ipamAllocation?: {
/**
* The ID of the IPAM pool to allocate the CIDR from
*/
readonly ipamPoolId: string;
/**
* The netmask length for the CIDR
* Must be a value between 16 and 28
*/
readonly netmaskLength: number;
};
}
- Update
Subnet
class implementation:
export class Subnet extends Resource implements ISubnet {
constructor(scope: Construct, id: string, props: SubnetProps) {
super(scope, id);
if (props.ipamAllocation && props.cidrBlock) {
throw new Error('Cannot specify both ipamAllocation and cidrBlock');
}
const subnet = new CfnSubnet(this, 'Resource', {
vpcId: props.vpcId,
availabilityZone: props.availabilityZone,
// ... other properties ...
// Add IPAM properties when specified
...(props.ipamAllocation && {
ipv4IpamPoolId: props.ipamAllocation.ipamPoolId,
ipv4NetmaskLength: props.ipamAllocation.netmaskLength
})
});
// ... rest of the implementation ...
}
}
- Add test cases in
packages/aws-cdk-lib/aws-ec2/test/subnet.test.ts
:
test('subnet with ipam allocation', () => {
const stack = new Stack();
new Subnet(stack, 'Subnet', {
vpcId: 'vpc-123',
availabilityZone: 'us-east-1a',
ipamAllocation: {
ipamPoolId: 'ipam-pool-123',
netmaskLength: 24
}
});
Template.fromStack(stack).hasResourceProperties('AWS::EC2::Subnet', {
VpcId: 'vpc-123',
AvailabilityZone: 'us-east-1a',
Ipv4IpamPoolId: 'ipam-pool-123',
Ipv4NetmaskLength: 24
});
});
test('cannot specify both cidrBlock and ipamAllocation', () => {
const stack = new Stack();
expect(() => {
new Subnet(stack, 'Subnet', {
vpcId: 'vpc-123',
availabilityZone: 'us-east-1a',
cidrBlock: '10.0.0.0/24',
ipamAllocation: {
ipamPoolId: 'ipam-pool-123',
netmaskLength: 24
}
});
}).toThrow(/Cannot specify both ipamAllocation and cidrBlock/);
});
- Update VPC integration:
export class Vpc extends Resource implements IVpc {
private allocateSubnet(props: AllocateSubnetProps): Subnet {
// ... existing allocation logic ...
// If VPC uses IPAM, prefer VPC's IPAM settings unless subnet explicitly specifies its own
const ipamAllocation = props.ipamAllocation ?? (this.ipamPool && {
ipamPoolId: this.ipamPool.poolId,
netmaskLength: this.defaultSubnetMask
});
return new Subnet(this, subnetId, {
// ... other properties ...
ipamAllocation,
});
}
}
- Documentation Updates:
- Add new section in
packages/aws-cdk-lib/aws-ec2/README.md
about IPAM support - Update API reference documentation
- Add examples showing IPAM usage with subnets
Backward Compatibility
This change is fully backward compatible:
- Existing code using
cidrBlock
continues to work as before - New
ipamAllocation
property is optional - VPC-level IPAM configuration remains unchanged
Integration Testing
Will add integration tests to verify:
- IPAM allocation works correctly at subnet creation
- VPC and subnet level IPAM configurations work together
- Error cases are handled appropriately
Other Information
No response
Acknowledgements
- I may be able to implement this feature request
- This feature might incur a breaking change
CDK version used
v2.192.0
Environment details (OS name and version, etc.)
macOS 15.4.1