Skip to content

Commit 25b6edd

Browse files
authored
feat(elasticloadbalancing): classic load balancer supports ec2 instances (#24353)
Introducing the `InstanceTarget` class: an EC2 instance that serves as the target for load balancing. This class allows to register an instance to a load balancer. `InstanceTarget ` takes an instance to register as the target for the load balancer. For example, ```ts const target = new elb.InstanceTarget(instance); elb.addTarget(target); ``` creates an InstanceTarget object with the specified instance and then adds it to the load balancer. > [CONTRIBUTING GUIDE]: https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md > [DESIGN GUIDELINES]: https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md Closes #23500. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 9c94d99 commit 25b6edd

13 files changed

+1763
-4
lines changed

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

+17
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,20 @@ lb.addListener({
4848
allowConnectionsFrom: [mySecurityGroup],
4949
});
5050
```
51+
52+
### Adding Ec2 Instance as a target for the load balancer
53+
54+
You can add an EC2 instance to the load balancer by calling using `new InstanceTarget` as the argument to `addTarget()`:
55+
56+
```ts
57+
const lb = new elb.LoadBalancer(this, 'LB', {
58+
vpc,
59+
});
60+
// instance to add as the target for load balancer.
61+
const instance = new Instance(stack, 'targetInstance', {
62+
vpc: vpc,
63+
instanceType: InstanceType.of(InstanceClass.BURSTABLE2, InstanceSize.MICRO),
64+
machineImage: new AmazonLinuxImage(),
65+
});
66+
lb.addTarget(elb.InstanceTarget(instance));
67+
```

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

+30-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
Connections, IConnectable, ISecurityGroup, IVpc, Peer, Port,
2+
Connections, IConnectable, Instance, ISecurityGroup, IVpc, Peer, Port,
33
SecurityGroup, SelectedSubnets, SubnetSelection, SubnetType,
44
} from '@aws-cdk/aws-ec2';
55
import { Duration, Lazy, Resource } from '@aws-cdk/core';
@@ -251,20 +251,21 @@ export class LoadBalancer extends Resource implements IConnectable {
251251

252252
private readonly instancePorts: number[] = [];
253253
private readonly targets: ILoadBalancerTarget[] = [];
254+
private readonly instanceIds: string[] = [];
254255

255256
constructor(scope: Construct, id: string, props: LoadBalancerProps) {
256257
super(scope, id);
257258

258259
this.securityGroup = new SecurityGroup(this, 'SecurityGroup', { vpc: props.vpc, allowAllOutbound: false });
259260
this.connections = new Connections({ securityGroups: [this.securityGroup] });
260-
261261
// Depending on whether the ELB has public or internal IPs, pick the right backend subnets
262262
const selectedSubnets: SelectedSubnets = loadBalancerSubnets(props);
263263

264264
this.elb = new CfnLoadBalancer(this, 'Resource', {
265265
securityGroups: [this.securityGroup.securityGroupId],
266266
subnets: selectedSubnets.subnetIds,
267267
listeners: Lazy.any({ produce: () => this.listeners }),
268+
instances: Lazy.list({ produce: () => this.instanceIds }, { omitEmpty: true }),
268269
scheme: props.internetFacing ? 'internet-facing' : 'internal',
269270
healthCheck: props.healthCheck && healthCheckToJSON(props.healthCheck),
270271
crossZone: props.crossZone ?? true,
@@ -398,6 +399,33 @@ export class LoadBalancer extends Resource implements IConnectable {
398399
Port.tcp(instancePort),
399400
`Port ${instancePort} LB to fleet`);
400401
}
402+
403+
/**
404+
* Add instance to the load balancer.
405+
* @internal
406+
*/
407+
public _addInstanceId(instanceId: string) {
408+
this.instanceIds.push(instanceId);
409+
}
410+
}
411+
412+
/**
413+
* An EC2 instance that is the target for load balancing
414+
*/
415+
export class InstanceTarget implements ILoadBalancerTarget {
416+
readonly connections: Connections;
417+
/**
418+
* Create a new Instance target.
419+
*
420+
* @param instance Instance to register to.
421+
*/
422+
constructor(public readonly instance: Instance) {
423+
this.connections = instance.connections;
424+
}
425+
426+
public attachToClassicLB(loadBalancer: LoadBalancer): void {
427+
loadBalancer._addInstanceId(this.instance.instanceId);
428+
}
401429
}
402430

403431
/**

packages/@aws-cdk/aws-elasticloadbalancing/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"@aws-cdk/assertions": "0.0.0",
8484
"@aws-cdk/cdk-build-tools": "0.0.0",
8585
"@aws-cdk/integ-runner": "0.0.0",
86+
"@aws-cdk/integ-tests": "0.0.0",
8687
"@aws-cdk/cfn2ts": "0.0.0",
8788
"@aws-cdk/pkglint": "0.0.0",
8889
"@types/jest": "^27.5.2"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "29.0.0",
3+
"files": {
4+
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
5+
"source": {
6+
"path": "InstanceTargetTestDefaultTestDeployAssertAF607556.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"Parameters": {
3+
"BootstrapVersion": {
4+
"Type": "AWS::SSM::Parameter::Value<String>",
5+
"Default": "/cdk-bootstrap/hnb659fds/version",
6+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
7+
}
8+
},
9+
"Rules": {
10+
"CheckBootstrapVersion": {
11+
"Assertions": [
12+
{
13+
"Assert": {
14+
"Fn::Not": [
15+
{
16+
"Fn::Contains": [
17+
[
18+
"1",
19+
"2",
20+
"3",
21+
"4",
22+
"5"
23+
],
24+
{
25+
"Ref": "BootstrapVersion"
26+
}
27+
]
28+
}
29+
]
30+
},
31+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
32+
}
33+
]
34+
}
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "29.0.0",
3+
"files": {
4+
"11ca0111a871a53be970c5db0c5a24d4146213fd59f6d172b6fc1bc3de206cf9": {
5+
"source": {
6+
"path": "aws-cdk-elb-instance-target-integ.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "11ca0111a871a53be970c5db0c5a24d4146213fd59f6d172b6fc1bc3de206cf9.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}

0 commit comments

Comments
 (0)