Skip to content

Commit 14e4bc9

Browse files
ScOut3Rmergify[bot]
authored andcommitted
feat(elasticloadbalancing): add subnet selection (#2833) (#3415)
* feat(elasticloadbalancing): add subnet selection (#2833) Add the ability to specify the subnets the classic load balancer is deployed to. closes (#2833) * feat(elasticloadbalancing): add subnet selection (#2833) Update subnetSelection property to follow API standards closes(#2833)
1 parent fa48e89 commit 14e4bc9

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Connections, IConnectable, ISecurityGroup, ISubnet, IVpc, Peer, Port, SecurityGroup } from '@aws-cdk/aws-ec2';
1+
import { Connections, IConnectable, ISecurityGroup, IVpc, Peer, Port,
2+
SecurityGroup, SelectedSubnets, SubnetSelection, SubnetType } from '@aws-cdk/aws-ec2';
23
import { Construct, Duration, Lazy, Resource } from '@aws-cdk/core';
34
import { CfnLoadBalancer } from './elasticloadbalancing.generated';
45

@@ -57,6 +58,16 @@ export interface LoadBalancerProps {
5758
* @default true
5859
*/
5960
readonly crossZone?: boolean;
61+
62+
/**
63+
* Which subnets to deploy the load balancer
64+
*
65+
* Can be used to define a specific set of subnets to deploy the load balancer to.
66+
* Useful multiple public or private subnets are covering the same availability zone.
67+
*
68+
* @default - Public subnets if internetFacing, Private subnets otherwise
69+
*/
70+
readonly subnetSelection?: SubnetSelection;
6071
}
6172

6273
/**
@@ -226,18 +237,18 @@ export class LoadBalancer extends Resource implements IConnectable {
226237
this.connections = new Connections({ securityGroups: [this.securityGroup] });
227238

228239
// Depending on whether the ELB has public or internal IPs, pick the right backend subnets
229-
const subnets: ISubnet[] = props.internetFacing ? props.vpc.publicSubnets : props.vpc.privateSubnets;
240+
const selectedSubnets: SelectedSubnets = loadBalancerSubnets(props);
230241

231242
this.elb = new CfnLoadBalancer(this, 'Resource', {
232243
securityGroups: [ this.securityGroup.securityGroupId ],
233-
subnets: subnets.map(s => s.subnetId),
244+
subnets: selectedSubnets.subnetIds,
234245
listeners: Lazy.anyValue({ produce: () => this.listeners }),
235246
scheme: props.internetFacing ? 'internet-facing' : 'internal',
236247
healthCheck: props.healthCheck && healthCheckToJSON(props.healthCheck),
237248
crossZone: (props.crossZone === undefined || props.crossZone) ? true : false
238249
});
239250
if (props.internetFacing) {
240-
this.elb.node.addDependency(...subnets.map(s => s.internetConnectivityEstablished));
251+
this.elb.node.addDependency(selectedSubnets.internetConnectivityEstablished);
241252
}
242253

243254
ifUndefined(props.listeners, []).forEach(b => this.addListener(b));
@@ -426,3 +437,17 @@ function healthCheckToJSON(healthCheck: HealthCheck): CfnLoadBalancer.HealthChec
426437
unhealthyThreshold: ifUndefined(healthCheck.unhealthyThreshold, 5).toString(),
427438
};
428439
}
440+
441+
function loadBalancerSubnets(props: LoadBalancerProps): SelectedSubnets {
442+
if (props.subnetSelection !== undefined) {
443+
return props.vpc.selectSubnets(props.subnetSelection);
444+
} else if (props.internetFacing) {
445+
return props.vpc.selectSubnets({
446+
subnetType: SubnetType.PUBLIC
447+
});
448+
} else {
449+
return props.vpc.selectSubnets({
450+
subnetType: SubnetType.PRIVATE
451+
});
452+
}
453+
}

packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, haveResource } from '@aws-cdk/assert';
2-
import { Connections, Peer, Vpc } from '@aws-cdk/aws-ec2';
2+
import { Connections, Peer, SubnetType, Vpc } from '@aws-cdk/aws-ec2';
33
import { Duration, Stack } from '@aws-cdk/core';
44
import { Test } from 'nodeunit';
55
import { ILoadBalancerTarget, LoadBalancer, LoadBalancingProtocol } from '../lib';
@@ -151,6 +151,47 @@ export = {
151151
test.done();
152152
},
153153

154+
'use specified subnet'(test: Test) {
155+
// GIVEN
156+
const stack = new Stack();
157+
const vpc = new Vpc(stack, 'VCP', {
158+
subnetConfiguration: [
159+
{
160+
name: 'public',
161+
subnetType: SubnetType.PUBLIC,
162+
cidrMask: 21
163+
},
164+
{
165+
name: 'private1',
166+
subnetType: SubnetType.PRIVATE,
167+
cidrMask: 21
168+
},
169+
{
170+
name: 'private2',
171+
subnetType: SubnetType.PRIVATE,
172+
cidrMask: 21
173+
}
174+
],
175+
});
176+
177+
// WHEN
178+
new LoadBalancer(stack, 'LB', {
179+
vpc,
180+
subnetSelection: {
181+
subnetName: 'private1'
182+
},
183+
});
184+
185+
// THEN
186+
expect(stack).to(haveResource('AWS::ElasticLoadBalancing::LoadBalancer', {
187+
Subnets: vpc.selectSubnets({
188+
subnetName: 'private1'
189+
}).subnetIds.map((subnetId: string) => stack.resolve(subnetId))
190+
}));
191+
192+
test.done();
193+
}
194+
154195
};
155196

156197
class FakeTarget implements ILoadBalancerTarget {

0 commit comments

Comments
 (0)