diff --git a/API.md b/API.md
index 0b7dadf..070ff12 100644
--- a/API.md
+++ b/API.md
@@ -58,7 +58,7 @@ Returns a string representation of this construct.
##### `createSubnet`
```typescript
-public createSubnet(option: ISubnetsProps, vpc: Vpc, peeringConnectionId?: PeeringConnectionInternalType): Subnet[]
+public createSubnet(option: ISubnetsProps, vpc: Vpc): Subnet[]
```
###### `option`Required
@@ -73,12 +73,6 @@ public createSubnet(option: ISubnetsProps, vpc: Vpc, peeringConnectionId?: Peeri
---
-###### `peeringConnectionId`Optional
-
-- *Type:* PeeringConnectionInternalType
-
----
-
#### Static Functions
| **Name** | **Description** |
@@ -111,7 +105,6 @@ Any object.
| --- | --- | --- |
| node | constructs.Node | The tree node. |
| endpointOutputs | {[ key: string ]: aws-cdk-lib.aws_ec2.InterfaceVpcEndpoint \| aws-cdk-lib.aws_ec2.GatewayVpcEndpoint} | *No description.* |
-| natProvider | aws-cdk-lib.aws_ec2.NatProvider | *No description.* |
| securityGroupOutputs | {[ key: string ]: aws-cdk-lib.aws_ec2.SecurityGroup} | *No description.* |
| vpc | aws-cdk-lib.aws_ec2.Vpc | *No description.* |
| natSubnets | aws-cdk-lib.aws_ec2.PublicSubnet[] | *No description.* |
@@ -143,16 +136,6 @@ public readonly endpointOutputs: {[ key: string ]: InterfaceVpcEndpoint | Gatewa
---
-##### `natProvider`Required
-
-```typescript
-public readonly natProvider: NatProvider;
-```
-
-- *Type:* aws-cdk-lib.aws_ec2.NatProvider
-
----
-
##### `securityGroupOutputs`Required
```typescript
diff --git a/src/constructs/network.ts b/src/constructs/network.ts
index 5d69ea3..ca13b1a 100644
--- a/src/constructs/network.ts
+++ b/src/constructs/network.ts
@@ -154,10 +154,10 @@ export class Network extends Construct {
public readonly securityGroupOutputs: { [key: string]: ec2.SecurityGroup } = {}; // Store Security Group outputs
public readonly endpointOutputs: { [key: string]: ec2.InterfaceVpcEndpoint | ec2.GatewayVpcEndpoint } = {}; // Store Endpoint outputs
private peeringConnectionIds: PeeringConnectionInternalType = {};
- public readonly natProvider!: ec2.NatProvider;
constructor(scope: Construct, id: string, props: VPCProps) {
super(scope, id);
this.vpc = new ec2.Vpc(this, 'VPC', props.vpc);
+
if (props.peeringConfigs) {
const convertPeeringConfig: Map = ObjToStrMap(props.peeringConfigs);
convertPeeringConfig.forEach((createVpcPeering, key) => {
@@ -175,8 +175,27 @@ export class Network extends Construct {
this.peeringConnectionIds[key] = peeringConnectionIdByKey;
});
}
+
+ const internetGateway = new ec2.CfnInternetGateway(
+ this,
+ 'InternetGateway',
+ {},
+ );
+ new ec2.CfnVPCGatewayAttachment(this, 'VPCGatewayAttachement', {
+ internetGatewayId: internetGateway.ref,
+ vpcId: this.vpc.vpcId,
+ });
+
+ // Initialize NAT provider after collecting all subnets
+ const natProvider = props.natEipAllocationIds?.length === this.natSubnets?.length && props.natEipAllocationIds?.length > 0
+ ? ec2.NatProvider.gateway({
+ eipAllocationIds: props.natEipAllocationIds,
+ }) : ec2.NatProvider.gateway();
+
+
+ // First pass: collect all subnets
props.subnets.forEach((subnetProps) => {
- let subnet = this.createSubnet(subnetProps, this.vpc, this.peeringConnectionIds);
+ let subnet = this.createSubnet(subnetProps, this.vpc);
this.subnets[subnetProps.subnetGroupName] = subnet;
subnet.forEach((sb) => {
if (sb instanceof ec2.PublicSubnet) {
@@ -197,40 +216,36 @@ export class Network extends Construct {
}
});
});
- const internetGateway = new ec2.CfnInternetGateway(
- this,
- 'InternetGateway',
- {},
- );
- const att = new ec2.CfnVPCGatewayAttachment(this, 'VPCGatewayAttachement', {
- internetGatewayId: internetGateway.ref,
- vpcId: this.vpc.vpcId,
- });
- this.pbSubnets.forEach((pb) => {
- pb.addDefaultInternetRoute(internetGateway.ref, att);
- });
- if (this.natSubnets.length > 0) {
- if (props.natEipAllocationIds && this.natSubnets.length != props.natEipAllocationIds?.length) {
- // eslint-disable-next-line max-len
- throw new Error(
- 'natEipAllocationIds and natSubnets length should be equal',
- );
- }
-
- if (props.natEipAllocationIds?.length == this.natSubnets?.length) {
- this.natProvider = ec2.NatProvider.gateway({
- eipAllocationIds: props.natEipAllocationIds,
- });
- } else {
- this.natProvider = ec2.NatProvider.gateway();
- }
- this.natProvider.configureNat({
+ // Configure NAT after collecting all subnets
+ if (this.natSubnets.length > 0) {
+ natProvider.configureNat({
vpc: this.vpc,
natSubnets: this.natSubnets,
privateSubnets: this.pvSubnets,
});
}
+
+ // Second pass: configure routes after NAT is configured
+ props.subnets.forEach((subnetProps) => {
+ const routeTableManager = new RouteTableManager(this, `${subnetProps.subnetGroupName}RouteTableManager`, {
+ vpc: this.vpc,
+ subnetGroupName: subnetProps.subnetGroupName,
+ routes: subnetProps.routes,
+ peeringConnectionId: this.peeringConnectionIds,
+ subnetType: subnetProps.subnetType,
+ natProvider: natProvider,
+ internetGateway: internetGateway,
+ });
+ this.subnets[subnetProps.subnetGroupName].forEach((subnet, index) => {
+ routeTableManager.associateSubnet(subnet, index);
+ });
+ });
+
+ // this.pbSubnets.forEach((pb) => {
+ // pb.addDefaultInternetRoute(internetGateway.ref, att);
+ // });
+
new CfnOutput(this, 'VpcId', { value: this.vpc.vpcId });
// Add VPC endpoints if specified in the props
if (props?.vpcEndpoints) {
@@ -245,7 +260,7 @@ export class Network extends Construct {
}
}
- createSubnet(option: ISubnetsProps, vpc: ec2.Vpc, peeringConnectionId?: PeeringConnectionInternalType) {
+ createSubnet(option: ISubnetsProps, vpc: ec2.Vpc) {
const subnets: ec2.Subnet[] = [];
const SUBNETTYPE_TAG = 'aws-cdk:subnet-type';
const SUBNETNAME_TAG = 'aws-cdk:subnet-name';
@@ -257,14 +272,6 @@ export class Network extends Construct {
);
}
- // Create a single RouteTableManager for the entire subnet group if migration is enabled
- const routeTableManager = new RouteTableManager(this, `${option.subnetGroupName}RouteTableManager`, {
- vpc,
- subnetGroupName: option.subnetGroupName,
- routes: option.routes,
- peeringConnectionId,
- });
-
option.availabilityZones.forEach((az, index) => {
let subnet: ec2.PrivateSubnet | ec2.PublicSubnet =
option.subnetType === ec2.SubnetType.PUBLIC
@@ -288,7 +295,6 @@ export class Network extends Construct {
mapPublicIpOnLaunch: false,
},
);
- routeTableManager.associateSubnet(subnet, index);
Tags.of(subnet).add(SUBNETNAME_TAG, option.subnetGroupName);
Tags.of(subnet).add(SUBNETTYPE_TAG, option.subnetType);
if (option.tags != undefined) {
@@ -299,6 +305,7 @@ export class Network extends Construct {
}
subnets.push(subnet);
});
+
const nacl = new ec2.NetworkAcl(this, `${option.subnetGroupName}NACL`, {
vpc: vpc,
subnetSelection: {
diff --git a/src/constructs/routeTableManager.ts b/src/constructs/routeTableManager.ts
index e7055ff..ee1b1f6 100644
--- a/src/constructs/routeTableManager.ts
+++ b/src/constructs/routeTableManager.ts
@@ -8,6 +8,9 @@ export interface RouteTableManagerProps {
readonly subnetGroupName: string;
readonly routes?: AddRouteOptions[];
readonly peeringConnectionId?: { [key: string]: ec2.CfnVPCPeeringConnection };
+ readonly subnetType: ec2.SubnetType;
+ readonly natProvider: ec2.NatProvider;
+ readonly internetGateway: ec2.CfnInternetGateway;
}
export class RouteTableManager extends Construct {
@@ -56,6 +59,27 @@ export class RouteTableManager extends Construct {
});
}
});
+
+ // Add default routes based on subnet type
+ if (props.subnetType === ec2.SubnetType.PUBLIC) {
+ // Add internet route for public subnets
+ new ec2.CfnRoute(this.nestedStack, `${props.subnetGroupName}-InternetRoute`, {
+ routeTableId: this.routeTable.ref,
+ destinationCidrBlock: '0.0.0.0/0',
+ gatewayId: props.internetGateway.ref,
+ });
+ } else if (props.subnetType === ec2.SubnetType.PRIVATE_WITH_EGRESS) {
+ // Add NAT route for private subnets
+ const natGateway = props.natProvider.configuredGateways[0];
+ console.log('natGateway', natGateway);
+ if (natGateway) {
+ new ec2.CfnRoute(this.nestedStack, `${props.subnetGroupName}-NatRoute`, {
+ routeTableId: this.routeTable.ref,
+ destinationCidrBlock: '0.0.0.0/0',
+ natGatewayId: natGateway.gatewayId,
+ });
+ }
+ }
}
public associateSubnet(subnet: ec2.ISubnet, index: number): void {