Skip to content

Commit

Permalink
feat(context): added context for both ad hoc base and app constructs,…
Browse files Browse the repository at this point in the history
… clean up and refactor app constructs
  • Loading branch information
briancaffey committed Jan 5, 2023
1 parent 1157326 commit 6c40d08
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 954 deletions.
29 changes: 24 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
## ad hoc base cdk commands
ad-hoc-base-synth:
cdk synth --app='lib/examples/ad-hoc/base/index.js' -e TestAdHocBaseStack
cdk synth --app='lib/examples/ad-hoc/base/index.js' -e ExampleAdHocBaseStack

ad-hoc-base-diff:
cdk diff --app='./lib/examples/ad-hoc/base/index.js' -e TestAdHocBaseStack
cdk diff --app='./lib/examples/ad-hoc/base/index.js' -e ExampleAdHocBaseStack

ad-hoc-base-deploy:
cdk deploy --app='./lib/examples/ad-hoc/base/index.js' --require-approval never -e TestAdHocBaseStack
cdk deploy --app='./lib/examples/ad-hoc/base/index.js' -e ExampleAdHocBaseStack

ad-hoc-base-deploy-approve:
cdk deploy --app='./lib/examples/ad-hoc/base/index.js' --require-approval never -e ExampleAdHocBaseStack

ad-hoc-base-destroy:
cdk destroy --app='./lib/examples/ad-hoc/base/index.js' --require-approval never TestAdHocBaseStack
cdk destroy --app='./lib/examples/ad-hoc/base/index.js' --require-approval never -e ExampleAdHocBaseStack

## ad hoc app cdk commands
ad-hoc-app-synth:
cdk synth --app='./lib/examples/ad-hoc/app/index.js' TestAdHocAppStack
cdk synth --app='./lib/examples/ad-hoc/base/index.js' -e ExampleAdHocAppStack

ad-hoc-app-diff:
cdk diff --app='./lib/examples/ad-hoc/base/index.js' -e ExampleAdHocAppStack

ad-hoc-app-deploy:
cdk deploy --app='./lib/examples/ad-hoc/base/index.js' -e ExampleAdHocAppStack

ad-hoc-app-delete-services:
export AWS_PAGER=''
aws ecs delete-service --cluster alpha-cluster --service alpha-web-ui --force
aws ecs delete-service --cluster alpha-cluster --service alpha-default-worker --force
aws ecs delete-service --cluster alpha-cluster --service alpha-redis --force
aws ecs delete-service --cluster alpha-cluster --service alpha-gunicorn --force

ad-hoc-app-destroy: ad-hoc-app-delete-services
cdk destroy --app='./lib/examples/ad-hoc/base/index.js' -e ExampleAdHocAppStack
34 changes: 15 additions & 19 deletions src/constructs/ad-hoc/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ export interface AdHocAppProps {
readonly assetsBucket: Bucket;
readonly domainName: string;
readonly listener: ApplicationListener;

// application specific props
readonly backendVersion?: string;
readonly frontendVersion?: string;
readonly djangoSettingsModule?: string;
}

