Skip to content

Commit

Permalink
feat(elasticloadbalancing): classic load balancer supports ec2 instan…
Browse files Browse the repository at this point in the history
…ces (#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*
  • Loading branch information
pattasai authored Mar 17, 2023
1 parent 9c94d99 commit 25b6edd
Show file tree
Hide file tree
Showing 13 changed files with 1,763 additions and 4 deletions.
17 changes: 17 additions & 0 deletions packages/@aws-cdk/aws-elasticloadbalancing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,20 @@ lb.addListener({
allowConnectionsFrom: [mySecurityGroup],
});
```

### Adding Ec2 Instance as a target for the load balancer

You can add an EC2 instance to the load balancer by calling using `new InstanceTarget` as the argument to `addTarget()`:

```ts
const lb = new elb.LoadBalancer(this, 'LB', {
vpc,
});
// instance to add as the target for load balancer.
const instance = new Instance(stack, 'targetInstance', {
vpc: vpc,
instanceType: InstanceType.of(InstanceClass.BURSTABLE2, InstanceSize.MICRO),
machineImage: new AmazonLinuxImage(),
});
lb.addTarget(elb.InstanceTarget(instance));
```
32 changes: 30 additions & 2 deletions packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
Connections, IConnectable, ISecurityGroup, IVpc, Peer, Port,
Connections, IConnectable, Instance, ISecurityGroup, IVpc, Peer, Port,
SecurityGroup, SelectedSubnets, SubnetSelection, SubnetType,
} from '@aws-cdk/aws-ec2';
import { Duration, Lazy, Resource } from '@aws-cdk/core';
Expand Down Expand Up @@ -251,20 +251,21 @@ export class LoadBalancer extends Resource implements IConnectable {

private readonly instancePorts: number[] = [];
private readonly targets: ILoadBalancerTarget[] = [];
private readonly instanceIds: string[] = [];

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

this.securityGroup = new SecurityGroup(this, 'SecurityGroup', { vpc: props.vpc, allowAllOutbound: false });
this.connections = new Connections({ securityGroups: [this.securityGroup] });

// Depending on whether the ELB has public or internal IPs, pick the right backend subnets
const selectedSubnets: SelectedSubnets = loadBalancerSubnets(props);

this.elb = new CfnLoadBalancer(this, 'Resource', {
securityGroups: [this.securityGroup.securityGroupId],
subnets: selectedSubnets.subnetIds,
listeners: Lazy.any({ produce: () => this.listeners }),
instances: Lazy.list({ produce: () => this.instanceIds }, { omitEmpty: true }),
scheme: props.internetFacing ? 'internet-facing' : 'internal',
healthCheck: props.healthCheck && healthCheckToJSON(props.healthCheck),
crossZone: props.crossZone ?? true,
Expand Down Expand Up @@ -398,6 +399,33 @@ export class LoadBalancer extends Resource implements IConnectable {
Port.tcp(instancePort),
`Port ${instancePort} LB to fleet`);
}

/**
* Add instance to the load balancer.
* @internal
*/
public _addInstanceId(instanceId: string) {
this.instanceIds.push(instanceId);
}
}

/**
* An EC2 instance that is the target for load balancing
*/
export class InstanceTarget implements ILoadBalancerTarget {
readonly connections: Connections;
/**
* Create a new Instance target.
*
* @param instance Instance to register to.
*/
constructor(public readonly instance: Instance) {
this.connections = instance.connections;
}

public attachToClassicLB(loadBalancer: LoadBalancer): void {
loadBalancer._addInstanceId(this.instance.instanceId);
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-elasticloadbalancing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@aws-cdk/assertions": "0.0.0",
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/integ-tests": "0.0.0",
"@aws-cdk/cfn2ts": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.5.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "29.0.0",
"files": {
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
"source": {
"path": "InstanceTargetTestDefaultTestDeployAssertAF607556.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "29.0.0",
"files": {
"11ca0111a871a53be970c5db0c5a24d4146213fd59f6d172b6fc1bc3de206cf9": {
"source": {
"path": "aws-cdk-elb-instance-target-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "11ca0111a871a53be970c5db0c5a24d4146213fd59f6d172b6fc1bc3de206cf9.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Loading

0 comments on commit 25b6edd

Please sign in to comment.