(aws-ec2): Support IPAM CIDR allocation in L2 Subnet construct
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
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`:
```typescript
new ec2.Subnet(stack, 'MySubnet', {
vpcId: vpc.vpcId,
availabilityZone: 'us-east-1a',
ipamAllocation: {
ipamPoolId: 'ipam-pool-123',
netmaskLength: 24
}
});
```
### Implementation Details
- Add `ipamAllocation` property to `SubnetProps` 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:
1. Either use L1 constructs directly, losing the benefits of L2 abstractions
2. 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:
1. Update `SubnetProps` interface in `packages/aws-cdk-lib/aws-ec2/lib/subnet.ts`:
```typescript
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;
};
}
```
2. Update `Subnet` class implementation:
```typescript
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 ...
}
}
```
3. Add test cases in `packages/aws-cdk-lib/aws-ec2/test/subnet.test.ts`:
```typescript
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/);
});
```
4. Update VPC integration:
```typescript
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,
});
}
}
```
5. 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
- [x] 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
Contributor guide
Research direction
Start in packages/aws-cdk-lib/aws-ec2/lib/subnet.ts and review the SubnetProps and Subnet implementation alongside the existing CfnSubnet IPAM properties. Run the subnet tests in packages/aws-cdk-lib/aws-ec2/test/subnet.test.ts, then add coverage for IPAM allocation and cidrBlock mutual exclusivity. Done includes VPC integration, documentation in packages/aws-cdk-lib/aws-ec2/README.md, and the described integration coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure, networking
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100