Skip to content

Commit

Permalink
feat(ecs-patterns): add taskDefinition props to
Browse files Browse the repository at this point in the history
QueueProcessingEc2Service
  • Loading branch information
badmintoncryer committed Dec 9, 2023
1 parent d1ad5ae commit 8e5c88c
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import { QueueProcessingServiceBase, QueueProcessingServiceBaseProps } from '../
* The properties for the QueueProcessingEc2Service service.
*/
export interface QueueProcessingEc2ServiceProps extends QueueProcessingServiceBaseProps {
/**
* The task definition to use for tasks in the service. TaskDefinition or Image must be specified, but not both..
*
* @default - none
*/
readonly taskDefinition?: Ec2TaskDefinition;

/**
* The number of cpu units used by the task.
*
Expand Down Expand Up @@ -106,23 +113,31 @@ export class QueueProcessingEc2Service extends QueueProcessingServiceBase {
constructor(scope: Construct, id: string, props: QueueProcessingEc2ServiceProps) {
super(scope, id, props);

const containerName = props.containerName ?? 'QueueProcessingContainer';
if (props.taskDefinition != null && props.image != null) {
throw new Error('You must specify only one of TaskDefinition or Image');
} else if (props.taskDefinition != null) {
this.taskDefinition = props.taskDefinition;
} else if (props.image != null) {
// Create a Task Definition for the container to start
this.taskDefinition = new Ec2TaskDefinition(this, 'QueueProcessingTaskDef', {
family: props.family,
});

// Create a Task Definition for the container to start
this.taskDefinition = new Ec2TaskDefinition(this, 'QueueProcessingTaskDef', {
family: props.family,
});
this.taskDefinition.addContainer(containerName, {
image: props.image,
memoryLimitMiB: props.memoryLimitMiB,
memoryReservationMiB: props.memoryReservationMiB,
cpu: props.cpu,
gpuCount: props.gpuCount,
command: props.command,
environment: this.environment,
secrets: this.secrets,
logging: this.logDriver,
});
const containerName = props.containerName ?? 'QueueProcessingContainer';
this.taskDefinition.addContainer(containerName, {
image: props.image,
memoryLimitMiB: props.memoryLimitMiB,
memoryReservationMiB: props.memoryReservationMiB,
cpu: props.cpu,
gpuCount: props.gpuCount,
command: props.command,
environment: this.environment,
secrets: this.secrets,
logging: this.logDriver,
});
} else {
throw new Error('You must specify one of: taskDefinition or image');
}

// The desiredCount should be removed from the fargate service when the feature flag is removed.
const desiredCount = FeatureFlags.of(this).isEnabled(cxapi.ECS_REMOVE_DEFAULT_DESIRED_COUNT) ? undefined : this.desiredCount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,3 +568,51 @@ it('throws validation errors of the specific queue prop, when setting queue and
});
}).toThrow(new Error('visibilityTimeout can be set only when queue is not set. Specify them in the QueueProps of the queue'));
});

test('test ECS queue worker service construct - with task definition', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const cluster = new ecs.Cluster(stack, 'Cluster', { vpc });
cluster.addAsgCapacityProvider(new AsgCapacityProvider(stack, 'DefaultAutoScalingGroupProvider', {
autoScalingGroup: new AutoScalingGroup(stack, 'DefaultAutoScalingGroup', {
vpc,
instanceType: new ec2.InstanceType('t2.micro'),
machineImage: MachineImage.latestAmazonLinux(),
}),
}));

// WHEN
const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef', {
family: 'MyTaskDefinitionFamily',
});

taskDefinition.addContainer('TheContainer', {
image: ecs.ContainerImage.fromRegistry('test'),
memoryLimitMiB: 1024,
logging: new ecs.AwsLogDriver({ streamPrefix: 'QueueProcessingFargateService' }),
});

new ecsPatterns.QueueProcessingEc2Service(stack, 'Service', {
cluster,
taskDefinition,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', {
ContainerDefinitions: [
Match.objectLike({
Essential: true,
Image: 'test',
LogConfiguration: {},
Memory: 1024,
Name: 'TheContainer',
}),
],
ExecutionRoleArn: { 'Fn::GetAtt': ['TaskDefExecutionRoleB4775C97', 'Arn'] },
Family: 'MyTaskDefinitionFamily',
NetworkMode: 'bridge',
RequiresCompatibilities: ['EC2'],
TaskRoleArn: { 'Fn::GetAtt': ['TaskDefTaskRole1EDB4A67', 'Arn'] },
});
});

0 comments on commit 8e5c88c

Please sign in to comment.