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(aws-ecs): refactor high level aws-ecs constructs into the aws-ecs-patterns module #2623

Merged
merged 3 commits into from
May 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions packages/@aws-cdk/aws-ecs-patterns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,82 @@

This library provides higher-level ECS constructs which follow common architectural patterns. It contains:

* Load Balanced Services
* Queue Worker Services
* Scheduled Tasks (cron jobs)

## Load Balanced Services

To define a service that is behind a load balancer, instantiate one of the following:

* `LoadBalancedEc2Service`

```ts
const loadBalancedEcsService = new ecsPatterns.LoadBalancedEc2Service(stack, 'Service', {
cluster,
memoryLimitMiB: 1024,
image: ecs.ContainerImage.fromRegistry('test'),
desiredCount: 2,
environment: {
TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value",
TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value"
}
});
```

* `LoadBalancedFargateService`

```ts
const loadBalancedFargateService = new ecsPatterns.LoadBalancedFargateService(stack, 'Service', {
cluster,
memoryMiB: '1GB',
cpu: '512',
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
});
```

## Queue Worker Services

To define a service that creates a queue and reads from that queue, instantiate one of the following:

* `Ec2QueueWorkerService`

```ts
const ecsQueueWorkerService = new Ec2QueueWorkerService(stack, 'Service', {
cluster,
memoryLimitMiB: 1024,
image: ecs.ContainerImage.fromRegistry('test'),
command: ["-c", "4", "amazon.com"],
enableLogging: false,
desiredTaskCount: 2,
environment: {
TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value",
TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value"
},
queue,
maxScalingCapacity: 5
});
```

* `FargateQueueWorkerService`

```ts
const fargateQueueWorkerService = new FargateQueueWorkerService(stack, 'Service', {
cluster,
memoryMiB: '512',
image: ecs.ContainerImage.fromRegistry('test'),
command: ["-c", "4", "amazon.com"],
enableLogging: false,
desiredTaskCount: 2,
environment: {
TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value",
TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value"
},
queue,
maxScalingCapacity: 5
});
```

## Scheduled Tasks

To define a task that runs periodically, instantiate an `ScheduledEc2Task`:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { ICertificate } from '@aws-cdk/aws-certificatemanager';
import ecs = require('@aws-cdk/aws-ecs');
import elbv2 = require('@aws-cdk/aws-elasticloadbalancingv2');
import cdk = require('@aws-cdk/cdk');
import { BaseService } from './base/base-service';
import { ICluster } from './cluster';
import { ContainerImage } from './container-image';

