Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ecs-patterns): handle desired task count being set to 0 #4722

Merged
merged 14 commits into from
Nov 4, 2019
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface ApplicationLoadBalancedServiceBaseProps {

/**
* The desired number of instantiations of the task definition to keep running on the service.
* The minimum value is 1
*
* @default 1
*/
Expand Down Expand Up @@ -258,6 +259,9 @@ export abstract class ApplicationLoadBalancedServiceBase extends cdk.Construct {
}
this.cluster = props.cluster || this.getDefaultCluster(this, props.vpc);

if (props.desiredCount !== undefined && props.desiredCount < 1) {
throw new Error('You must specify a desiredCount greater than 0');
}
this.desiredCount = props.desiredCount || 1;

const internetFacing = props.publicLoadBalancer !== undefined ? props.publicLoadBalancer : true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface NetworkLoadBalancedServiceBaseProps {

/**
* The desired number of instantiations of the task definition to keep running on the service.
* The minimum value is 1
*
* @default 1
*/
Expand Down Expand Up @@ -230,6 +231,9 @@ export abstract class NetworkLoadBalancedServiceBase extends cdk.Construct {
}
this.cluster = props.cluster || this.getDefaultCluster(this, props.vpc);

if (props.desiredCount !== undefined && props.desiredCount < 1) {
throw new Error('You must specify a desiredCount greater than 0');
}
this.desiredCount = props.desiredCount || 1;

const internetFacing = props.publicLoadBalancer !== undefined ? props.publicLoadBalancer : true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,13 @@ export abstract class QueueProcessingServiceBase extends Construct {
this.secrets = props.secrets;

// Determine the desired task count (minimum) and maximum scaling capacity
this.desiredCount = props.desiredTaskCount || 1;
this.desiredCount = props.desiredTaskCount !== undefined ? props.desiredTaskCount : 1;
this.maxCapacity = props.maxScalingCapacity || (2 * this.desiredCount);
piradeepk marked this conversation as resolved.
Show resolved Hide resolved

if (!this.desiredCount && !this.maxCapacity) {
throw new Error(`maxScalingCapacity must be set and greater than 0 if desiredCount is 0`);
}

new CfnOutput(this, 'SQSQueue', { value: this.sqsQueue.queueName });
new CfnOutput(this, 'SQSQueueArn', { value: this.sqsQueue.queueArn });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export abstract class ScheduledTaskBase extends Construct {
public readonly cluster: ICluster;
/**
* The desired number of instantiations of the task definition to keep running on the service.
*
* The minimum value is 1
*/
public readonly desiredTaskCount: number;

Expand All @@ -105,6 +107,9 @@ export abstract class ScheduledTaskBase extends Construct {
super(scope, id);

this.cluster = props.cluster || this.getDefaultCluster(this, props.vpc);
if (props.desiredTaskCount !== undefined && props.desiredTaskCount < 1) {
throw new Error('You must specify a desiredTaskCount greater than 0');
}
this.desiredTaskCount = props.desiredTaskCount || 1;

// An EventRule that describes the event trigger (in this case a scheduled run)
Expand Down
44 changes: 44 additions & 0 deletions packages/@aws-cdk/aws-ecs-patterns/test/ec2/test.l3s.ts
Original file line number Diff line number Diff line change
Expand Up @@ -729,4 +729,48 @@ export = {

test.done();
},

'ALB - throws if desiredTaskCount is 0'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const cluster = new ecs.Cluster(stack, 'Cluster', { vpc });
cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') });

// THEN
test.throws(() =>
new ecsPatterns.ApplicationLoadBalancedEc2Service(stack, 'Service', {
cluster,
memoryLimitMiB: 1024,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry('test'),
},
desiredCount: 0,
})
, /You must specify a desiredCount greater than 0/);

test.done();
},

'NLB - throws if desiredTaskCount is 0'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const cluster = new ecs.Cluster(stack, 'Cluster', { vpc });
cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') });

// THEN
test.throws(() =>
new ecsPatterns.NetworkLoadBalancedEc2Service(stack, 'Service', {
cluster,
memoryLimitMiB: 1024,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry('test'),
},
desiredCount: 0,
})
, /You must specify a desiredCount greater than 0/);

test.done();
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,50 @@ export = {
}));

test.done();
}
},

'can set desiredTaskCount to 0'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const cluster = new ecs.Cluster(stack, 'Cluster', { vpc });
cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') });

// WHEN
new ecsPatterns.QueueProcessingEc2Service(stack, 'Service', {
cluster,
desiredTaskCount: 0,
maxScalingCapacity: 2,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test')
});

// THEN - QueueWorker is of EC2 launch type, an SQS queue is created and all default properties are set.
expect(stack).to(haveResource("AWS::ECS::Service", {
DesiredCount: 0,
LaunchType: "EC2",
}));

test.done();
},

'throws if desiredTaskCount and maxScalingCapacity are 0'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const cluster = new ecs.Cluster(stack, 'Cluster', { vpc });
cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') });

// THEN
test.throws(() =>
new ecsPatterns.QueueProcessingEc2Service(stack, 'Service', {
cluster,
desiredTaskCount: 0,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test')
})
, /maxScalingCapacity must be set and greater than 0 if desiredCount is 0/);

test.done();
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,29 @@ export = {

test.done();
},

"throws if desiredTaskCount is 0"(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 1 });
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
cluster.addCapacity('DefaultAutoScalingGroup', {
instanceType: new ec2.InstanceType('t2.micro')
});

// THEN
test.throws(() =>
new ScheduledEc2Task(stack, 'ScheduledEc2Task', {
cluster,
scheduledEc2TaskImageOptions: {
image: ecs.ContainerImage.fromRegistry('henk'),
memoryLimitMiB: 512,
},
schedule: events.Schedule.expression('rate(1 minute)'),
desiredTaskCount: 0,
}),
/You must specify a desiredTaskCount greater than 0/);

test.done();
},
};