Skip to content

Commit 1958f26

Browse files
Jimmy Gaussenmergify[bot]
authored andcommitted
feat(elbv2): support UDP and TCP_UDP protocols (#4390)
* feat(elbv2): support udp, tcp_udp protocols * fix: revert NetworkProtocol, JSDoc Protocol, fix tests * chore: revert test order * fix: health check protocol validation, docs * chore: stricter tests
1 parent adbc2e3 commit 1958f26

File tree

7 files changed

+94
-19
lines changed

7 files changed

+94
-19
lines changed

packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps,
66
TargetGroupBase, TargetGroupImportProps
77
} from '../shared/base-target-group';
8-
import { ApplicationProtocol, TargetType } from '../shared/enums';
8+
import { ApplicationProtocol, Protocol, TargetType } from '../shared/enums';
99
import { ImportedTargetGroupBase } from '../shared/imported';
1010
import { determineProtocolAndPort } from '../shared/util';
1111
import { IApplicationListener } from './application-listener';
@@ -309,6 +309,13 @@ export class ApplicationTargetGroup extends TargetGroupBase implements IApplicat
309309
ret.push(`At least one of 'port' or 'protocol' is required for a non-Lambda TargetGroup`);
310310
}
311311

312+
if (this.healthCheck && this.healthCheck.protocol && !ALB_HEALTH_CHECK_PROTOCOLS.includes(this.healthCheck.protocol)) {
313+
ret.push([
314+
`Health check protocol '${this.healthCheck.protocol}' is not supported. `,
315+
`Must be one of [${ALB_HEALTH_CHECK_PROTOCOLS.join(', ')}]`
316+
].join(''));
317+
}
318+
312319
return ret;
313320
}
314321
}
@@ -373,3 +380,5 @@ export interface IApplicationLoadBalancerTarget {
373380
*/
374381
attachToApplicationTargetGroup(targetGroup: IApplicationTargetGroup): LoadBalancerTargetProps;
375382
}
383+
384+
const ALB_HEALTH_CHECK_PROTOCOLS = [Protocol.HTTP, Protocol.HTTPS];

packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ export class NetworkListener extends BaseListener implements INetworkListener {
8989
const certs = props.certificates || [];
9090
const proto = props.protocol || (certs.length > 0 ? Protocol.TLS : Protocol.TCP);
9191

92-
if ([Protocol.TCP, Protocol.TLS].indexOf(proto) === -1) {
93-
throw new Error(`The protocol must be either ${Protocol.TCP} or ${Protocol.TLS}. Found ${props.protocol}`);
92+
if (NLB_PROTOCOLS.indexOf(proto) === -1) {
93+
throw new Error(`The protocol must be one of ${NLB_PROTOCOLS.join(', ')}. Found ${props.protocol}`);
9494
}
9595

9696
if (proto === Protocol.TLS && certs.filter(v => v != null).length === 0) {
@@ -220,3 +220,5 @@ export interface AddNetworkTargetsProps {
220220
*/
221221
readonly healthCheck?: HealthCheck;
222222
}
223+
224+
const NLB_PROTOCOLS = [Protocol.TCP, Protocol.TLS, Protocol.UDP, Protocol.TCP_UDP];

packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-target-group.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ export class NetworkTargetGroup extends TargetGroupBase implements INetworkTarge
106106
if (healthCheck.path) {
107107
ret.push('Health check paths are not supported for Network Load Balancer health checks');
108108
}
109-
if (healthCheck.protocol && healthCheck.protocol !== Protocol.TCP && healthCheck.protocol !== Protocol.TLS) {
110-
ret.push(`Health check protocol '${healthCheck.protocol}' is not supported. Must be one of [TCP, TLS]`);
109+
if (healthCheck.protocol && !NLB_HEALTH_CHECK_PROTOCOLS.includes(healthCheck.protocol)) {
110+
ret.push(`Health check protocol '${healthCheck.protocol}' is not supported. Must be one of [${NLB_HEALTH_CHECK_PROTOCOLS.join(', ')}]`);
111111
}
112112
if (healthCheck.timeout) {
113113
ret.push('Custom health check timeouts are not supported for Network Load Balancer health checks');
@@ -151,3 +151,5 @@ export interface INetworkLoadBalancerTarget {
151151
*/
152152
attachToNetworkTargetGroup(targetGroup: INetworkTargetGroup): LoadBalancerTargetProps;
153153
}
154+
155+
const NLB_HEALTH_CHECK_PROTOCOLS = [Protocol.HTTP, Protocol.HTTPS, Protocol.TCP];

packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ export interface HealthCheck {
8484
/**
8585
* The protocol the load balancer uses when performing health checks on targets.
8686
*
87-
* The TCP protocol is supported only if the protocol of the target group
88-
* is TCP.
87+
* The TCP protocol is supported for health checks only if the protocol of the target group is TCP, TLS, UDP, or TCP_UDP.
88+
* The TLS, UDP, and TCP_UDP protocols are not supported for health checks.
8989
*
9090
* @default HTTP for ALBs, TCP for NLBs
9191
*/

packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/enums.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,38 @@ export enum IpAddressType {
1414
}
1515

1616
/**
17-
* Backend protocol for health checks
17+
* Backend protocol for network load balancers and health checks
1818
*/
1919
export enum Protocol {
2020
/**
21-
* HTTP
21+
* HTTP (ALB health checks and NLB health checks)
2222
*/
2323
HTTP = 'HTTP',
2424

2525
/**
26-
* HTTPS
26+
* HTTPS (ALB health checks and NLB health checks)
2727
*/
2828
HTTPS = 'HTTPS',
2929

3030
/**
31-
* TCP
31+
* TCP (NLB, NLB health checks)
3232
*/
3333
TCP = 'TCP',
3434

3535
/**
36-
* TLS
36+
* TLS (NLB)
37+
*/
38+
TLS = 'TLS',
39+
40+
/**
41+
* UDP (NLB)
42+
*/
43+
UDP = 'UDP',
44+
45+
/**
46+
* Listen to both TCP and UDP on the same port (NLB)
3747
*/
38-
TLS = 'TLS'
48+
TCP_UDP = 'TCP_UDP',
3949
}
4050

4151
/**

packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.listener.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,34 @@ export = {
369369
test.done();
370370
},
371371

372+
'validation error if invalid health check protocol'(test: Test) {
373+
// GIVEN
374+
const stack = new cdk.Stack();
375+
const vpc = new ec2.Vpc(stack, 'Stack');
376+
const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc });
377+
const listener = lb.addListener('Listener', { port: 80 });
378+
379+
// WHEN
380+
const group = listener.addTargets('Group', {
381+
port: 80,
382+
targets: [new FakeSelfRegisteringTarget(stack, 'Target', vpc)]
383+
});
384+
385+
group.configureHealthCheck({
386+
unhealthyThresholdCount: 3,
387+
timeout: cdk.Duration.hours(1),
388+
interval: cdk.Duration.seconds(30),
389+
path: '/test',
390+
protocol: elbv2.Protocol.TCP
391+
});
392+
393+
// THEN
394+
const validationErrors: string[] = (group as any).validate();
395+
test.deepEqual(validationErrors, ["Health check protocol 'TCP' is not supported. Must be one of [HTTP, HTTPS]"]);
396+
397+
test.done();
398+
},
399+
372400
'Can call addTargetGroups on imported listener'(test: Test) {
373401
// GIVEN
374402
const stack = new cdk.Stack();

packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.listener.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@ export = {
179179
const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc });
180180

181181
test.throws(() => lb.addListener('Listener', {
182-
port: 443,
183-
protocol: elbv2.Protocol.HTTP,
184-
defaultTargetGroups: [new elbv2.NetworkTargetGroup(stack, 'Group', { vpc, port: 80 })]
185-
}), Error, '/The protocol must be either TCP or TLS. Found HTTP/');
182+
port: 443,
183+
protocol: elbv2.Protocol.HTTP,
184+
defaultTargetGroups: [new elbv2.NetworkTargetGroup(stack, 'Group', { vpc, port: 80 })]
185+
}), /The protocol must be one of TCP, TLS, UDP, TCP_UDP\. Found HTTP/);
186186

187187
test.done();
188188
},
@@ -206,6 +206,30 @@ export = {
206206
test.done();
207207
},
208208

209+
'validation error if invalid health check protocol'(test: Test) {
210+
const stack = new cdk.Stack();
211+
const vpc = new ec2.Vpc(stack, 'Stack');
212+
const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc });
213+
const listener = lb.addListener('PublicListener', { port: 80 });
214+
const targetGroup = listener.addTargets('ECS', {
215+
port: 80,
216+
healthCheck: {
217+
interval: cdk.Duration.seconds(60)
218+
}
219+
});
220+
221+
targetGroup.configureHealthCheck({
222+
interval: cdk.Duration.seconds(30),
223+
protocol: elbv2.Protocol.UDP
224+
});
225+
226+
// THEN
227+
const validationErrors: string[] = (targetGroup as any).validate();
228+
test.deepEqual(validationErrors, ["Health check protocol 'UDP' is not supported. Must be one of [HTTP, HTTPS, TCP]"]);
229+
230+
test.done();
231+
},
232+
209233
'Protocol & certs TLS listener'(test: Test) {
210234
const stack = new cdk.Stack();
211235
const vpc = new ec2.Vpc(stack, 'Stack');
@@ -215,7 +239,7 @@ export = {
215239
port: 443,
216240
protocol: elbv2.Protocol.TLS,
217241
defaultTargetGroups: [new elbv2.NetworkTargetGroup(stack, 'Group', { vpc, port: 80 })]
218-
}), Error, '/When the protocol is set to TLS, you must specify certificates/');
242+
}), /When the protocol is set to TLS, you must specify certificates/);
219243

220244
test.done();
221245
},
@@ -233,7 +257,7 @@ export = {
233257
protocol: elbv2.Protocol.TCP,
234258
certificates: [ { certificateArn: cert.certificateArn } ],
235259
defaultTargetGroups: [new elbv2.NetworkTargetGroup(stack, 'Group', { vpc, port: 80 })]
236-
}), Error, '/Protocol must be TLS when certificates have been specified/');
260+
}), /Protocol must be TLS when certificates have been specified/);
237261

238262
test.done();
239263
},

0 commit comments

Comments
 (0)