export enum LoadBalancerType {
Application,
Expand All @@ -14,12 +12,12 @@ export interface LoadBalancedServiceBaseProps {
/**
* The cluster where your service will be deployed
*/
readonly cluster: ICluster;
readonly cluster: ecs.ICluster;

/**
* The image to start.
*/
readonly image: ContainerImage;
readonly image: ecs.ContainerImage;

/**
* The container port of the application load balancer attached to your Fargate service. Corresponds to container port mapping.
Expand Down Expand Up @@ -127,7 +125,7 @@ export abstract class LoadBalancedServiceBase extends cdk.Construct {
new cdk.CfnOutput(this, 'LoadBalancerDNS', { value: this.loadBalancer.loadBalancerDnsName });
}

protected addServiceAsTarget(service: BaseService) {
protected addServiceAsTarget(service: ecs.BaseService) {
if (this.loadBalancerType === LoadBalancerType.Application) {
(this.targetGroup as elbv2.ApplicationTargetGroup).addTarget(service);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import autoscaling = require('@aws-cdk/aws-applicationautoscaling');
import ecs = require('@aws-cdk/aws-ecs');
import sqs = require('@aws-cdk/aws-sqs');
import { IQueue } from '@aws-cdk/aws-sqs';
import cdk = require('@aws-cdk/cdk');
import { BaseService } from './base/base-service';
import { ICluster } from './cluster';
import { ContainerImage } from './container-image';
import { AwsLogDriver } from './log-drivers/aws-log-driver';
import { LogDriver } from './log-drivers/log-driver';

/**
* Properties to define a Query Worker service
Expand All @@ -15,12 +10,12 @@ export interface QueueWorkerServiceBaseProps {
/**
* Cluster where service will be deployed
*/
readonly cluster: ICluster;
readonly cluster: ecs.ICluster;

/**
* The image to start.
*/
readonly image: ContainerImage;
readonly image: ecs.ContainerImage;

/**
* The CMD value to pass to the container. A string with commands delimited by commas.
Expand Down Expand Up @@ -58,7 +53,7 @@ export interface QueueWorkerServiceBaseProps {
*
* @default 'SQSQueue with CloudFormation-generated name'
*/
readonly queue?: IQueue;
readonly queue?: sqs.IQueue;

/**
* Maximum capacity to scale to.
Expand All @@ -85,7 +80,7 @@ export abstract class QueueWorkerServiceBase extends cdk.Construct {
/**
* The SQS queue that the worker service will process from
*/
public readonly sqsQueue: IQueue;
public readonly sqsQueue: sqs.IQueue;

// Properties that have defaults defined. The Queue Worker will handle assigning undefined properties with default
// values so that derived classes do not need to maintain the same logic.
Expand All @@ -109,7 +104,7 @@ export abstract class QueueWorkerServiceBase extends cdk.Construct {
/**
* The AwsLogDriver to use for logging if logging is enabled.
*/
public readonly logDriver?: LogDriver;
public readonly logDriver?: ecs.LogDriver;

constructor(scope: cdk.Construct, id: string, props: QueueWorkerServiceBaseProps) {
super(scope, id);
Expand Down Expand Up @@ -141,7 +136,7 @@ export abstract class QueueWorkerServiceBase extends cdk.Construct {
*
* @param service the ECS/Fargate service for which to apply the autoscaling rules to
*/
protected configureAutoscalingForService(service: BaseService) {
protected configureAutoscalingForService(service: ecs.BaseService) {
const scalingTarget = service.autoScaleTaskCount({ maxCapacity: this.maxCapacity, minCapacity: this.desiredCount });
scalingTarget.scaleOnCpuUtilization('CpuScaling', {
targetUtilizationPercent: 50,
Expand All @@ -157,7 +152,7 @@ export abstract class QueueWorkerServiceBase extends cdk.Construct {
*
* @param prefix the Cloudwatch logging prefix
*/
private createAwsLogDriver(prefix: string): AwsLogDriver {
return new AwsLogDriver(this, 'QueueWorkerLogging', { streamPrefix: prefix });
private createAwsLogDriver(prefix: string): ecs.AwsLogDriver {
return new ecs.AwsLogDriver(this, 'QueueWorkerLogging', { streamPrefix: prefix });
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ecs = require('@aws-cdk/aws-ecs');
import cdk = require('@aws-cdk/cdk');
import { Ec2Service } from './ec2/ec2-service';
import { Ec2TaskDefinition } from './ec2/ec2-task-definition';
import { QueueWorkerServiceBase, QueueWorkerServiceBaseProps } from './queue-worker-service-base';
import { QueueWorkerServiceBase, QueueWorkerServiceBaseProps } from '../base/queue-worker-service-base';

/**
* Properties to define an Ec2 query worker service
Expand Down Expand Up @@ -49,7 +48,7 @@ export class Ec2QueueWorkerService extends QueueWorkerServiceBase {
super(scope, id, props);

// Create a Task Definition for the container to start
const taskDefinition = new Ec2TaskDefinition(this, 'QueueWorkerTaskDef');
const taskDefinition = new ecs.Ec2TaskDefinition(this, 'QueueWorkerTaskDef');
taskDefinition.addContainer('QueueWorkerContainer', {
image: props.image,
memoryLimitMiB: props.memoryLimitMiB,
Expand All @@ -62,7 +61,7 @@ export class Ec2QueueWorkerService extends QueueWorkerServiceBase {

// Create an ECS service with the previously defined Task Definition and configure
// autoscaling based on cpu utilization and number of messages visible in the SQS queue.
const ecsService = new Ec2Service(this, 'QueueWorkerService', {
const ecsService = new ecs.Ec2Service(this, 'QueueWorkerService', {
cluster: props.cluster,
desiredCount: this.desiredCount,
taskDefinition
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ecs = require('@aws-cdk/aws-ecs');
import cdk = require('@aws-cdk/cdk');
import { Ec2Service } from './ec2/ec2-service';
import { Ec2TaskDefinition } from './ec2/ec2-task-definition';
import { LoadBalancedServiceBase, LoadBalancedServiceBaseProps } from './load-balanced-service-base';
import { LoadBalancedServiceBase, LoadBalancedServiceBaseProps } from '../base/load-balanced-service-base';

/**
* Properties for a LoadBalancedEc2Service
Expand Down Expand Up @@ -42,12 +41,12 @@ export class LoadBalancedEc2Service extends LoadBalancedServiceBase {
/**
* The ECS service in this construct
*/
public readonly service: Ec2Service;
public readonly service: ecs.Ec2Service;

constructor(scope: cdk.Construct, id: string, props: LoadBalancedEc2ServiceProps) {
super(scope, id, props);

const taskDefinition = new Ec2TaskDefinition(this, 'TaskDef', {});
const taskDefinition = new ecs.Ec2TaskDefinition(this, 'TaskDef', {});

const container = taskDefinition.addContainer('web', {
image: props.image,
Expand All @@ -60,7 +59,7 @@ export class LoadBalancedEc2Service extends LoadBalancedServiceBase {
containerPort: props.containerPort || 80
});

const service = new Ec2Service(this, "Service", {
const service = new ecs.Ec2Service(this, "Service", {
cluster: props.cluster,
desiredCount: props.desiredCount || 1,
taskDefinition
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ecs = require('@aws-cdk/aws-ecs');
import cdk = require('@aws-cdk/cdk');
import { FargateService } from './fargate/fargate-service';
import { FargateTaskDefinition } from './fargate/fargate-task-definition';
import { QueueWorkerServiceBase, QueueWorkerServiceBaseProps } from './queue-worker-service-base';
import { QueueWorkerServiceBase, QueueWorkerServiceBaseProps } from '../base/queue-worker-service-base';

/**
* Properties to define a Fargate queue worker service
Expand Down Expand Up @@ -53,7 +52,7 @@ export class FargateQueueWorkerService extends QueueWorkerServiceBase {
super(scope, id, props);

// Create a Task Definition for the container to start
const taskDefinition = new FargateTaskDefinition(this, 'QueueWorkerTaskDef', {
const taskDefinition = new ecs.FargateTaskDefinition(this, 'QueueWorkerTaskDef', {
memoryMiB: props.memoryMiB !== undefined ? props.memoryMiB : '512',
cpu: props.cpu !== undefined ? props.cpu : '256',
});
Expand All @@ -66,7 +65,7 @@ export class FargateQueueWorkerService extends QueueWorkerServiceBase {

// Create a Fargate service with the previously defined Task Definition and configure
// autoscaling based on cpu utilization and number of messages visible in the SQS queue.
const fargateService = new FargateService(this, 'FargateQueueWorkerService', {
const fargateService = new ecs.FargateService(this, 'FargateQueueWorkerService', {
cluster: props.cluster,
desiredCount: this.desiredCount,
taskDefinition
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Certificate } from '@aws-cdk/aws-certificatemanager';
import { Vpc } from '@aws-cdk/aws-ec2';
import { Cluster, ContainerImage } from '@aws-cdk/aws-ecs';
import { HostedZoneProvider } from '@aws-cdk/aws-route53';
import cdk = require('@aws-cdk/cdk');
import { Cluster } from './cluster';
import { ContainerImage } from './container-image';
import { LoadBalancedFargateService } from './load-balanced-fargate-service';

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import ecs = require('@aws-cdk/aws-ecs');
import { AliasRecord, IHostedZone } from '@aws-cdk/aws-route53';
import targets = require('@aws-cdk/aws-route53-targets');
import cdk = require('@aws-cdk/cdk');
import { FargateService } from './fargate/fargate-service';
import { FargateTaskDefinition } from './fargate/fargate-task-definition';
import { LoadBalancedServiceBase, LoadBalancedServiceBaseProps } from './load-balanced-service-base';
import { AwsLogDriver } from './log-drivers/aws-log-driver';
import { LoadBalancedServiceBase, LoadBalancedServiceBaseProps } from '../base/load-balanced-service-base';

/**
* Properties for a LoadBalancedEcsService
Expand Down Expand Up @@ -84,12 +82,12 @@ export class LoadBalancedFargateService extends LoadBalancedServiceBase {
/**
* The Fargate service in this construct
*/
public readonly service: FargateService;
public readonly service: ecs.FargateService;

constructor(scope: cdk.Construct, id: string, props: LoadBalancedFargateServiceProps) {
super(scope, id, props);

const taskDefinition = new FargateTaskDefinition(this, 'TaskDef', {
const taskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDef', {
memoryMiB: props.memoryMiB,
cpu: props.cpu
});
Expand All @@ -107,7 +105,7 @@ export class LoadBalancedFargateService extends LoadBalancedServiceBase {
});

const assignPublicIp = props.publicTasks !== undefined ? props.publicTasks : false;
const service = new FargateService(this, "Service", {
const service = new ecs.FargateService(this, "Service", {
cluster: props.cluster,
desiredCount: props.desiredCount || 1,
taskDefinition,
Expand All @@ -130,7 +128,7 @@ export class LoadBalancedFargateService extends LoadBalancedServiceBase {
}
}

private createAWSLogDriver(prefix: string): AwsLogDriver {
return new AwsLogDriver(this, 'Logging', { streamPrefix: prefix });
private createAWSLogDriver(prefix: string): ecs.AwsLogDriver {
return new ecs.AwsLogDriver(this, 'Logging', { streamPrefix: prefix });
}
}
12 changes: 10 additions & 2 deletions packages/@aws-cdk/aws-ecs-patterns/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
// AWS::ECS-PATTERNS CloudFormation Resources:
export * from './scheduled-ecs-task';
export * from './ecs/ecs-queue-worker-service';
export * from './fargate/fargate-queue-worker-service';
export * from './base/queue-worker-service-base';

export * from './ecs/load-balanced-ecs-service';
export * from './fargate/load-balanced-fargate-service';
export * from './fargate/load-balanced-fargate-service-applet';
export * from './base/load-balanced-service-base';

export * from './ecs/scheduled-ecs-task';
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-ecs-patterns/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,32 @@
"pkglint": "^0.32.0"
},
"dependencies": {
"@aws-cdk/aws-applicationautoscaling": "^0.32.0",
"@aws-cdk/aws-certificatemanager": "^0.32.0",
"@aws-cdk/aws-ec2": "^0.32.0",
"@aws-cdk/aws-ecs": "^0.32.0",
"@aws-cdk/aws-elasticloadbalancingv2": "^0.32.0",
"@aws-cdk/aws-events": "^0.32.0",
"@aws-cdk/aws-events-targets": "^0.32.0",
"@aws-cdk/aws-iam": "^0.32.0",
"@aws-cdk/aws-route53": "^0.32.0",
"@aws-cdk/aws-route53-targets": "^0.32.0",
"@aws-cdk/aws-sqs": "^0.32.0",
"@aws-cdk/cdk": "^0.32.0"
},
"homepage": "https://github.com/awslabs/aws-cdk",
"peerDependencies": {
"@aws-cdk/aws-applicationautoscaling": "^0.32.0",
"@aws-cdk/aws-certificatemanager": "^0.32.0",
"@aws-cdk/aws-ec2": "^0.32.0",
"@aws-cdk/aws-ecs": "^0.32.0",
"@aws-cdk/aws-elasticloadbalancingv2": "^0.32.0",
"@aws-cdk/aws-events": "^0.32.0",
"@aws-cdk/aws-events-targets": "^0.32.0",
"@aws-cdk/aws-iam": "^0.32.0",
"@aws-cdk/aws-route53": "^0.32.0",
"@aws-cdk/aws-route53-targets": "^0.32.0",
"@aws-cdk/aws-sqs": "^0.32.0",
"@aws-cdk/cdk": "^0.32.0"
},
"engines": {
Expand Down
5 changes: 5 additions & 0 deletions packages/@aws-cdk/aws-ecs-patterns/test/demo-image/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM python:3.6
EXPOSE 8000
WORKDIR /src
ADD . /src
CMD python3 index.py
Loading