Skip to content

Commit

Permalink
feat(aws-ecs-patterns): add circuitbreaker deployment configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
Dave Harmon committed Mar 9, 2021
1 parent 6c3d407 commit 50b477c
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 4 deletions.
26 changes: 25 additions & 1 deletion packages/@aws-cdk/aws-ecs-patterns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,30 @@ const queueProcessingFargateService = new QueueProcessingFargateService(stack, '
});
```

### Deployment circuit breaker and rollback

Amazon ECS [deployment circuit breaker](https://aws.amazon.com/tw/blogs/containers/announcing-amazon-ecs-deployment-circuit-breaker/)
automatically rolls back unhealthy service deployments without the need for manual intervention. Use `circuitBreaker` to enable
deployment circuit breaker and optionally enable `rollback` for automatic rollback. See [Using the deployment circuit breaker](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-type-ecs.html)
for more details.

```ts
const queueProcessingFargateService = new ecs.QueueProcessingFargateService(stack, 'Service', {
cluster,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
command: ["-c", "4", "amazon.com"],
enableLogging: false,
desiredTaskCount: 2,
environment: {},
queue,
maxScalingCapacity: 5,
maxHealthyPercent: 200,
minHealthPercent: 66,
circuitBreaker: { rollback: true },
});
```

### Set taskSubnets and securityGroups for QueueProcessingFargateService

```ts
Expand Down Expand Up @@ -469,7 +493,7 @@ const scheduledFargateTask = new ScheduledFargateTask(stack, 'ScheduledFargateTa

### Use the REMOVE_DEFAULT_DESIRED_COUNT feature flag

The REMOVE_DEFAULT_DESIRED_COUNT feature flag is used to override the default desiredCount that is autogenerated by the CDK. This will set the desiredCount of any service created by any of the following constructs to be undefined.
The REMOVE_DEFAULT_DESIRED_COUNT feature flag is used to override the default desiredCount that is autogenerated by the CDK. This will set the desiredCount of any service created by any of the following constructs to be undefined.

* ApplicationLoadBalancedEc2Service
* ApplicationLoadBalancedFargateService
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Certificate, CertificateValidation, ICertificate } from '@aws-cdk/aws-certificatemanager';
import { IVpc } from '@aws-cdk/aws-ec2';
import { AwsLogDriver, BaseService, CloudMapOptions, Cluster, ContainerImage, DeploymentController, ICluster, LogDriver, PropagatedTagSource, Secret } from '@aws-cdk/aws-ecs';
import { AwsLogDriver, BaseService, CloudMapOptions, Cluster, ContainerImage, DeploymentController, DeploymentCircuitBreaker, ICluster, LogDriver, PropagatedTagSource, Secret } from '@aws-cdk/aws-ecs';
import {
ApplicationListener, ApplicationLoadBalancer, ApplicationProtocol, ApplicationTargetGroup,
IApplicationLoadBalancer, ListenerCertificate, ListenerAction, AddApplicationTargetsProps,
Expand Down Expand Up @@ -226,6 +226,13 @@ export interface ApplicationLoadBalancedServiceBaseProps {
* @default - Rolling update (ECS)
*/
readonly deploymentController?: DeploymentController;

/**
* Whether to enable the deployment circuit breaker. If this property is defined, circuit breaker will be implicitly
* enabled.
* @default - disabled
*/
readonly circuitBreaker?: DeploymentCircuitBreaker;
}

export interface ApplicationLoadBalancedTaskImageOptions {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IVpc } from '@aws-cdk/aws-ec2';
import { AwsLogDriver, BaseService, CloudMapOptions, Cluster, ContainerImage, DeploymentController, ICluster, LogDriver, PropagatedTagSource, Secret } from '@aws-cdk/aws-ecs';
import { AwsLogDriver, BaseService, CloudMapOptions, Cluster, ContainerImage, DeploymentController, DeploymentCircuitBreaker, ICluster, LogDriver, PropagatedTagSource, Secret } from '@aws-cdk/aws-ecs';
import { INetworkLoadBalancer, NetworkListener, NetworkLoadBalancer, NetworkTargetGroup } from '@aws-cdk/aws-elasticloadbalancingv2';
import { IRole } from '@aws-cdk/aws-iam';
import { ARecord, CnameRecord, IHostedZone, RecordTarget } from '@aws-cdk/aws-route53';
Expand Down Expand Up @@ -176,6 +176,13 @@ export interface NetworkLoadBalancedServiceBaseProps {
* @default - Rolling update (ECS)
*/
readonly deploymentController?: DeploymentController;

/**
* Whether to enable the deployment circuit breaker. If this property is defined, circuit breaker will be implicitly
* enabled.
* @default - disabled
*/
readonly circuitBreaker?: DeploymentCircuitBreaker;
}

export interface NetworkLoadBalancedTaskImageOptions {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ScalingInterval } from '@aws-cdk/aws-applicationautoscaling';
import { IVpc } from '@aws-cdk/aws-ec2';
import { AwsLogDriver, BaseService, Cluster, ContainerImage, DeploymentController, ICluster, LogDriver, PropagatedTagSource, Secret } from '@aws-cdk/aws-ecs';
import { AwsLogDriver, BaseService, Cluster, ContainerImage, DeploymentController, DeploymentCircuitBreaker, ICluster, LogDriver, PropagatedTagSource, Secret } from '@aws-cdk/aws-ecs';
import { IQueue, Queue } from '@aws-cdk/aws-sqs';
import { CfnOutput, Duration, Stack } from '@aws-cdk/core';
import * as cxapi from '@aws-cdk/cx-api';
Expand Down Expand Up @@ -189,6 +189,13 @@ export interface QueueProcessingServiceBaseProps {
* @default - Rolling update (ECS)
*/
readonly deploymentController?: DeploymentController;

/**
* Whether to enable the deployment circuit breaker. If this property is defined, circuit breaker will be implicitly
* enabled.
* @default - disabled
*/
readonly circuitBreaker?: DeploymentCircuitBreaker;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export class ApplicationLoadBalancedEc2Service extends ApplicationLoadBalancedSe
enableECSManagedTags: props.enableECSManagedTags,
cloudMapOptions: props.cloudMapOptions,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
});
this.addServiceAsTarget(this.service);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export class NetworkLoadBalancedEc2Service extends NetworkLoadBalancedServiceBas
enableECSManagedTags: props.enableECSManagedTags,
cloudMapOptions: props.cloudMapOptions,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
});
this.addServiceAsTarget(this.service);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export class QueueProcessingEc2Service extends QueueProcessingServiceBase {
propagateTags: props.propagateTags,
enableECSManagedTags: props.enableECSManagedTags,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
});

