Skip to content

Commit

Permalink
Added a CDK stack for the database and network.
Browse files Browse the repository at this point in the history
  • Loading branch information
rizen committed Aug 9, 2024
1 parent bc9feb1 commit 3831ed7
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 66 deletions.
22 changes: 22 additions & 0 deletions cdk/bin/cdk.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import cdk from 'aws-cdk-lib';
import { UploadStack } from '../lib/upload-stack.mjs';
import { NetworkStack } from '../lib/network-stack.mjs';
import { DatabaseStack } from '../lib/database-stack.mjs';
import { generatePrefix, generateSuffix } from '../lib/utils.mjs';
import constants from '../lib/constants.mjs';

Expand All @@ -27,3 +29,23 @@ new UploadStack(app, `${prefix}-UploadStack${suffix}`, {
env: { account: constants.stages[stage].account, region: constants.stages[stage].region },
});

if (stage != 'dev') {

const network = new NetworkStack(app, `${prefix}-NetworkStack${suffix}`, {
stage,
constants,
stageConfig: constants.stages[stage],
formatName: (name) => `${prefix}-${name}${suffix}`,
env: { account: constants.stages[stage].account, region: constants.stages[stage].region },
});

new DatabaseStack(app, `${prefix}-DatabaseStack${suffix}`, {
vpc: network.vpc,
stage,
constants,
stageConfig: constants.stages[stage],
formatName: (name) => `${prefix}-${name}${suffix}`,
env: { account: constants.stages[stage].account, region: constants.stages[stage].region },
});

}
10 changes: 10 additions & 0 deletions cdk/cdk.context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"availability-zones:account=041977924901:region=us-east-1": [
"us-east-1a",
"us-east-1b",
"us-east-1c",
"us-east-1d",
"us-east-1e",
"us-east-1f"
]
}
10 changes: 8 additions & 2 deletions cdk/lib/constants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ export default {
memorySize: 512, // megabytes
timeout: 60, // seconds
},
uploadsBucketNameOverride: 'uploads.ving.com',
thumbnailsBucketNameOverride: 'thumbnails.ving.com',
auroraSettings: {
adminUser: 'root',
minCapacity: 0.5,
maxCapacity: 2,
backupRetention: 7, // days
},
uploadsBucketNameOverride: 'uploads.somedomainthattotallyexists.com',
thumbnailsBucketNameOverride: 'thumbnails.somedomainthattotallyexists.com',
},
}
};
92 changes: 92 additions & 0 deletions cdk/lib/database-stack.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Stack, Duration } from 'aws-cdk-lib';
import elasticache from 'aws-cdk-lib/aws-elasticache';
import cdk from 'aws-cdk-lib';
import rds from 'aws-cdk-lib/aws-rds';
import ec2 from 'aws-cdk-lib/aws-ec2';

export class DatabaseStack extends Stack {
/**
*
* @param {Construct} scope
* @param {string} id
* @param {StackProps=} props
*/
constructor(scope, id, props) {
super(scope, id, props);

const vpc = props.vpc;

const securityGroup = new ec2.SecurityGroup(this, props.formatName('database-sg'), {
description: 'Allow traffic to Aurora and Redis',
vpc,
allowAllOutbound: true,
});

// will need to close thse down once we have servers connecting to the database and can use better rules
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(3306));
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(6379));


/*
* Redis
*/

const redisSubnetGroup = new elasticache.CfnSubnetGroup(this, props.formatName('redis-sg'), {
description: 'Redis subnet group',
subnetIds: vpc.privateSubnets.map((subnet) => subnet.subnetId),
});

const redisCluster = new elasticache.CfnReplicationGroup(this, props.formatName('redis'), {
replicationGroupDescription: 'Redis cluster',
cacheNodeType: 'cache.t3.micro',
engine: 'redis',
engineVersion: '7.0',
numCacheClusters: 1,
automaticFailoverEnabled: false,
cacheSubnetGroupName: redisSubnetGroup.ref,
securityGroupIds: [securityGroup.securityGroupId],
});


/*
* Aurora
*/


const clusterParameterGroup = new rds.ParameterGroup(this, props.formatName('mysql8params'), {
engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_3_07_0 }),
description: 'Custom parameter group for MySLQ 8 on ving',
parameters: {
'character_set_server': 'utf8',
'collation_server': 'utf8_unicode_ci',
'innodb_ft_min_token_size': 2,
'sql_mode': 'NO_ENGINE_SUBSTITUTION',
},
});

