import { Construct } from 'constructs'; import kebabCase from 'lodash.kebabcase'; import snakeCase from 'lodash.snakecase'; import { DbInstance } from '../generated/providers/aws/rds'; import { SecurityGroup } from '../generated/providers/aws/vpc'; import { getId } from '../utils'; import DatabaseCredentials from './DatabaseCredentials'; export type DatabaseProps = { /** * List of security groups that can access the db */ securityGroupIds: string[]; credentials: DatabaseCredentials; }; export default class Database extends Construct { readonly address: string; readonly port: number; readonly name: string; constructor(scope: Construct, id: string, props: DatabaseProps) { super(scope, id); const dbSecurityGroup = new SecurityGroup(this, 'security_group', { namePrefix: kebabCase(id), ingress: [ { fromPort: 0, toPort: 0, protocol: '-1', cidrBlocks: ['0.0.0.0/0'], // Allowing traffic in from all ip in the security group securityGroups: [...props.securityGroupIds], }, ], egress: [ { fromPort: 0, toPort: 0, protocol: '-1', cidrBlocks: ['0.0.0.0/0'], // Allowing traffic out to all ip in the security group securityGroups: [...props.securityGroupIds], }, ], }); const dbName = snakeCase(getId()); const db = new DbInstance(this, 'instance', { identifier: `${kebabCase(getId())}-pg`, instanceClass: process.env.NODE_ENV === 'production' ? 'db.m6g.large' : 'db.t3.micro', allocatedStorage: 10, maxAllocatedStorage: 100, engine: 'postgres', username: props.credentials.username, password: props.credentials.password, name: dbName, publiclyAccessible: true, vpcSecurityGroupIds: [...props.securityGroupIds, dbSecurityGroup.id], finalSnapshotIdentifier: kebabCase(getId(id, 'snapshot')), snapshotIdentifier: undefined, backupRetentionPeriod: 3, }); this.name = dbName; this.address = db.address; this.port = db.port; } }