Skip to content

Commit 1ebf362

Browse files
authored
feat(elasticloadbalancingv2): multiple security groups for ALBs (#10244)
Provide an `addSecurityGroup` method for ALBs for use cases where multiple security groups are needed. I opted for this approach over adding a new (and redundant) `securityGroups` prop to `ApplicationLoadBalancerProps` to keep the props targeted at the most common use case of a single (or default) group. fixes #5138 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent a00a4ee commit 1ebf362

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

packages/@aws-cdk/aws-elasticloadbalancingv2/README.md

+17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
## Amazon Elastic Load Balancing V2 Construct Library
2+
23
<!--BEGIN STABILITY BANNER-->
34
---
45

@@ -61,6 +62,21 @@ listener.addTargets('ApplicationFleet', {
6162
The security groups of the load balancer and the target are automatically
6263
updated to allow the network traffic.
6364

65+
One (or more) security groups can be associated with the load balancer;
66+
if a security group isn't provided, one will be automatically created.
67+
68+
```ts
69+
const securityGroup1 = new ec2.SecurityGroup(stack, 'SecurityGroup1', { vpc });
70+
const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
71+
vpc,
72+
internetFacing: true,
73+
securityGroup: securityGroup1, // Optional - will be automatically created otherwise
74+
});
75+
76+
const securityGroup2 = new ec2.SecurityGroup(stack, 'SecurityGroup2', { vpc });
77+
lb.addSecurityGroup(securityGroup2);
78+
```
79+
6480
#### Conditions
6581

6682
It's possible to route traffic to targets based on conditions in the incoming
@@ -320,6 +336,7 @@ public attachToApplicationTargetGroup(targetGroup: ApplicationTargetGroup): Load
320336
};
321337
}
322338
```
339+
323340
`targetType` should be one of `Instance` or `Ip`. If the target can be
324341
directly added to the target group, `targetJson` should contain the `id` of
325342
the target (either instance ID or IP address depending on the type) and

packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,21 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic
5858

5959
public readonly connections: ec2.Connections;
6060
public readonly ipAddressType?: IpAddressType;
61-
private readonly securityGroup: ec2.ISecurityGroup;
6261

6362
constructor(scope: Construct, id: string, props: ApplicationLoadBalancerProps) {
6463
super(scope, id, props, {
6564
type: 'application',
66-
securityGroups: Lazy.listValue({ produce: () => [this.securityGroup.securityGroupId] }),
65+
securityGroups: Lazy.listValue({ produce: () => this.connections.securityGroups.map(sg => sg.securityGroupId) }),
6766
ipAddressType: props.ipAddressType,
6867
});
6968

7069
this.ipAddressType = props.ipAddressType ?? IpAddressType.IPV4;
71-
this.securityGroup = props.securityGroup || new ec2.SecurityGroup(this, 'SecurityGroup', {
70+
const securityGroups = [props.securityGroup || new ec2.SecurityGroup(this, 'SecurityGroup', {
7271
vpc: props.vpc,
7372
description: `Automatically created Security Group for ELB ${this.node.uniqueId}`,
7473
allowAllOutbound: false,
75-
});
76-
this.connections = new ec2.Connections({ securityGroups: [this.securityGroup] });
74+
})];
75+
this.connections = new ec2.Connections({ securityGroups });
7776

7877
if (props.http2Enabled === false) { this.setAttribute('routing.http2.enabled', 'false'); }
7978
if (props.idleTimeout !== undefined) { this.setAttribute('idle_timeout.timeout_seconds', props.idleTimeout.toSeconds().toString()); }
@@ -107,6 +106,13 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic
107106
});
108107
}
109108

109+
/**
110+
* Add a security group to this load balancer
111+
*/
112+
public addSecurityGroup(securityGroup: ec2.ISecurityGroup) {
113+
this.connections.addSecurityGroup(securityGroup);
114+
}
115+
110116
/**
111117
* Return the given named metric for this Application Load Balancer
112118
*

packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/load-balancer.test.ts

+20
Original file line numberDiff line numberDiff line change
@@ -314,4 +314,24 @@ describe('tests', () => {
314314
const listener = alb.addListener('Listener', { port: 80 });
315315
expect(() => listener.addTargets('Targets', { port: 8080 })).not.toThrow();
316316
});
317+
318+
test.only('can add secondary security groups', () => {
319+
const stack = new cdk.Stack();
320+
const vpc = new ec2.Vpc(stack, 'Stack');
321+
322+
const alb = new elbv2.ApplicationLoadBalancer(stack, 'LB', {
323+
vpc,
324+
securityGroup: new ec2.SecurityGroup(stack, 'SecurityGroup1', { vpc }),
325+
});
326+
alb.addSecurityGroup(new ec2.SecurityGroup(stack, 'SecurityGroup2', { vpc }));
327+
328+
// THEN
329+
expect(stack).toHaveResource('AWS::ElasticLoadBalancingV2::LoadBalancer', {
330+
SecurityGroups: [
331+
{ 'Fn::GetAtt': ['SecurityGroup1F554B36F', 'GroupId'] },
332+
{ 'Fn::GetAtt': ['SecurityGroup23BE86BB7', 'GroupId'] },
333+
],
334+
Type: 'application',
335+
});
336+
});
317337
});

0 commit comments

Comments
 (0)