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 df442537b7232..acb3c8fe7ff76 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -968,6 +968,7 @@ abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGrou public abstract readonly osType: ec2.OperatingSystemType; protected albTargetGroup?: elbv2.ApplicationTargetGroup; public readonly grantPrincipal: iam.IPrincipal = new iam.UnknownPrincipal({ resource: this }); + protected hasSetScaleOnRequest: boolean = false; /** * Send a message to either an SQS queue or SNS topic when instances launch or terminate @@ -1071,6 +1072,7 @@ abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGrou }); policy.node.addDependency(this.albTargetGroup.loadBalancerAttached); + this.hasSetScaleOnRequest = true; return policy; } @@ -1370,6 +1372,8 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements if (props.requireImdsv2) { Aspects.of(this).add(new AutoScalingGroupRequireImdsv2Aspect()); } + + this.node.addValidation({ validate: () => this.validateTargetGroup() }); } /** @@ -1397,10 +1401,6 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements * Attach to ELBv2 Application Target Group */ public attachToApplicationTargetGroup(targetGroup: elbv2.IApplicationTargetGroup): elbv2.LoadBalancerTargetProps { - if (this.albTargetGroup !== undefined) { - throw new Error('Cannot add AutoScalingGroup to 2nd Target Group'); - } - this.targetGroupArns.push(targetGroup.targetGroupArn); if (targetGroup instanceof elbv2.ApplicationTargetGroup) { // Copy onto self if it's a concrete type. We need this for autoscaling @@ -1747,6 +1747,16 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements }; } } + + + private validateTargetGroup(): string[] { + const errors = new Array(); + if (this.hasSetScaleOnRequest && this.targetGroupArns.length > 1) { + errors.push('Cannon use multiple target groups if `setScaleOnRequest()` is being used.'); + } + + return errors; + } } /** diff --git a/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts b/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts index 48062024b9fb4..d73a332d4aab6 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts @@ -2,6 +2,7 @@ import { Annotations, Match, Template } from '@aws-cdk/assertions'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import { AmazonLinuxCpuType, AmazonLinuxGeneration, AmazonLinuxImage, InstanceType, LaunchTemplate } from '@aws-cdk/aws-ec2'; +import { ApplicationLoadBalancer, ApplicationTargetGroup } from '@aws-cdk/aws-elasticloadbalancingv2'; import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; import { testDeprecated } from '@aws-cdk/cdk-build-tools'; @@ -1845,6 +1846,43 @@ describe('auto scaling group', () => { })).not.toThrow(); }); + + test('Should validate multiple target groups i conjunction with `setScaleOnRequest()`', () => { + const stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' } }); + + + const vpc = mockVpc(stack); + + const alb = new ApplicationLoadBalancer(stack, 'alb', { + vpc, + internetFacing: true, + }); + + const listener = alb.addListener('Listener', { + port: 80, + open: true, + }); + const asg = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage(), + vpc, + }); + + const atg1 = new ApplicationTargetGroup(stack, 'ATG1', { port: 443 }); + const atg2 = new ApplicationTargetGroup(stack, 'ATG2', { port: 443 }); + + listener.addTargetGroups('tgs', { targetGroups: [atg1, atg2] }); + + asg.attachToApplicationTargetGroup(atg1); + asg.attachToApplicationTargetGroup(atg2); + + expect(asg.node.validate()).toEqual([]); + + asg.scaleOnRequestCount('requests-per-minute', { targetRequestsPerMinute: 60 }); + + expect(asg.node.validate()).toContainEqual('Cannon use multiple target groups if `setScaleOnRequest()` is being used.'); + + }); }); function mockVpc(stack: cdk.Stack) {