export class AdHocApp extends Construct {
Expand All @@ -46,11 +41,11 @@ export class AdHocApp extends Construct {
// const highestPriorityRule = new HighestPriorityRule(this, 'HighestPriorityRule', { listener: props.listener });

const backendEcrRepo = Repository.fromRepositoryName(this, 'BackendRepo', 'backend');
const backendVersion = props.frontendVersion ?? 'latest';
const backendVersion = 'latest';
const backendImage = new EcrImage(backendEcrRepo, backendVersion);

const frontendEcrRepo = Repository.fromRepositoryName(this, 'FrontendRepo', 'frontend');
const frontendVersion = props.frontendVersion ?? 'latest';
const frontendVersion = 'latest';
const frontendImage = new EcrImage(frontendEcrRepo, frontendVersion);

const cluster = new Cluster(this, 'Cluster', {
Expand All @@ -61,19 +56,26 @@ export class AdHocApp extends Construct {

const serviceDiscoveryNamespace = props.serviceDiscoveryNamespace.namespaceName;

const settingsModule = this.node.tryGetContext('config').settingsModule ?? 'backend.settings.production';
// shared environment variables
const environmentVariables: { [key: string]: string }= {
let environmentVariables: { [key: string]: string } = {
S3_BUCKET_NAME: props.assetsBucket.bucketName,
REDIS_SERVICE_HOST: `${stackName}-redis.${serviceDiscoveryNamespace}`,
POSTGRES_SERVICE_HOST: props.rdsInstance.dbInstanceEndpointAddress,
POSTGRES_NAME: `${stackName}-db`,
DJANGO_SETTINGS_MODULE: props.djangoSettingsModule ?? 'backend.settings.production',
DJANGO_SETTINGS_MODULE: settingsModule,
FRONTEND_URL: `https://${stackName}.${props.domainName}`,
DOMAIN_NAME: props.domainName,
// TODO: read this from ad hoc base stack
DB_SECRET_NAME: 'DB_SECRET_NAME',
};

const extraEnvVars = this.node.tryGetContext('config').extraEnvVars;

if (extraEnvVars) {
environmentVariables = { ...extraEnvVars, ...environmentVariables };
}

// define ecsTaskRole and taskExecutionRole for ECS
const ecsRoles = new EcsRoles(scope, 'EcsRoles');

Expand Down Expand Up @@ -109,12 +111,10 @@ export class AdHocApp extends Construct {
image: backendImage,
listener: props.listener,
command: ['gunicorn', '-t', '1000', '-b', '0.0.0.0:8000', '--log-level', 'info', 'backend.wsgi'],
containerName: 'api',
family: 'api',
name: 'gunicorn',
port: 8000,
domainName: props.domainName,
pathPatterns: ['/api/*', '/admin/*', '/mtv/*', '/graphql/*'],
hostHeaders: ['*'],
priority: 2, //highestPriorityRule.priority + 1,
healthCheckPath: '/api/health-check/',
});
Expand All @@ -131,12 +131,10 @@ export class AdHocApp extends Construct {
image: frontendImage,
listener: props.listener,
command: ['nginx', '-g', 'daemon off;'],
containerName: 'web-ui',
family: `${stackName}-web-ui`,
name: 'web-ui',
port: 80,
domainName: props.domainName,
pathPatterns: ['/*'],
hostHeaders: ['*'],
priority: 3, // highestPriorityRule.priority + 2,
healthCheckPath: '/',
});
Expand All @@ -151,8 +149,7 @@ export class AdHocApp extends Construct {
executionRole: ecsRoles.taskExecutionRole,
image: backendImage,
command: ['celery', '--app=backend.celery_app:app', 'worker', '--loglevel=INFO', '-Q', 'default'],
containerName: 'default-worker',
family: 'default-worker',
name: 'default-worker',
});

// scheduler service
Expand All @@ -167,8 +164,7 @@ export class AdHocApp extends Construct {
executionRole: ecsRoles.taskExecutionRole,
image: backendImage,
command: ['python', 'manage.py', 'pre_update'],
containerName: 'backendUpdate',
family: 'backendUpdate',
name: 'backendUpdate',
});

// define stack output use for running the management command
Expand Down
8 changes: 3 additions & 5 deletions src/constructs/ad-hoc/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ export class AdHocBase extends Construct {
constructor(scope: Construct, id: string, props: AdHocBaseProps) {
super(scope, id);

const foo = this.node.tryGetContext('config').extraEnvVars;

console.log(foo);

const stackName = Stack.of(this).stackName;
this.domainName = props.domainName;

Expand Down Expand Up @@ -72,7 +68,7 @@ export class AdHocBase extends Construct {
const rdsInstance = new RdsInstance(this, 'RdsInstance', {
vpc: this.vpc,
appSecurityGroup: appSecurityGroup,
dbSecretName: 'DB_SECRET_NAME',
dbSecretName: this.node.tryGetContext('config')?.dbSecretName ?? 'DB_SECRET_NAME',
});
this.databaseInstance = rdsInstance.rdsInstance;
const { dbInstanceEndpointAddress } = rdsInstance.rdsInstance;
Expand All @@ -81,6 +77,8 @@ export class AdHocBase extends Construct {
appSecurityGroup,
vpc: this.vpc,
rdsAddress: dbInstanceEndpointAddress,
instanceClass: this.node.tryGetContext('config').instanceClass,
// instanceType: this.node.tryGetContext('config').instanceType,
});
}
}
17 changes: 8 additions & 9 deletions src/constructs/internal/ecs/management-command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ export interface ManagementCommandTaskProps {
readonly appSecurityGroup: ISecurityGroup;
readonly image: ContainerImage;
readonly command: string[];
readonly containerName: string;
readonly name: string;
readonly taskRole: Role;
readonly executionRole: Role;
readonly family: string;
readonly environmentVariables: { [key: string]: string };
};

Expand All @@ -43,8 +42,8 @@ export class ManagementCommandTask extends Construct {
const stackName = Stack.of(this).stackName;

// define log group and logstream
const logGroupName = `/ecs/${stackName}/${props.containerName}/`;
const streamPrefix = props.containerName;
const logGroupName = `/ecs/${stackName}/${props.name}/`;
const streamPrefix = props.name;
const logGroup = new LogGroup(this, 'LogGroup', {
logGroupName,
retention: RetentionDays.ONE_DAY,
Expand All @@ -53,21 +52,21 @@ export class ManagementCommandTask extends Construct {

new LogStream(this, 'LogStream', {
logGroup,
logStreamName: props.containerName,
logStreamName: props.name,
});

// task definition
const taskDefinition = new FargateTaskDefinition(this, 'TaskDefinition', {
cpu: props.cpu ?? 256,
executionRole: props.executionRole,
taskRole: props.taskRole,
family: props.family,
family: props.name,
});

taskDefinition.addContainer(props.containerName, {
taskDefinition.addContainer(props.name, {
image: props.image,
command: props.command,
containerName: props.containerName,
containerName: props.name,
environment: props.environmentVariables,
essential: true,
logging: LogDriver.awsLogs({
Expand All @@ -88,7 +87,7 @@ aws ecs wait tasks-stopped --tasks $TASK_ID --cluster ${props.cluster.clusterArn
END_TIME=$(date +%s000)
aws logs get-log-events --log-group-name ${logGroupName} --log-stream-name ${streamPrefix}/${props.containerName}/\${TASK_ID##*/} --start-time $START_TIME --end-time $END_TIME | jq -r '.events[].message'
aws logs get-log-events --log-group-name ${logGroupName} --log-stream-name ${streamPrefix}/${props.name}/\${TASK_ID##*/} --start-time $START_TIME --end-time $END_TIME | jq -r '.events[].message'
`;

this.executionScript = executionScript;
Expand Down
18 changes: 8 additions & 10 deletions src/constructs/internal/ecs/web/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { Construct } from 'constructs';


export interface WebProps {
readonly name: string;
readonly cluster: Cluster;
readonly vpc: IVpc;
readonly listener: ApplicationListener;
Expand All @@ -35,14 +36,11 @@ export interface WebProps {
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 };
readonly domainName: string;
readonly pathPatterns: string[];
readonly hostHeaders: string[];
readonly port: number;
readonly priority: number;
readonly healthCheckPath: string;
Expand All @@ -55,8 +53,8 @@ export class WebService extends Construct {
const stackName = Stack.of(this).stackName;

// define log group and logstream
const logGroupName = `/ecs/${stackName}/${props.containerName}/`;
const streamPrefix = props.containerName;
const logGroupName = `/ecs/${stackName}/${props.name}/`;
const streamPrefix = props.name;

// define log group and logstream
const logGroup = new LogGroup(this, 'LogGroup', {
Expand All @@ -67,21 +65,21 @@ export class WebService extends Construct {

new LogStream(this, 'LogStream', {
logGroup,
logStreamName: props.containerName,
logStreamName: props.name,
});

// task definition
const taskDefinition = new FargateTaskDefinition(this, 'TaskDefinition', {
cpu: props.cpu ?? 256,
executionRole: props.executionRole,
taskRole: props.taskRole,
family: props.family,
family: props.name,
});

taskDefinition.addContainer(props.containerName, {
taskDefinition.addContainer(props.name, {
image: props.image,
command: props.command,
containerName: props.containerName,
containerName: props.name,
environment: props.environmentVariables,
essential: true,
logging: LogDriver.awsLogs({
Expand Down Expand Up @@ -113,7 +111,7 @@ export class WebService extends Construct {
desiredCount: 1,
enableExecuteCommand: true,
securityGroups: [props.appSecurityGroup],
serviceName: `${stackName}-${props.containerName}`,
serviceName: `${stackName}-${props.name}`,
vpcSubnets: {
subnets: props.vpc.privateSubnets,
},
Expand Down
17 changes: 8 additions & 9 deletions src/constructs/internal/ecs/worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Construct } from 'constructs';


export interface WorkerProps {
readonly name: string;
readonly cluster: Cluster;
readonly vpc: IVpc;
readonly cpu?: number;
Expand All @@ -25,10 +26,8 @@ export interface WorkerProps {
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 };
};

Expand All @@ -39,8 +38,8 @@ export class WorkerService extends Construct {
const stackName = Stack.of(this).stackName;

// define log group and logstream
const logGroupName = `/ecs/${stackName}/${props.containerName}/`;
const streamPrefix = props.containerName;
const logGroupName = `/ecs/${stackName}/${props.name}/`;
const streamPrefix = props.name;

// define log group and logstream
const logGroup = new LogGroup(this, 'LogGroup', {
Expand All @@ -51,21 +50,21 @@ export class WorkerService extends Construct {

new LogStream(this, 'LogStream', {
logGroup,
logStreamName: props.containerName,
logStreamName: props.name,
});

// task definition
const taskDefinition = new FargateTaskDefinition(this, 'TaskDefinition', {
cpu: props.cpu ?? 256,
executionRole: props.executionRole,
taskRole: props.taskRole,
family: props.family,
family: props.name,
});

taskDefinition.addContainer(props.containerName, {
taskDefinition.addContainer(props.name, {
image: props.image,
command: props.command,
containerName: props.containerName,
containerName: props.name,
environment: props.environmentVariables,
essential: true,
logging: LogDriver.awsLogs({
Expand Down Expand Up @@ -96,7 +95,7 @@ export class WorkerService extends Construct {
desiredCount: 1,
enableExecuteCommand: true,
securityGroups: [props.appSecurityGroup],
serviceName: `${stackName}-${props.containerName}`,
serviceName: `${stackName}-${props.name}`,
vpcSubnets: {
subnets: props.vpc.privateSubnets,
},
Expand Down
Loading

0 comments on commit 6c40d08

Please sign in to comment.