@@ -293,3 +293,219 @@ Here’s a breakdown of the configuration options available:
2932934. externalSubnets: Specify external subnets if you need to define subnets manually (each with an id, availabilityZone, and routeTableId).
2942945. iamPolicyStatements: (Optional) Attach IAM policy statements to control access to the endpoint.
2952956. additionalTags: (Optional) Add custom tags to the VPC Endpoint for easier identification and tracking.
296+
297+ ## Dynamic Routing Strategy
298+
299+ The module automatically chooses the optimal routing strategy based on the number of NAT Gateways to prevent duplicate ` 0.0.0.0/0` route entries:
300+
301+ ### **Single NAT Gateway (≤1 NAT Gateway)**
302+ - **Strategy**: One route table per subnet group
303+ - **Benefits**:
304+ - **Cost Optimized**: Fewer route tables = lower costs
305+ - **Simpler Management**: One route table per subnet group
306+ - **No Duplicate Routes**: Single NAT Gateway means no duplicate ` 0.0.0.0/0` entries
307+ - **Suitable for**: Development, testing, small workloads
308+ - **Configuration**: All subnets in a group share the same route table with one NAT route
309+
310+ ### **Multiple NAT Gateways (>1 NAT Gateway)**
311+ - **Strategy**: One route table per subnet
312+ - **Benefits**:
313+ - **Prevents Duplicate Routes**: Each subnet gets its own route table, avoiding duplicate ` 0.0.0.0/0` entries
314+ - **AZ-Aware Routing**: Each subnet uses NAT Gateway in the same AZ when possible
315+ - **High Availability**: Better fault tolerance and load distribution
316+ - **Cross-AZ Cost Reduction**: Reduced data transfer costs
317+ - **Suitable for**: Production workloads, high availability requirements
318+ - **Configuration**: Each subnet gets its own route table with one NAT route
319+
320+ ### **Why This Strategy?**
321+
322+ AWS route tables don't support duplicate entries for the same destination CIDR (like ` 0.0.0.0/0` ). When you have multiple NAT Gateways:
323+
324+ - **❌ Wrong Approach**: Multiple NAT routes in same route table → ` AlreadyExists ` error
325+ - **✅ Correct Approach**: One route table per subnet → Each gets one NAT route
326+
327+ ### **Automatic Strategy Selection**
328+
329+ ` ` ` typescript
330+ // Single NAT Gateway - Cost Optimized
331+ new Network(this, ' NETWORK' , {
332+ vpc : {
333+ cidr : ' 10.10.0.0/16' ,
334+ subnetConfiguration : [],
335+ },
336+ subnets : [
337+ {
338+ subnetGroupName: ' NATGateway' ,
339+ subnetType: ec2 .SubnetType .PUBLIC ,
340+ cidrBlock: [' 10.10.0.0/28' ], // Only one subnet
341+ availabilityZones: [' ap-south-1a' ], // Only one AZ
342+ useSubnetForNAT: true ,
343+ },
344+ {
345+ subnetGroupName: ' Private' ,
346+ subnetType: ec2 .SubnetType .PRIVATE_WITH_NAT ,
347+ cidrBlock: [' 10.10.5.0/24' , ' 10.10.6.0/24' , ' 10.10.7.0/24' ],
348+ availabilityZones: [' ap-south-1a' , ' ap-south-1b' , ' ap-south-1c' ],
349+ },
350+ ],
351+ });
352+
353+ // Multiple NAT Gateways - Performance Optimized
354+ new Network(this , ' NETWORK' , {
355+ vpc : {
356+ cidr : ' 10.10.0.0/16' ,
357+ subnetConfiguration : [],
358+ },
359+ natEipAllocationIds : [
360+ ' eipalloc-1234567890abcdef' ,
361+ ' eipalloc-0987654321fedcba' ,
362+ ' eipalloc-abcdef1234567890' ,
363+ ],
364+ subnets : [
365+ {
366+ subnetGroupName : ' NATGateway' ,
367+ subnetType : ec2 .SubnetType .PUBLIC ,
368+ cidrBlock : [' 10.10.0.0/28' , ' 10.10.0.16/28' , ' 10.10.0.32/28' ],
369+ availabilityZones : [' ap-south-1a' , ' ap-south-1b' , ' ap-south-1c' ],
370+ useSubnetForNAT : true ,
371+ },
372+ {
373+ subnetGroupName : ' Private' ,
374+ subnetType : ec2 .SubnetType .PRIVATE_WITH_NAT ,
375+ cidrBlock : [' 10.10.5.0/24' , ' 10.10.6.0/24' , ' 10.10.7.0/24' ],
376+ availabilityZones : [' ap-south-1a' , ' ap-south-1b' , ' ap-south-1c' ],
377+ },
378+ ],
379+ });
380+ ` ` `
381+
382+ ### **CloudFormation Outputs**
383+
384+ The module provides outputs to show which strategy is being used:
385+
386+ - **RoutingStrategy**: Shows "Route Table per Subnet Group" or "Route Table per Subnet"
387+ - **NATGatewayCount**: Shows the number of NAT Gateways configured
388+
389+ ### **Route Table Distribution**
390+
391+ | Scenario | Route Tables | NAT Routes per Table | Strategy |
392+ |----------|-------------|---------------------|----------|
393+ | Single NAT | 1 per subnet group | 1 | Cost optimized |
394+ | Multiple NAT | 1 per subnet | 1 | Performance optimized |
395+
396+ ### **Migration Strategy**
397+
398+ You can easily migrate between strategies by changing your configuration:
399+
400+ 1. **Development → Production**: Add more NAT Gateway subnets
401+ 2. **Production → Development**: Reduce to single NAT Gateway subnet
402+ 3. **Cost Optimization**: Monitor usage and adjust NAT Gateway count
403+
404+ The module handles the migration automatically without manual route table changes.
405+
406+ ## NAT Gateway EIP Allocation
407+
408+ You can specify existing Elastic IP (EIP) allocation IDs to use with your NAT Gateways. This is useful when you want to:
409+
410+ - Use pre-existing EIPs
411+ - Maintain consistent IP addresses across deployments
412+ - Control EIP costs and management
413+
414+ ### **Using EIP Allocation IDs**
415+
416+ ` ` ` typescript
417+ new Network(this, ' NETWORK' , {
418+ vpc : {
419+ cidr : ' 10.10.0.0/16' ,
420+ subnetConfiguration : [],
421+ },
422+ // Specify existing EIP allocation IDs
423+ natEipAllocationIds : [
424+ ' eipalloc-1234567890abcdef' , // EIP for NAT Gateway 1
425+ ' eipalloc-0987654321fedcba' , // EIP for NAT Gateway 2
426+ ' eipalloc-abcdef1234567890' , // EIP for NAT Gateway 3
427+ ],
428+ subnets : [
429+ {
430+ subnetGroupName: ' NATGateway' ,
431+ subnetType: ec2 .SubnetType .PUBLIC ,
432+ cidrBlock: [' 10.10.0.0/28' , ' 10.10.0.16/28' , ' 10.10.0.32/28' ],
433+ availabilityZones: [' ap-south-1a' , ' ap-south-1b' , ' ap-south-1c' ],
434+ useSubnetForNAT: true ,
435+ },
436+ {
437+ subnetGroupName: ' Private' ,
438+ subnetType: ec2 .SubnetType .PRIVATE_WITH_NAT ,
439+ cidrBlock: [' 10.10.5.0/24' , ' 10.10.6.0/24' , ' 10.10.7.0/24' ],
440+ availabilityZones: [' ap-south-1a' , ' ap-south-1b' , ' ap-south-1c' ],
441+ },
442+ ],
443+ });
444+ ` ` `
445+
446+ ### **EIP Allocation ID Requirements**
447+
448+ - **Count**: Should match the number of NAT Gateway subnets (optional)
449+ - **Format**: Must be valid EIP allocation IDs (e.g., ` eipalloc-xxxxxxxxx ` )
450+ - **Region**: Must be in the same region as your VPC
451+ - **Account**: Must be owned by the same AWS account
452+
453+ ### **Benefits of Using EIP Allocation IDs**
454+
455+ 1. **Cost Control**: Reuse existing EIPs instead of creating new ones
456+ 2. **IP Consistency**: Maintain the same public IP addresses across deployments
457+ 3. **Compliance**: Meet requirements for static IP addresses
458+ 4. **DNS**: Use existing DNS records that point to specific EIPs
459+
460+ ### **CloudFormation Outputs**
461+
462+ When EIP allocation IDs are provided, the module outputs:
463+
464+ - **NATEipAllocationIds**: Comma-separated list of EIP allocation IDs used
465+ - **RoutingStrategy**: Shows the routing strategy being used
466+ - **NATGatewayCount**: Number of NAT Gateways configured
467+
468+ ### **Example Output**
469+
470+ ` ` ` json
471+ {
472+ " NATEipAllocationIds" : " eipalloc-1234567890abcdef,eipalloc-0987654321fedcba,eipalloc-abcdef1234567890" ,
473+ " RoutingStrategy" : " Route Table per Subnet" ,
474+ " NATGatewayCount" : " 3"
475+ }
476+ ` ` `
477+
478+ ### **Creating EIPs for NAT Gateways**
479+
480+ If you need to create EIPs first, you can do so using CDK:
481+
482+ ` ` ` typescript
483+ import * as ec2 from ' aws-cdk-lib/aws-ec2' ;
484+
485+ // Create EIPs
486+ const eip1 = new ec2 .CfnEIP (this , ' NATEip1' , {
487+ domain: ' vpc' ,
488+ });
489+
490+ const eip2 = new ec2 .CfnEIP (this , ' NATEip2' , {
491+ domain: ' vpc' ,
492+ });
493+
494+ const eip3 = new ec2 .CfnEIP (this , ' NATEip3' , {
495+ domain: ' vpc' ,
496+ });
497+
498+ // Use them in your Network construct
499+ new Network (this , ' NETWORK' , {
500+ vpc: {
501+ cidr: ' 10.10.0.0/16' ,
502+ subnetConfiguration: [],
503+ },
504+ natEipAllocationIds: [
505+ eip1 .attrAllocationId ,
506+ eip2 .attrAllocationId ,
507+ eip3 .attrAllocationId ,
508+ ],
509+ // ... rest of configuration
510+ });
511+ ` ` `
0 commit comments