Skip to content

Commit

Permalink
feat(ecs-patterns): PlacementStrategy and PlacementConstraint for man…
Browse files Browse the repository at this point in the history
…y patterns (aws#19612)

I've added PlacementStrategy and PlacementConstraint to 
- ApplicationLoadBalancedEc2Service
- ApplicationMultipleTargetGroupsEc2Service
- NetworkLoadBalancedEc2Service
- NetworkMultipleTargetGroupsEc2Service
- QueueProcessingEc2Service

and pass it to AWS ECS related service.

fixes aws#19225

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)?
	* [ ] Did you use `cdk-integ` to deploy the infrastructure and generate the snapshot (i.e. `cdk-integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
IhnatKlimchuk authored and Stephen Potter committed Apr 27, 2022
1 parent 49b378a commit 72a9b75
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ec2Service, Ec2TaskDefinition } from '@aws-cdk/aws-ecs';
import { Ec2Service, Ec2TaskDefinition, PlacementConstraint, PlacementStrategy } from '@aws-cdk/aws-ecs';
import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { ApplicationLoadBalancedServiceBase, ApplicationLoadBalancedServiceBaseProps } from '../base/application-load-balanced-service-base';
Expand Down Expand Up @@ -63,6 +63,22 @@ export interface ApplicationLoadBalancedEc2ServiceProps extends ApplicationLoadB
* @default - No memory reserved.
*/
readonly memoryReservationMiB?: number;

/**
* The placement constraints to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Constraints](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html).
*
* @default - No constraints.
*/
readonly placementConstraints?: PlacementConstraint[];

/**
* The placement strategies to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Strategies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html).
*
* @default - No strategies.
*/
readonly placementStrategies?: PlacementStrategy[];
}

/**
Expand Down Expand Up @@ -135,6 +151,8 @@ export class ApplicationLoadBalancedEc2Service extends ApplicationLoadBalancedSe
cloudMapOptions: props.cloudMapOptions,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
placementConstraints: props.placementConstraints,
placementStrategies: props.placementStrategies,
});
this.addServiceAsTarget(this.service);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ec2Service, Ec2TaskDefinition } from '@aws-cdk/aws-ecs';
import { Ec2Service, Ec2TaskDefinition, PlacementConstraint, PlacementStrategy } from '@aws-cdk/aws-ecs';
import { ApplicationTargetGroup } from '@aws-cdk/aws-elasticloadbalancingv2';
import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
Expand Down Expand Up @@ -58,6 +58,22 @@ export interface ApplicationMultipleTargetGroupsEc2ServiceProps extends Applicat
* @default - No memory reserved.
*/
readonly memoryReservationMiB?: number;

/**
* The placement constraints to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Constraints](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html).
*
* @default - No constraints.
*/
readonly placementConstraints?: PlacementConstraint[];

/**
* The placement strategies to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Strategies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html).
*
* @default - No strategies.
*/
readonly placementStrategies?: PlacementStrategy[];
}

/**
Expand Down Expand Up @@ -150,6 +166,8 @@ export class ApplicationMultipleTargetGroupsEc2Service extends ApplicationMultip
propagateTags: props.propagateTags,
enableECSManagedTags: props.enableECSManagedTags,
cloudMapOptions: props.cloudMapOptions,
placementConstraints: props.placementConstraints,
placementStrategies: props.placementStrategies,
});
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ec2Service, Ec2TaskDefinition } from '@aws-cdk/aws-ecs';
import { Ec2Service, Ec2TaskDefinition, PlacementConstraint, PlacementStrategy } from '@aws-cdk/aws-ecs';
import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { NetworkLoadBalancedServiceBase, NetworkLoadBalancedServiceBaseProps } from '../base/network-load-balanced-service-base';
Expand Down Expand Up @@ -61,6 +61,22 @@ export interface NetworkLoadBalancedEc2ServiceProps extends NetworkLoadBalancedS
* @default - No memory reserved.
*/
readonly memoryReservationMiB?: number;

/**
* The placement constraints to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Constraints](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html).
*
* @default - No constraints.
*/
readonly placementConstraints?: PlacementConstraint[];

/**
* The placement strategies to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Strategies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html).
*
* @default - No strategies.
*/
readonly placementStrategies?: PlacementStrategy[];
}

/**
Expand Down Expand Up @@ -133,6 +149,8 @@ export class NetworkLoadBalancedEc2Service extends NetworkLoadBalancedServiceBas
cloudMapOptions: props.cloudMapOptions,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
placementConstraints: props.placementConstraints,
placementStrategies: props.placementStrategies,
});
this.addServiceAsTarget(this.service);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ec2Service, Ec2TaskDefinition } from '@aws-cdk/aws-ecs';
import { Ec2Service, Ec2TaskDefinition, PlacementConstraint, PlacementStrategy } from '@aws-cdk/aws-ecs';
import { NetworkTargetGroup } from '@aws-cdk/aws-elasticloadbalancingv2';
import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
Expand Down Expand Up @@ -57,6 +57,22 @@ export interface NetworkMultipleTargetGroupsEc2ServiceProps extends NetworkMulti
* @default - No memory reserved.
*/
readonly memoryReservationMiB?: number;

/**
* The placement constraints to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Constraints](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html).
*
* @default - No constraints.
*/
readonly placementConstraints?: PlacementConstraint[];

/**
* The placement strategies to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Strategies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html).
*
* @default - No strategies.
*/
readonly placementStrategies?: PlacementStrategy[];
}

/**
Expand Down Expand Up @@ -150,6 +166,8 @@ export class NetworkMultipleTargetGroupsEc2Service extends NetworkMultipleTarget
propagateTags: props.propagateTags,
enableECSManagedTags: props.enableECSManagedTags,
cloudMapOptions: props.cloudMapOptions,
placementConstraints: props.placementConstraints,
placementStrategies: props.placementStrategies,
});
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ec2Service, Ec2TaskDefinition } from '@aws-cdk/aws-ecs';
import { Ec2Service, Ec2TaskDefinition, PlacementConstraint, PlacementStrategy } from '@aws-cdk/aws-ecs';
import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { QueueProcessingServiceBase, QueueProcessingServiceBaseProps } from '../base/queue-processing-service-base';
Expand Down Expand Up @@ -67,6 +67,22 @@ export interface QueueProcessingEc2ServiceProps extends QueueProcessingServiceBa
* @default - QueueProcessingContainer
*/
readonly containerName?: string;

/**
* The placement constraints to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Constraints](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html).
*
* @default - No constraints.
*/
readonly placementConstraints?: PlacementConstraint[];

/**
* The placement strategies to use for tasks in the service. For more information, see
* [Amazon ECS Task Placement Strategies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html).
*
* @default - No strategies.
*/
readonly placementStrategies?: PlacementStrategy[];
}

/**
Expand Down Expand Up @@ -124,6 +140,8 @@ export class QueueProcessingEc2Service extends QueueProcessingServiceBase {
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
capacityProviderStrategies: props.capacityProviderStrategies,
placementConstraints: props.placementConstraints,
placementStrategies: props.placementStrategies,
});

this.configureAutoscalingForService(this.service);
Expand Down
10 changes: 10 additions & 0 deletions packages/@aws-cdk/aws-ecs-patterns/test/ec2/l3s-v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
Ec2TaskDefinition,
PropagatedTagSource,
Protocol,
PlacementStrategy,
PlacementConstraint,
} from '@aws-cdk/aws-ecs';
import { ApplicationProtocol, SslPolicy } from '@aws-cdk/aws-elasticloadbalancingv2';
import { CompositePrincipal, Role, ServicePrincipal } from '@aws-cdk/aws-iam';
Expand Down Expand Up @@ -163,6 +165,8 @@ describe('When Application Load Balancer', () => {
protocol: Protocol.TCP,
},
],
placementStrategies: [PlacementStrategy.spreadAcrossInstances(), PlacementStrategy.packedByCpu(), PlacementStrategy.randomly()],
placementConstraints: [PlacementConstraint.memberOf('attribute:ecs.instance-type =~ m5a.*')],
});

// THEN
Expand All @@ -189,6 +193,8 @@ describe('When Application Load Balancer', () => {
],
PropagateTags: 'SERVICE',
ServiceName: 'myService',
PlacementConstraints: [{ Type: 'memberOf', Expression: 'attribute:ecs.instance-type =~ m5a.*' }],
PlacementStrategies: [{ Field: 'instanceId', Type: 'spread' }, { Field: 'cpu', Type: 'binpack' }, { Type: 'random' }],
});

Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', {
Expand Down Expand Up @@ -1042,6 +1048,8 @@ describe('When Network Load Balancer', () => {
listener: 'listener2',
},
],
placementStrategies: [PlacementStrategy.spreadAcrossInstances(), PlacementStrategy.packedByCpu(), PlacementStrategy.randomly()],
placementConstraints: [PlacementConstraint.memberOf('attribute:ecs.instance-type =~ m5a.*')],
});

// THEN
Expand Down Expand Up @@ -1069,6 +1077,8 @@ describe('When Network Load Balancer', () => {
PropagateTags: 'SERVICE',
SchedulingStrategy: 'REPLICA',
ServiceName: 'myService',
PlacementConstraints: [{ Type: 'memberOf', Expression: 'attribute:ecs.instance-type =~ m5a.*' }],
PlacementStrategies: [{ Field: 'instanceId', Type: 'spread' }, { Field: 'cpu', Type: 'binpack' }, { Type: 'random' }],
});

Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ testDeprecated('test ECS queue worker service construct - with optional props',
family: 'ecs-task-family',
circuitBreaker: { rollback: true },
gpuCount: 256,
placementStrategies: [ecs.PlacementStrategy.spreadAcrossInstances(), ecs.PlacementStrategy.packedByCpu(), ecs.PlacementStrategy.randomly()],
placementConstraints: [ecs.PlacementConstraint.memberOf('attribute:ecs.instance-type =~ m5a.*')],
});

// THEN - QueueWorker is of EC2 launch type, an SQS queue is created and all optional properties are set.
Expand All @@ -252,6 +254,8 @@ testDeprecated('test ECS queue worker service construct - with optional props',
DeploymentController: {
Type: 'ECS',
},
PlacementConstraints: [{ Type: 'memberOf', Expression: 'attribute:ecs.instance-type =~ m5a.*' }],
PlacementStrategies: [{ Field: 'instanceId', Type: 'spread' }, { Field: 'cpu', Type: 'binpack' }, { Type: 'random' }],
});

Template.fromStack(stack).hasResourceProperties('AWS::SQS::Queue', {
Expand Down

0 comments on commit 72a9b75

Please sign in to comment.