// Create a new Aurora Serverless MySQL cluster
const auroraName = props.formatName('aurora')
const auroraCluster = new rds.DatabaseCluster(this, auroraName, {
engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_3_07_0 }),
vpc,
credentials: {
username: props.stageConfig.auroraSettings.adminUser || 'root',
},
clusterIdentifier: auroraName,
serverlessV2MinCapacity: props.stageConfig.auroraSettings.minCapacity || 1,
serverlessV2MaxCapacity: props.stageConfig.auroraSettings.maxCapacity || 2,
backupRetention: Duration.days(props.stageConfig.auroraSettings.backupRetention || 7),
securityGroups: [securityGroup],
parameterGroup: clusterParameterGroup,
deletionProtection: true,
removalPolicy: cdk.RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE,
writer: rds.ClusterInstance.serverlessV2(auroraName + '-writer'),
readers: [
// will be put in promotion tier 1 and will scale with the writer
rds.ClusterInstance.serverlessV2(auroraName + '-reader1', { scaleWithWriter: true }),
],

});

}
}
23 changes: 23 additions & 0 deletions cdk/lib/network-stack.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Stack, Duration } from 'aws-cdk-lib';
import iam from 'aws-cdk-lib/aws-iam';
import cdk from 'aws-cdk-lib';
import rds from 'aws-cdk-lib/aws-rds';
import ec2 from 'aws-cdk-lib/aws-ec2';

export class NetworkStack extends Stack {
/**
*
* @param {Construct} scope
* @param {string} id
* @param {StackProps=} props
*/
constructor(scope, id, props) {
super(scope, id, props);

this.vpc = new ec2.Vpc(this, props.formatName('vpc'), {
maxAzs: 2,
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
});

}
}
6 changes: 3 additions & 3 deletions cdk/lib/upload-stack.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class UploadStack extends Stack {
// create the bucket
const thumbnailsName = props.formatName(props.constants.thumbnailsBucketName);
const thumbnailsBucket = new s3.Bucket(this, thumbnailsName, {
bucketName: props.stageConfig.uploadsBucketNameOverride || thumbnailsName,
bucketName: props.stageConfig.thumbnailsBucketNameOverride || thumbnailsName,
removalPolicy: cdk.RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE,
cors: [
{
Expand Down Expand Up @@ -149,8 +149,8 @@ export class UploadStack extends Stack {
code: lambda.Code.fromAsset('./lib/lambda/func/processUpload'),
layers: [nodemodsLayer],
role: iamForLambda,
timeout: props.constants.stages[props.stage].uploadsLambdaSettings.timeout,
memorySize: props.constants.stages[props.stage].uploadsLambdaSettings.memorySize,
timeout: Duration.seconds(props.stageConfig.uploadsLambdaSettings.timeout || 60),
memorySize: props.stageConfig.uploadsLambdaSettings.memorySize || 128,
environment: {
VING_AWS_THUMBNAILS_BUCKET: thumbnailsBucket.bucketName,
},
Expand Down
1 change: 1 addition & 0 deletions ving/docs/change-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ outline: deep
* Started replacing Pulumi with CDK.
* Added a CDK stack for uploads.
* NOTE: Pulumi will be removed in a near future release. Do a `pulumi down; pulumi destroy` to remove the stacks, and then follow the CDK instructions to create recreate the stacks.
* Added a CDK stack for the database and network.

### 2024-08-07
* Switched to using hooks to copy ving.json to the build directory.
Expand Down
10 changes: 7 additions & 3 deletions ving/docs/subsystems/cdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,15 @@ Above we always used the `dev` stage. This is what you want to use on your local


## Stacks
Stacks are divisions of AWS resources in CDK. We divide them into areas of responsibility. For example, we have a `uploads` stack that generates the S3 buckets for uploads and thumbnails. We have a `database` stack that generates the Aurora Serverless database and Redis cluster. And we have a `server` stack that generates the EC2 instance that runs the Ving server.
Stacks are divisions of AWS resources in CDK. We divide them into areas of responsibility. For example, we have a `uploads` stack that generates the S3 buckets for uploads and thumbnails. There is also a `network` stack for creating the virtual private cloud that all the hardware will be connected to. We have a `database` stack that generates the Aurora Serverless database and Redis cluster. And in the future we will have a `server` stack that generates the EC2/lambda instances that run the Ving web and jobs servers.

You can create your own stacks as well by following the instructions in the [CDK documentation](https://docs.aws.amazon.com/cdk/v2/guide/stacks.html#stacks).

### Special Needs of the Databsae Stack
First by default it will create a database with the root user of `root` and the password `changeMeAfterTheFact`. You'll need to change this password in the AWS console. You can do this by going to the RDS console, clicking on the cluster, and then clicking on the "Modify" button. Then you can change the password.
First, by default it will create a database with the root user of `root` and no password. You'll need to set the password in the AWS console. You can do this by going to the RDS console, clicking on the cluster, and then clicking on the "Modify" button. Then you can change the password.

Second, you may also want to change the minimum and maximum capacity units of the Aurora cluster. You can do this in the `cdk/lib/constants.mjs` file.
Second, you may also want to change the minimum and maximum capacity units of the Aurora cluster. You can do this in the `cdk/lib/constants.mjs` file.

Third, the stack does not create or deploy your ving database schema. It simply creates the cluster that the database will run on. Follow the [Drizzle](drizzle) documentation to create and deploy your schema.

*Note:* If you ever want to delete your database, you should change `RETAIN_ON_UPDATE_OR_DELETE` to `DESTROY` in the `DatabaseStack` class first. Then deploy it. And then destroy it.
58 changes: 0 additions & 58 deletions ving/docs/subsystems/pulumi.md

This file was deleted.

0 comments on commit 3831ed7

Please sign in to comment.