Skip to content

Commit

Permalink
feat(stacks.api/stacks): implement DatabaseBastion construct
Browse files Browse the repository at this point in the history
Signed-off-by: Braden Mars <bradenmars@bradenmars.me>
  • Loading branch information
BradenM committed Aug 14, 2023
1 parent a9425fa commit 1880500
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions packages/stacks/api/src/stacks/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as ec2 from 'aws-cdk-lib/aws-ec2'
import * as kms from 'aws-cdk-lib/aws-kms'
import * as rds from 'aws-cdk-lib/aws-rds'
import { type ISecret, Secret } from 'aws-cdk-lib/aws-secretsmanager'
import { KeyPair } from 'cdk-ec2-key-pair'
import { Construct } from 'constructs'
import { type DatabaseConfig } from '../schema'

Expand Down Expand Up @@ -103,6 +104,81 @@ export class Database extends Construct {
}
}

interface DatabaseBastionProps {
readonly database: rds.IDatabaseCluster
readonly vpc: ec2.IVpc
readonly allowCidrs: string[]
readonly encryptionKey: kms.IKey
}

export class DatabaseBastion extends Construct {
readonly bastion: ec2.BastionHostLinux
readonly securityGroup: ec2.ISecurityGroup
readonly allowPrefixList: ec2.IPrefixList
readonly keyPair: KeyPair

constructor(scope: Construct, id: string, props: DatabaseBastionProps) {
super(scope, id)

const { database, vpc, encryptionKey, allowCidrs } = props

this.securityGroup = new ec2.SecurityGroup(this, id + '-security-group', {
vpc,
allowAllOutbound: true,
description: 'Security group for bastion host',
})
database.connections.allowFrom(
this.securityGroup,
ec2.Port.tcp(5432),
'Allow inbound from bastion host',
)
this.securityGroup.connections.allowTo(
database,
ec2.Port.tcp(5432),
'Allow outbound to database',
)

this.allowPrefixList = new ec2.PrefixList(this, id + '-prefix-list', {
addressFamily: ec2.AddressFamily.IP_V4,
entries: allowCidrs.map((cidr) => ({
cidr,
description: 'Bastion allowlist.',
})),
maxEntries: 50,
})

this.securityGroup.addIngressRule(
ec2.Peer.prefixList(this.allowPrefixList.prefixListId),
ec2.Port.tcp(22),
'Bastion Allow list.',
)

this.keyPair = new KeyPair(this, id + '-key-pair', {
kms: encryptionKey as kms.Key,
description: 'SSH key pair for bastion host',
name: 'database/bastion/key-pair',
storePublicKey: true,
})

this.bastion = new ec2.BastionHostLinux(this, id + '-bastion', {
vpc,
securityGroup: this.securityGroup,
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T4G,
ec2.InstanceSize.NANO,
),
subnetSelection: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }),
})
this.bastion.instance.instance.addPropertyOverride(
'KeyName',
this.keyPair.keyPairName,
)
this.bastion.allowSshAccessFrom(
ec2.Peer.prefixList(this.allowPrefixList.prefixListId),
)
}
}

export interface DataStackProps {
vpc: ec2.IVpc
encryptionKey?: kms.IKey
Expand Down Expand Up @@ -148,5 +224,12 @@ export class DataStack extends cdk.Stack {
credentialsSecret: this.credentialsSecret,
...props.clusterProps,
})

new DatabaseBastion(this, id + '-bastion', {
vpc: props.vpc,
encryptionKey: this.encryptionKey,
allowCidrs: props.clusterProps.bastionAllowList,
database: this.dbCluster.cluster,
})
}
}

0 comments on commit 1880500

Please sign in to comment.