From 9e08b9b18611a2c21e63d8636cd0326936998407 Mon Sep 17 00:00:00 2001 From: James Fleming Date: Tue, 7 Jan 2020 17:26:48 +0000 Subject: [PATCH 1/5] Add support for isolated subnets without specifying subnet type --- .../lib/shared/base-load-balancer.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index d05a44bfb7f94..d8891ca62eed4 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -127,8 +127,29 @@ export abstract class BaseLoadBalancer extends Resource { const internetFacing = ifUndefined(baseProps.internetFacing, false); + const hasPrivateSubnets = baseProps.vpc.privateSubnets !== undefined && baseProps.vpc.privateSubnets.length > 0; + const hasPublicSubnets = baseProps.vpc.publicSubnets !== undefined && baseProps.vpc.publicSubnets.length > 0; + const hasIsolatedSubnets = baseProps.vpc.isolatedSubnets !== undefined && baseProps.vpc.isolatedSubnets.length > 0; + + let vpcSubnetType; + if (internetFacing) { + if (!hasPublicSubnets) { + throw new Error("Internet-facing load balancer requires 'Public' subnets, but none were found."); + } else { + vpcSubnetType = ec2.SubnetType.PUBLIC; + } + } else { + if (hasPrivateSubnets) { + vpcSubnetType = ec2.SubnetType.PRIVATE; + } else if (hasIsolatedSubnets) { + vpcSubnetType = ec2.SubnetType.ISOLATED; + } else { + throw new Error("Internal load balancer requires 'Private' or 'Isolated' subnets, but none were found."); + } + } + const vpcSubnets = ifUndefined(baseProps.vpcSubnets, - { subnetType: internetFacing ? ec2.SubnetType.PUBLIC : ec2.SubnetType.PRIVATE }); + { subnetType: vpcSubnetType }); const { subnetIds, internetConnectivityEstablished } = baseProps.vpc.selectSubnets(vpcSubnets); From de34e1fcb42539ce32cab19613e320454290ab15 Mon Sep 17 00:00:00 2001 From: James Fleming Date: Tue, 7 Jan 2020 19:00:49 +0000 Subject: [PATCH 2/5] Update tests and readme --- .../lib/shared/base-load-balancer.ts | 4 ++- .../test/nlb/test.load-balancer.ts | 30 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index d8891ca62eed4..628001b85903e 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -29,7 +29,9 @@ export interface BaseLoadBalancerProps { /** * Where in the VPC to place the load balancer * - * @default - Public subnets if internetFacing, otherwise private subnets. + * @default - Public subnets if internetFacing, Private subnets if internal and + * there are Private subnets, Isolated subnets if internal and there are no + * Private subnets. */ readonly vpcSubnets?: ec2.SubnetSelection; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts index 1977dd8425ce5..f9628c0004f03 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts @@ -90,6 +90,34 @@ export = { Name: 'myLoadBalancer' })); test.done(); - } + }, + 'Trivial construction: internal with Isolated subnets only'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC', { + subnetConfiguration: [{ + cidrMask: 20, + name: 'Isolated', + subnetType: ec2.SubnetType.ISOLATED, + }] + }); + + // WHEN + new elbv2.NetworkLoadBalancer(stack, 'LB', { + vpc, + internetFacing: false, + }); + // THEN + expect(stack).to(haveResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + Scheme: "internal", + Subnets: [ + { Ref: "VPCIsolatedSubnet1SubnetEBD00FC6" }, + { Ref: "VPCIsolatedSubnet2Subnet4B1C8CAA" }, + ], + Type: "network" + })); + + test.done(); + } }; From d19d97a4f462f33283cc7f58ed6f28de2bb0cf6d Mon Sep 17 00:00:00 2001 From: James Fleming Date: Tue, 7 Jan 2020 21:06:13 +0000 Subject: [PATCH 3/5] Expanded tests --- .../test/nlb/test.load-balancer.ts | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts index f9628c0004f03..d797bb7bc04f0 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts @@ -118,6 +118,82 @@ export = { Type: "network" })); + test.done(); + }, + 'Internal with Public, Private, and Isolated subnets'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC', { + subnetConfiguration: [{ + cidrMask: 24, + name: 'Public', + subnetType: ec2.SubnetType.PUBLIC, + }, { + cidrMask: 24, + name: 'Private', + subnetType: ec2.SubnetType.PRIVATE, + }, { + cidrMask: 28, + name: 'Isolated', + subnetType: ec2.SubnetType.ISOLATED, + } + ] + }); + + // WHEN + new elbv2.NetworkLoadBalancer(stack, 'LB', { + vpc, + internetFacing: false, + }); + + // THEN + expect(stack).to(haveResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + Scheme: "internal", + Subnets: [ + { Ref: "VPCPrivateSubnet1Subnet8BCA10E0" }, + { Ref: "VPCPrivateSubnet2SubnetCFCDAA7A" }, + ], + Type: "network" + })); + + test.done(); + }, + 'Internet-facing with Public, Private, and Isolated subnets'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC', { + subnetConfiguration: [{ + cidrMask: 24, + name: 'Public', + subnetType: ec2.SubnetType.PUBLIC, + }, { + cidrMask: 24, + name: 'Private', + subnetType: ec2.SubnetType.PRIVATE, + }, { + cidrMask: 28, + name: 'Isolated', + subnetType: ec2.SubnetType.ISOLATED, + } + ] + }); + + // WHEN + new elbv2.NetworkLoadBalancer(stack, 'LB', { + vpc, + internetFacing: true, + }); + + // THEN + expect(stack).to(haveResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + Scheme: "internet-facing", + Subnets: [ + { Ref: "VPCPublicSubnet1SubnetB4246D30" }, + { Ref: "VPCPublicSubnet2Subnet74179F39" }, + ], + Type: "network" + })); + test.done(); } }; From 17e40f873922b83280f60070917b8d57f47ba9d1 Mon Sep 17 00:00:00 2001 From: James Fleming Date: Fri, 10 Jan 2020 18:49:34 +0000 Subject: [PATCH 4/5] Review feedback --- .../lib/shared/base-load-balancer.ts | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index 628001b85903e..b105f1dfcde41 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -129,30 +129,7 @@ export abstract class BaseLoadBalancer extends Resource { const internetFacing = ifUndefined(baseProps.internetFacing, false); - const hasPrivateSubnets = baseProps.vpc.privateSubnets !== undefined && baseProps.vpc.privateSubnets.length > 0; - const hasPublicSubnets = baseProps.vpc.publicSubnets !== undefined && baseProps.vpc.publicSubnets.length > 0; - const hasIsolatedSubnets = baseProps.vpc.isolatedSubnets !== undefined && baseProps.vpc.isolatedSubnets.length > 0; - - let vpcSubnetType; - if (internetFacing) { - if (!hasPublicSubnets) { - throw new Error("Internet-facing load balancer requires 'Public' subnets, but none were found."); - } else { - vpcSubnetType = ec2.SubnetType.PUBLIC; - } - } else { - if (hasPrivateSubnets) { - vpcSubnetType = ec2.SubnetType.PRIVATE; - } else if (hasIsolatedSubnets) { - vpcSubnetType = ec2.SubnetType.ISOLATED; - } else { - throw new Error("Internal load balancer requires 'Private' or 'Isolated' subnets, but none were found."); - } - } - - const vpcSubnets = ifUndefined(baseProps.vpcSubnets, - { subnetType: vpcSubnetType }); - + const vpcSubnets = (internetFacing ? { subnetType: ec2.SubnetType.PUBLIC } : {}); const { subnetIds, internetConnectivityEstablished } = baseProps.vpc.selectSubnets(vpcSubnets); this.vpc = baseProps.vpc; From a680529e5924a1fb832425b47348ddfa6b936b64 Mon Sep 17 00:00:00 2001 From: James Fleming Date: Mon, 13 Jan 2020 16:47:28 +0000 Subject: [PATCH 5/5] Add tests for provided subnet configuration, and fixed using provided VPC subnets --- .../lib/shared/base-load-balancer.ts | 3 +- .../test/nlb/test.load-balancer.ts | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index b105f1dfcde41..0a4cb0ac3eaeb 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -129,7 +129,8 @@ export abstract class BaseLoadBalancer extends Resource { const internetFacing = ifUndefined(baseProps.internetFacing, false); - const vpcSubnets = (internetFacing ? { subnetType: ec2.SubnetType.PUBLIC } : {}); + const vpcSubnets = ifUndefined(baseProps.vpcSubnets, + (internetFacing ? {subnetType: ec2.SubnetType.PUBLIC} : {}) ); const { subnetIds, internetConnectivityEstablished } = baseProps.vpc.selectSubnets(vpcSubnets); this.vpc = baseProps.vpc; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts index d797bb7bc04f0..5c0046e186013 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts @@ -91,6 +91,7 @@ export = { })); test.done(); }, + 'Trivial construction: internal with Isolated subnets only'(test: Test) { // GIVEN const stack = new cdk.Stack(); @@ -194,6 +195,69 @@ export = { Type: "network" })); + test.done(); + }, + 'Internal load balancer supplying public subnets'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + + // WHEN + new elbv2.NetworkLoadBalancer(stack, 'LB', { + vpc, + internetFacing: false, + vpcSubnets: {subnetType: ec2.SubnetType.PUBLIC} + }); + + // THEN + expect(stack).to(haveResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + Scheme: "internal", + Subnets: [ + { Ref: "VPCPublicSubnet1SubnetB4246D30" }, + { Ref: "VPCPublicSubnet2Subnet74179F39" }, + ], + Type: "network" + })); + + test.done(); + }, + 'Internal load balancer supplying isolated subnets'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC', { + subnetConfiguration: [{ + cidrMask: 24, + name: 'Public', + subnetType: ec2.SubnetType.PUBLIC, + }, { + cidrMask: 24, + name: 'Private', + subnetType: ec2.SubnetType.PRIVATE, + }, { + cidrMask: 28, + name: 'Isolated', + subnetType: ec2.SubnetType.ISOLATED, + } + ] + }); + + // WHEN + new elbv2.NetworkLoadBalancer(stack, 'LB', { + vpc, + internetFacing: false, + vpcSubnets: {subnetType: ec2.SubnetType.ISOLATED} + }); + + // THEN + expect(stack).to(haveResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + Scheme: "internal", + Subnets: [ + { Ref: "VPCIsolatedSubnet1SubnetEBD00FC6" }, + { Ref: "VPCIsolatedSubnet2Subnet4B1C8CAA" }, + ], + Type: "network" + })); + test.done(); } };