this.configureAutoscalingForService(this.service);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export class ApplicationLoadBalancedFargateService extends ApplicationLoadBalanc
cloudMapOptions: props.cloudMapOptions,
platformVersion: props.platformVersion,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
securityGroups: props.securityGroups,
vpcSubnets: props.taskSubnets,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export class NetworkLoadBalancedFargateService extends NetworkLoadBalancedServic
cloudMapOptions: props.cloudMapOptions,
platformVersion: props.platformVersion,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
vpcSubnets: props.taskSubnets,
});
this.addServiceAsTarget(this.service);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export class QueueProcessingFargateService extends QueueProcessingServiceBase {
enableECSManagedTags: props.enableECSManagedTags,
platformVersion: props.platformVersion,
deploymentController: props.deploymentController,
circuitBreaker: props.circuitBreaker,
securityGroups: props.securityGroups,
vpcSubnets: props.taskSubnets,
assignPublicIp: props.assignPublicIp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,19 @@ export = {
deploymentController: {
type: ecs.DeploymentControllerType.CODE_DEPLOY,
},
circuitBreaker: {
rollback: true,
},
});

// THEN - QueueWorker is of EC2 launch type, an SQS queue is created and all optional properties are set.
expect(stack).to(haveResource('AWS::ECS::Service', {
DesiredCount: 2,
DeploymentConfiguration: {
DeploymentCircuitBreaker: {
Enable: true,
Rollback: true,
},
MinimumHealthyPercent: 60,
MaximumPercent: 150,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,19 @@ export = {
deploymentController: {
type: ecs.DeploymentControllerType.CODE_DEPLOY,
},
circuitBreaker: {
rollback: true,
},
});

// THEN - QueueWorker is of FARGATE launch type, an SQS queue is created and all optional properties are set.
expect(stack).to(haveResource('AWS::ECS::Service', {
DesiredCount: 2,
DeploymentConfiguration: {
DeploymentCircuitBreaker: {
Enable: true,
Rollback: true,
},
MinimumHealthyPercent: 60,
MaximumPercent: 150,
},
Expand Down

0 comments on commit 50b477c

Please sign in to comment.