-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7d91ebc
commit 9f0a6c0
Showing
3 changed files
with
249 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { Duration, RemovalPolicy, Stack } from 'aws-cdk-lib'; | ||
import { ISecurityGroup, IVpc } from 'aws-cdk-lib/aws-ec2'; | ||
import { | ||
LogDriver, | ||
Cluster, | ||
ContainerImage, | ||
FargateService, | ||
FargateTaskDefinition, | ||
} from 'aws-cdk-lib/aws-ecs'; | ||
import { Role } from 'aws-cdk-lib/aws-iam'; | ||
import { | ||
LogGroup, | ||
LogStream, | ||
RetentionDays, | ||
} from 'aws-cdk-lib/aws-logs'; | ||
import { DnsRecordType, PrivateDnsNamespace } from 'aws-cdk-lib/aws-servicediscovery'; | ||
import { Construct } from 'constructs'; | ||
|
||
|
||
export interface RedisProps { | ||
readonly cluster: Cluster; | ||
readonly vpc: IVpc; | ||
readonly cpu?: number; | ||
readonly memorySize?: number; | ||
readonly appSecurityGroup: ISecurityGroup; | ||
readonly image: ContainerImage; | ||
readonly useSpot?: boolean; | ||
readonly containerName: string; | ||
readonly taskRole: Role; | ||
readonly executionRole: Role; | ||
readonly family: string; | ||
readonly environmentVariables: { [key: string]: string }; | ||
readonly serviceDiscoveryNamespace: PrivateDnsNamespace; | ||
}; | ||
|
||
export class RedisService extends Construct { | ||
constructor(scope: Construct, id: string, props: RedisProps) { | ||
super(scope, id); | ||
|
||
const stackName = Stack.of(this).stackName; | ||
|
||
// define log group and logstream | ||
const logGroupName = `/ecs/${stackName}/${props.containerName}/`; | ||
const streamPrefix = props.containerName; | ||
|
||
// define log group and logstream | ||
const logGroup = new LogGroup(this, 'LogGroup', { | ||
logGroupName, | ||
retention: RetentionDays.ONE_DAY, | ||
removalPolicy: RemovalPolicy.DESTROY, | ||
}); | ||
|
||
new LogStream(this, 'LogStream', { | ||
logGroup, | ||
logStreamName: props.containerName, | ||
}); | ||
|
||
// task definition | ||
const taskDefinition = new FargateTaskDefinition(this, 'TaskDefinition', { | ||
cpu: props.cpu ?? 256, | ||
executionRole: props.executionRole, | ||
taskRole: props.taskRole, | ||
family: props.family, | ||
}); | ||
|
||
taskDefinition.addContainer(props.containerName, { | ||
image: props.image, | ||
containerName: props.containerName, | ||
environment: props.environmentVariables, | ||
essential: true, | ||
logging: LogDriver.awsLogs({ | ||
streamPrefix, | ||
logGroup, | ||
}), | ||
}); | ||
|
||
const useSpot = props.useSpot ?? false; | ||
|
||
|
||
// TODO: add service discovery service | ||
const cloudMapService = props.serviceDiscoveryNamespace.createService('Service', { | ||
name: `${stackName}-redis`, | ||
dnsRecordType: DnsRecordType.A, | ||
dnsTtl: Duration.seconds(30), | ||
healthCheck: { | ||
failureThreshold: 1, | ||
}, | ||
}); | ||
|
||
const fargateService = new FargateService(this, 'Service', { | ||
cluster: props.cluster, | ||
taskDefinition, | ||
assignPublicIp: true, | ||
capacityProviderStrategies: [ | ||
{ | ||
capacityProvider: 'FARGATE_SPOT', | ||
weight: useSpot ? 100 : 0, | ||
}, | ||
{ | ||
capacityProvider: 'FARGATE', | ||
weight: useSpot ? 0 : 100, | ||
}, | ||
], | ||
desiredCount: 1, | ||
enableExecuteCommand: true, | ||
securityGroups: [props.appSecurityGroup], | ||
serviceName: `${stackName}-${props.containerName}`, | ||
vpcSubnets: { | ||
subnets: props.vpc.privateSubnets, | ||
}, | ||
}); | ||
|
||
fargateService.associateCloudMapService({ service: cloudMapService }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { RemovalPolicy, Stack } from 'aws-cdk-lib'; | ||
import { ISecurityGroup, IVpc } from 'aws-cdk-lib/aws-ec2'; | ||
import { | ||
LogDriver, | ||
Cluster, | ||
ContainerImage, | ||
FargateService, | ||
FargateTaskDefinition, | ||
} from 'aws-cdk-lib/aws-ecs'; | ||
import { Role } from 'aws-cdk-lib/aws-iam'; | ||
import { | ||
LogGroup, | ||
LogStream, | ||
RetentionDays, | ||
} from 'aws-cdk-lib/aws-logs'; | ||
import { Construct } from 'constructs'; | ||
|
||
|
||
export interface WorkerProps { | ||
readonly cluster: Cluster; | ||
readonly vpc: IVpc; | ||
readonly cpu?: number; | ||
readonly memorySize?: number; | ||
readonly appSecurityGroup: ISecurityGroup; | ||
readonly image: ContainerImage; | ||
readonly command: string[]; | ||
readonly useSpot?: boolean; | ||
readonly containerName: string; | ||
readonly taskRole: Role; | ||
readonly executionRole: Role; | ||
readonly family: string; | ||
readonly environmentVariables: { [key: string]: string }; | ||
}; | ||
|
||
export class WorkerService extends Construct { | ||
constructor(scope: Construct, id: string, props: WorkerProps) { | ||
super(scope, id); | ||
|
||
const stackName = Stack.of(this).stackName; | ||
|
||
// define log group and logstream | ||
const logGroupName = `/ecs/${stackName}/${props.containerName}/`; | ||
const streamPrefix = props.containerName; | ||
|
||
// define log group and logstream | ||
const logGroup = new LogGroup(this, 'LogGroup', { | ||
logGroupName, | ||
retention: RetentionDays.ONE_DAY, | ||
removalPolicy: RemovalPolicy.DESTROY, | ||
}); | ||
|
||
new LogStream(this, 'LogStream', { | ||
logGroup, | ||
logStreamName: props.containerName, | ||
}); | ||
|
||
// task definition | ||
const taskDefinition = new FargateTaskDefinition(this, 'TaskDefinition', { | ||
cpu: props.cpu ?? 256, | ||
executionRole: props.executionRole, | ||
taskRole: props.taskRole, | ||
family: props.family, | ||
}); | ||
|
||
taskDefinition.addContainer(props.containerName, { | ||
image: props.image, | ||
command: props.command, | ||
containerName: props.containerName, | ||
environment: props.environmentVariables, | ||
essential: true, | ||
logging: LogDriver.awsLogs({ | ||
streamPrefix, | ||
logGroup, | ||
}), | ||
}); | ||
|
||
const useSpot = props.useSpot ?? false; | ||
|
||
// we don't need autoscaling in ad hoc environments | ||
// TODO: add prop to enable autoscaling for the worker | ||
// const service = | ||
new FargateService(this, 'Service', { | ||
cluster: props.cluster, | ||
taskDefinition, | ||
assignPublicIp: true, | ||
capacityProviderStrategies: [ | ||
{ | ||
capacityProvider: 'FARGATE_SPOT', | ||
weight: useSpot ? 100 : 0, | ||
}, | ||
{ | ||
capacityProvider: 'FARGATE', | ||
weight: useSpot ? 0 : 100, | ||
}, | ||
], | ||
desiredCount: 1, | ||
enableExecuteCommand: true, | ||
securityGroups: [props.appSecurityGroup], | ||
serviceName: `${stackName}-${props.containerName}`, | ||
vpcSubnets: { | ||
subnets: props.vpc.privateSubnets, | ||
}, | ||
}); | ||
} | ||
} |