From c9a4dc27187ba688675b29ba28a34656d7c2a46d Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 13 Sep 2018 14:15:03 +0200 Subject: [PATCH 1/4] BREAKING: move LoadBalancer to aws-elasticloadbalancing package This is where it should have been all along. --- .../aws-autoscaling/lib/auto-scaling-group.ts | 5 +- .../@aws-cdk/aws-autoscaling/package.json | 1 + .../test/integ.asg-w-loadbalancer.ts | 3 +- packages/@aws-cdk/aws-ec2/lib/index.ts | 1 - packages/@aws-cdk/aws-ec2/package.json | 1 - .../aws-elasticloadbalancing/lib/index.ts | 2 + .../lib/load-balancer.ts | 54 ++--- .../aws-elasticloadbalancing/package.json | 4 +- .../test/integ.elb.expected.json | 228 ++++++++++++++++++ .../test/integ.elb.ts | 26 ++ .../test/test.elasticloadbalancing.ts | 8 - .../test/test.loadbalancer.ts | 5 +- 12 files changed, 294 insertions(+), 44 deletions(-) rename packages/@aws-cdk/{aws-ec2 => aws-elasticloadbalancing}/lib/load-balancer.ts (83%) create mode 100644 packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json create mode 100644 packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts delete mode 100644 packages/@aws-cdk/aws-elasticloadbalancing/test/test.elasticloadbalancing.ts rename packages/@aws-cdk/{aws-ec2 => aws-elasticloadbalancing}/test/test.loadbalancer.ts (85%) diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index fc8ff9c4720ba..26bb60f910fef 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -1,4 +1,5 @@ import ec2 = require('@aws-cdk/aws-ec2'); +import elb = require('@aws-cdk/aws-elasticloadbalancing'); import iam = require('@aws-cdk/aws-iam'); import sns = require('@aws-cdk/aws-sns'); import cdk = require('@aws-cdk/cdk'); @@ -135,7 +136,7 @@ export interface AutoScalingGroupProps { * * The ASG spans all availability zones. */ -export class AutoScalingGroup extends cdk.Construct implements ec2.IClassicLoadBalancerTarget, ec2.IConnectable { +export class AutoScalingGroup extends cdk.Construct implements elb.ILoadBalancerTarget, ec2.IConnectable { /** * The type of OS instances of this fleet are running. */ @@ -240,7 +241,7 @@ export class AutoScalingGroup extends cdk.Construct implements ec2.IClassicLoadB this.securityGroups.push(securityGroup); } - public attachToClassicLB(loadBalancer: ec2.ClassicLoadBalancer): void { + public attachToClassicLB(loadBalancer: elb.LoadBalancer): void { this.loadBalancerNames.push(loadBalancer.loadBalancerName); } diff --git a/packages/@aws-cdk/aws-autoscaling/package.json b/packages/@aws-cdk/aws-autoscaling/package.json index 80eb9c9f6dc39..a918c3766f65b 100644 --- a/packages/@aws-cdk/aws-autoscaling/package.json +++ b/packages/@aws-cdk/aws-autoscaling/package.json @@ -61,6 +61,7 @@ "dependencies": { "@aws-cdk/aws-ec2": "^0.9.0", "@aws-cdk/aws-iam": "^0.9.0", + "@aws-cdk/aws-elasticloadbalancing": "^0.9.0", "@aws-cdk/aws-sns": "^0.9.0", "@aws-cdk/cdk": "^0.9.0" }, diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts index 5a31c3c95700d..1f2ed44b61804 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts @@ -1,5 +1,6 @@ #!/usr/bin/env node import ec2 = require('@aws-cdk/aws-ec2'); +import elb = require('@aws-cdk/aws-elasticloadbalancing'); import cdk = require('@aws-cdk/cdk'); import autoscaling = require('../lib'); @@ -16,7 +17,7 @@ const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', { machineImage: new ec2.AmazonLinuxImage(), }); -new ec2.ClassicLoadBalancer(stack, 'LB', { +new elb.LoadBalancer(stack, 'LB', { vpc, internetFacing: true, listeners: [{ diff --git a/packages/@aws-cdk/aws-ec2/lib/index.ts b/packages/@aws-cdk/aws-ec2/lib/index.ts index 28bd413c5a9cf..9e6e38d27bba0 100644 --- a/packages/@aws-cdk/aws-ec2/lib/index.ts +++ b/packages/@aws-cdk/aws-ec2/lib/index.ts @@ -1,6 +1,5 @@ export * from './connections'; export * from './instance-types'; -export * from './load-balancer'; export * from './machine-image'; export * from './security-group'; export * from './security-group-rule'; diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index cb1d84f4189da..02a37b160189d 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -59,7 +59,6 @@ "pkglint": "^0.9.0" }, "dependencies": { - "@aws-cdk/aws-elasticloadbalancing": "^0.9.0", "@aws-cdk/aws-iam": "^0.9.0", "@aws-cdk/cdk": "^0.9.0", "@aws-cdk/util": "^0.9.0" diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/lib/index.ts b/packages/@aws-cdk/aws-elasticloadbalancing/lib/index.ts index ca0a911e001da..ed23ccf109691 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/lib/index.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/lib/index.ts @@ -1,2 +1,4 @@ // AWS::ElasticLoadBalancing CloudFormation Resources: export * from './elasticloadbalancing.generated'; + +export * from './load-balancer'; \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/lib/load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts similarity index 83% rename from packages/@aws-cdk/aws-ec2/lib/load-balancer.ts rename to packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts index f4436294e69fa..cb5e1bb42a6c6 100644 --- a/packages/@aws-cdk/aws-ec2/lib/load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts @@ -1,14 +1,12 @@ -import elasticloadbalancing = require('@aws-cdk/aws-elasticloadbalancing'); +import { AnyIPv4, Connections, IConnectable, IPortRange, SecurityGroup, SecurityGroupRef, + TcpPort, VpcNetworkRef, VpcSubnetRef } from '@aws-cdk/aws-ec2'; import cdk = require('@aws-cdk/cdk'); -import { Connections, IConnectable } from './connections'; -import { SecurityGroup, SecurityGroupRef } from './security-group'; -import { AnyIPv4, IPortRange, TcpPort } from './security-group-rule'; -import { VpcNetworkRef, VpcSubnetRef } from './vpc-ref'; +import { cloudformation } from './elasticloadbalancing.generated'; /** - * Construction properties for a ClassicLoadBalancer + * Construction properties for a LoadBalancer */ -export interface ClassicLoadBalancerProps { +export interface LoadBalancerProps { /** * VPC network of the fleet instances */ @@ -29,14 +27,14 @@ export interface ClassicLoadBalancerProps { * * Can also be added by .addListener() */ - listeners?: ClassicLoadBalancerListener[]; + listeners?: LoadBalancerListener[]; /** * What targets to load balance to. * * Can also be added by .addTarget() */ - targets?: IClassicLoadBalancerTarget[]; + targets?: ILoadBalancerTarget[]; /** * Health check settings for the load balancing targets. @@ -106,17 +104,17 @@ export interface HealthCheck { /** * Interface that is going to be implemented by constructs that you can load balance to */ -export interface IClassicLoadBalancerTarget extends IConnectable { +export interface ILoadBalancerTarget extends IConnectable { /** * Attach load-balanced target to a classic ELB */ - attachToClassicLB(loadBalancer: ClassicLoadBalancer): void; + attachToClassicLB(loadBalancer: LoadBalancer): void; } /** * Add a backend to the load balancer */ -export interface ClassicLoadBalancerListener { +export interface LoadBalancerListener { /** * External listening port */ @@ -187,7 +185,7 @@ export enum LoadBalancingProtocol { * * Routes to a fleet of of instances in a VPC. */ -export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { +export class LoadBalancer extends cdk.Construct implements IConnectable { /** * Control all connections from and to this load balancer */ @@ -196,16 +194,16 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { /** * An object controlling specifically the connections for each listener added to this load balancer */ - public readonly listenerPorts: ClassicListenerPort[] = []; + public readonly listenerPorts: ListenerPort[] = []; - private readonly elb: elasticloadbalancing.cloudformation.LoadBalancerResource; + private readonly elb: cloudformation.LoadBalancerResource; private readonly securityGroup: SecurityGroup; - private readonly listeners: elasticloadbalancing.cloudformation.LoadBalancerResource.ListenersProperty[] = []; + private readonly listeners: cloudformation.LoadBalancerResource.ListenersProperty[] = []; private readonly instancePorts: number[] = []; - private readonly targets: IClassicLoadBalancerTarget[] = []; + private readonly targets: ILoadBalancerTarget[] = []; - constructor(parent: cdk.Construct, name: string, props: ClassicLoadBalancerProps) { + constructor(parent: cdk.Construct, name: string, props: LoadBalancerProps) { super(parent, name); this.securityGroup = new SecurityGroup(this, 'SecurityGroup', { vpc: props.vpc }); @@ -214,7 +212,7 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { // Depending on whether the ELB has public or internal IPs, pick the right backend subnets const subnets: VpcSubnetRef[] = props.internetFacing ? props.vpc.publicSubnets : props.vpc.privateSubnets; - this.elb = new elasticloadbalancing.cloudformation.LoadBalancerResource(this, 'Resource', { + this.elb = new cloudformation.LoadBalancerResource(this, 'Resource', { securityGroups: [ this.securityGroup.securityGroupId ], subnets: subnets.map(s => s.subnetId), listeners: new cdk.Token(() => this.listeners), @@ -229,9 +227,9 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { /** * Add a backend to the load balancer * - * @returns A ClassicListenerPort object that controls connections to the listener port + * @returns A ListenerPort object that controls connections to the listener port */ - public addListener(listener: ClassicLoadBalancerListener): ClassicListenerPort { + public addListener(listener: LoadBalancerListener): ListenerPort { const protocol = ifUndefinedLazy(listener.externalProtocol, () => wellKnownProtocol(listener.externalPort)); const instancePort = listener.internalPort || listener.externalPort; const instanceProtocol = ifUndefined(listener.internalProtocol, @@ -247,7 +245,7 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { policyNames: listener.policyNames }); - const port = new ClassicListenerPort(this.securityGroup, new TcpPort(listener.externalPort)); + const port = new ListenerPort(this.securityGroup, new TcpPort(listener.externalPort)); // Allow connections on the public port for all supplied peers (default: everyone) ifUndefined(listener.allowConnectionsFrom, [new AnyIPv4()]).forEach(peer => { @@ -262,7 +260,7 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { return port; } - public addTarget(target: IClassicLoadBalancerTarget) { + public addTarget(target: ILoadBalancerTarget) { target.attachToClassicLB(this); this.newTarget(target); @@ -301,7 +299,7 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { /** * Allow connections to target on all existing instance ports */ - private newTarget(target: IClassicLoadBalancerTarget) { + private newTarget(target: ILoadBalancerTarget) { this.instancePorts.forEach(p => this.allowTargetConnection(p, target)); // Keep track of target for future listeners. @@ -311,7 +309,7 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { /** * Allow connections for a single (port, target) pair */ - private allowTargetConnection(instancePort: number, target: IClassicLoadBalancerTarget) { + private allowTargetConnection(instancePort: number, target: ILoadBalancerTarget) { this.connections.allowTo( target, new TcpPort(instancePort), @@ -332,7 +330,7 @@ export class ClassicLoadBalancer extends cdk.Construct implements IConnectable { * // or * instance.connections.allowToDefaultPort(listener); */ -export class ClassicListenerPort implements IConnectable { +export class ListenerPort implements IConnectable { public readonly connections: Connections; constructor(securityGroup: SecurityGroupRef, defaultPortRange: IPortRange) { @@ -367,9 +365,9 @@ function ifUndefinedLazy(x: T | undefined, def: () => T): T { } /** - * Turn health check parameters into a parameter blob for the Classic LB + * Turn health check parameters into a parameter blob for the LB */ -function healthCheckToJSON(healthCheck: HealthCheck): elasticloadbalancing.cloudformation.LoadBalancerResource.HealthCheckProperty { +function healthCheckToJSON(healthCheck: HealthCheck): cloudformation.LoadBalancerResource.HealthCheckProperty { const protocol = ifUndefined(healthCheck.protocol, ifUndefined(tryWellKnownProtocol(healthCheck.port), LoadBalancingProtocol.Tcp)); diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/package.json b/packages/@aws-cdk/aws-elasticloadbalancing/package.json index 6397084cfca39..8fa2f8ce38404 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/package.json +++ b/packages/@aws-cdk/aws-elasticloadbalancing/package.json @@ -54,11 +54,13 @@ "devDependencies": { "@aws-cdk/assert": "^0.9.0", "cdk-build-tools": "^0.9.0", + "cdk-integ-tools": "^0.9.0", "cfn2ts": "^0.9.0", "pkglint": "^0.9.0" }, "dependencies": { - "@aws-cdk/cdk": "^0.9.0" + "@aws-cdk/cdk": "^0.9.0", + "@aws-cdk/aws-ec2": "^0.9.0" }, "homepage": "https://github.com/awslabs/aws-cdk" } diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json new file mode 100644 index 0000000000000..4b05529da2869 --- /dev/null +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json @@ -0,0 +1,228 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-elb-integ/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/17", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-elb-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-elb-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableAssociatioin249B4093": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc" + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-elb-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/17", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-elb-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-elb-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableAssociatioin77F7CA18": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-elb-integ/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "LBSecurityGroup8A41EA2B": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-cdk-elb-integ/LB/SecurityGroup", + "SecurityGroupEgress": [], + "SecurityGroupIngress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Default rule allow on 80", + "FromPort": 80, + "IpProtocol": "tcp", + "ToPort": 80 + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "LB8A12904C": { + "Type": "AWS::ElasticLoadBalancing::LoadBalancer", + "Properties": { + "Listeners": [ + { + "InstancePort": "80", + "InstanceProtocol": "http", + "LoadBalancerPort": "80", + "Protocol": "http" + } + ], + "HealthCheck": { + "HealthyThreshold": "2", + "Interval": "30", + "Target": "HTTP:80/", + "Timeout": "5", + "UnhealthyThreshold": "5" + }, + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "LBSecurityGroup8A41EA2B", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + ] + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts new file mode 100644 index 0000000000000..d7b150e524719 --- /dev/null +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts @@ -0,0 +1,26 @@ +#!/usr/bin/env node +import ec2 = require('@aws-cdk/aws-ec2'); +import cdk = require('@aws-cdk/cdk'); +import elb = require('../lib'); + +const app = new cdk.App(process.argv); +const stack = new cdk.Stack(app, 'aws-cdk-elb-integ'); + +const vpc = new ec2.VpcNetwork(stack, 'VPC', { + maxAZs: 1 +}); + +new elb.LoadBalancer(stack, 'LB', { + vpc, + internetFacing: true, + listeners: [{ + externalPort: 80, + allowConnectionsFrom: [new ec2.AnyIPv4()] + }], + healthCheck: { + port: 80 + }, + targets: [] +}); + +process.stdout.write(app.run()); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/test.elasticloadbalancing.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.elasticloadbalancing.ts deleted file mode 100644 index db4c843199541..0000000000000 --- a/packages/@aws-cdk/aws-elasticloadbalancing/test/test.elasticloadbalancing.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Test, testCase } from 'nodeunit'; - -exports = testCase({ - notTested(test: Test) { - test.ok(true, 'No tests are specified for this package.'); - test.done(); - } -}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.loadbalancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts similarity index 85% rename from packages/@aws-cdk/aws-ec2/test/test.loadbalancer.ts rename to packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts index b4cb8a197b097..7a8d824520f99 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.loadbalancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts @@ -1,7 +1,8 @@ import { expect, haveResource } from '@aws-cdk/assert'; +import { VpcNetwork } from '@aws-cdk/aws-ec2'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { ClassicLoadBalancer, LoadBalancingProtocol, VpcNetwork } from '../lib'; +import { LoadBalancer, LoadBalancingProtocol } from '../lib'; export = { 'test specifying nonstandard port works'(test: Test) { @@ -9,7 +10,7 @@ export = { stack.setContext('availability-zones:1234:test', ['test-1a', 'test-1b']); const vpc = new VpcNetwork(stack, 'VCP'); - const lb = new ClassicLoadBalancer(stack, 'LB', { vpc }); + const lb = new LoadBalancer(stack, 'LB', { vpc }); lb.addListener({ externalProtocol: LoadBalancingProtocol.Http, From 12c4dd03cdad21113013f5ea9d1242663c91e510 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 13 Sep 2018 14:18:16 +0200 Subject: [PATCH 2/4] Update examples to use new ELB location --- examples/cdk-examples-typescript/ec2/index.ts | 5 +++-- examples/cdk-examples-typescript/package.json | 1 + .../use-vpc-from-another-stack/index.ts | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/cdk-examples-typescript/ec2/index.ts b/examples/cdk-examples-typescript/ec2/index.ts index 3153c7270041d..2962b8f62850c 100644 --- a/examples/cdk-examples-typescript/ec2/index.ts +++ b/examples/cdk-examples-typescript/ec2/index.ts @@ -1,5 +1,6 @@ import autoscaling = require('@aws-cdk/aws-autoscaling'); import ec2 = require('@aws-cdk/aws-ec2'); +import elb = require('@aws-cdk/aws-elasticloadbalancing'); import cdk = require('@aws-cdk/cdk'); class AppWithVpc extends cdk.Stack { @@ -14,7 +15,7 @@ class AppWithVpc extends cdk.Stack { machineImage: new ec2.AmazonLinuxImage() }); - const clb = new ec2.ClassicLoadBalancer(this, 'LB', { + const clb = new elb.LoadBalancer(this, 'LB', { vpc, internetFacing: true }); @@ -40,7 +41,7 @@ class MyApp extends cdk.Stack { machineImage: new ec2.AmazonLinuxImage() }); - const clb = new ec2.ClassicLoadBalancer(this, 'LB', { + const clb = new elb.LoadBalancer(this, 'LB', { vpc, internetFacing: true }); diff --git a/examples/cdk-examples-typescript/package.json b/examples/cdk-examples-typescript/package.json index 835fa60ff8177..824c6dd05c422 100644 --- a/examples/cdk-examples-typescript/package.json +++ b/examples/cdk-examples-typescript/package.json @@ -28,6 +28,7 @@ "@aws-cdk/aws-cognito": "^0.9.0", "@aws-cdk/aws-dynamodb": "^0.9.0", "@aws-cdk/aws-ec2": "^0.9.0", + "@aws-cdk/aws-elasticloadbalancing": "^0.9.0", "@aws-cdk/aws-iam": "^0.9.0", "@aws-cdk/aws-lambda": "^0.9.0", "@aws-cdk/aws-neptune": "^0.9.0", diff --git a/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts b/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts index f62a5648d68a3..14b26922efa49 100644 --- a/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts +++ b/examples/cdk-examples-typescript/use-vpc-from-another-stack/index.ts @@ -5,6 +5,7 @@ // until we have that. import autoscaling = require('@aws-cdk/aws-autoscaling'); import ec2 = require('@aws-cdk/aws-ec2'); +import elb = require('@aws-cdk/aws-elasticloadbalancing'); import cdk = require('@aws-cdk/cdk'); const app = new cdk.App(process.argv); @@ -24,7 +25,7 @@ const asg = new autoscaling.AutoScalingGroup(appStack, 'ASG', { machineImage: new ec2.AmazonLinuxImage() }); -new ec2.ClassicLoadBalancer(appStack, 'LB', { +new elb.LoadBalancer(appStack, 'LB', { vpc: importedVpc, internetFacing: true, listeners: [{ From 434296a0f53e020924bd0f795b43200e32cdfa0f Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 13 Sep 2018 15:35:18 +0200 Subject: [PATCH 3/4] Add more tests --- .../test/test.loadbalancer.ts | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts index 7a8d824520f99..14070ec83dbcb 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts @@ -1,8 +1,8 @@ import { expect, haveResource } from '@aws-cdk/assert'; -import { VpcNetwork } from '@aws-cdk/aws-ec2'; +import { CidrIPv4, Connections, VpcNetwork } from '@aws-cdk/aws-ec2'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { LoadBalancer, LoadBalancingProtocol } from '../lib'; +import { ILoadBalancerTarget, LoadBalancer, LoadBalancingProtocol } from '../lib'; export = { 'test specifying nonstandard port works'(test: Test) { @@ -28,6 +28,80 @@ export = { }] })); + test.done(); + }, + + 'add a health check'(test: Test) { + // GIVEN + const stack = new Stack(); + const vpc = new VpcNetwork(stack, 'VCP'); + + // WHEN + new LoadBalancer(stack, 'LB', { + vpc, + healthCheck: { + interval: 60, + path: '/ping', + protocol: LoadBalancingProtocol.Https, + port: 443, + } + }); + + // THEN + expect(stack).to(haveResource("AWS::ElasticLoadBalancing::LoadBalancer", { + HealthCheck: { + HealthyThreshold: "2", + Interval: "60", + Target: "HTTPS:443/ping", + Timeout: "5", + UnhealthyThreshold: "5" + }, + })); + + test.done(); + }, + + 'add a listener and load balancing target'(test: Test) { + // GIVEN + const stack = new Stack(); + const vpc = new VpcNetwork(stack, 'VCP'); + const elb = new LoadBalancer(stack, 'LB', { + vpc, + healthCheck: { + interval: 60, + path: '/ping', + protocol: LoadBalancingProtocol.Https, + port: 443, + } + }); + + // WHEN + elb.addListener({ externalPort: 80, internalPort: 8080 }); + elb.addTarget(new FakeTarget()); + + // THEN: at the very least it added a security group rule for the backend + expect(stack).to(haveResource('AWS::EC2::SecurityGroup', { + SecurityGroupEgress: [ + { + CidrIp: "666.666.666.666/666", + FromPort: 8080, + IpProtocol: "tcp", + ToPort: 8080 + } + ], + })); + test.done(); } }; + +class FakeTarget implements ILoadBalancerTarget { + public readonly connections = new Connections({ + securityGroupRule: new CidrIPv4('666.666.666.666/666') + }); + + public attachToClassicLB(_loadBalancer: LoadBalancer): void { + // Nothing to do. Normally we set a property on ourselves so + // our instances know to bind to the LB on startup. + } +} From 4e25a710ca9b0528f923ba05810654a0bf890f17 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 13 Sep 2018 15:47:42 +0200 Subject: [PATCH 4/4] Move README section --- .../test/integ.asg-w-loadbalancer.ts | 10 ++--- packages/@aws-cdk/aws-ec2/README.md | 28 +------------- .../aws-elasticloadbalancing/README.md | 37 ++++++++++++++++++- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts index 1f2ed44b61804..776f2bc33a7ab 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-loadbalancer.ts @@ -17,17 +17,15 @@ const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', { machineImage: new ec2.AmazonLinuxImage(), }); -new elb.LoadBalancer(stack, 'LB', { +const lb = new elb.LoadBalancer(stack, 'LB', { vpc, internetFacing: true, - listeners: [{ - externalPort: 80, - allowConnectionsFrom: [new ec2.AnyIPv4()] - }], healthCheck: { port: 80 }, - targets: [asg] }); +lb.addTarget(asg); +lb.addListener({ externalPort: 80 }); + process.stdout.write(app.run()); diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index a357f5a93558f..fb5c7164616b4 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -1,7 +1,7 @@ ## AWS Compute and Networking Construct Library -The `@aws-cdk/aws-ec2` package contains primitives for setting up networking, -instances, and load balancers. +The `@aws-cdk/aws-ec2` package contains primitives for setting up networking and +instances. ### VPC @@ -172,30 +172,6 @@ The `VpcNetwork` above will have the exact same subnet definitions as listed above. However, this time the VPC will have only 1 NAT Gateway and all Application subnets will route to the NAT Gateway. - -### Load Balancer - -Load balancers send traffic to one or more fleets. Create a load balancer, -set up listeners and a health check, and supply the fleet(s) you want to load -balance to in the `targets` property. - -The load balancer allows all connections by default. If you want to change that, -pass the `allowConnectionsFrom` property while setting up the listener. - -```ts -new ec2.ClassicLoadBalancer(stack, 'LB', { - vpc, - internetFacing: true, - listeners: [{ - externalPort: 80, - }], - healthCheck: { - port: 80 - }, - targets: [fleet] -}); -``` - ### Allowing Connections In AWS, all connections to and from EC2 instances are governed by *Security diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/README.md b/packages/@aws-cdk/aws-elasticloadbalancing/README.md index 45244f2937771..a2cfc7ffd5cb0 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/README.md +++ b/packages/@aws-cdk/aws-elasticloadbalancing/README.md @@ -1,2 +1,35 @@ -## CDK Constructs for AWS Elastic Load Balancing (ELB) -This module is part of the [AWS Cloud Development Kit](https://github.com/awslabs/aws-cdk) project. +## AWS Elastic Load Balancing Construct Library + +The `@aws-cdk/aws-ec2` package provides constructs for configuring +classic load balancers. + +### Configuring a Load Balancer + +Load balancers send traffic to one or more AutoScalingGroups. Create a load +balancer, set up listeners and a health check, and supply the fleet(s) you want +to load balance to in the `targets` property. + +```ts +const lb = new elb.LoadBalancer(stack, 'LB', { + vpc, + internetFacing: true, + healthCheck: { + port: 80 + }, +}); + +lb.addTarget(myAutoScalingGroup); +lb.addListener({ + externalPort: 80, +}); +``` + +The load balancer allows all connections by default. If you want to change that, +pass the `allowConnectionsFrom` property while setting up the listener: + +``` +lb.addListener({ + externalPort: 80, + allowConnectionsFrom: [mySecurityGroup] +}); +```