aws / aws/aws-cdk

(aws-ec2): Support IPAM CIDR allocation in L2 Subnet construct

Open
#34,296 3 comments 2 reactions 0 assignees View on GitHub
@aws-cdk/aws-ec2 effort/medium feature-request p2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.