in apigw-http-api-lambda-rds-proxy-cdk/src/lib/rds-proxy-sequelize-stack.ts [15:171]
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpc = new ec2.Vpc(this, "RdsProxyExampleVpc", {
subnetConfiguration: [
{
name: 'Isolated',
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
{
name: 'Private',
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
},
{
name: 'Public',
subnetType: ec2.SubnetType.PUBLIC,
}
]
});
const dbUsername = 'syscdk';
const rdsSecret = new secretsmanager.Secret(this, 'RdsProxyExampleSecret', {
secretName: id+'-rds-credentials',
generateSecretString: {
secretStringTemplate: JSON.stringify({ username: dbUsername }),
generateStringKey: 'password',
excludePunctuation: true,
includeSpace: false,
}
});
// Create a security group to be used on the lambda functions
const lambdaSecurityGroup = new ec2.SecurityGroup(this, 'Lambda Security Group', {
vpc
});
// Create a security group to be used on the RDS proxy
const rdsProxySecurityGroup = new ec2.SecurityGroup(this, 'Only Allow Access From Lambda', {
vpc
});
rdsProxySecurityGroup.addIngressRule(lambdaSecurityGroup, ec2.Port.tcp(5432), 'allow lambda connection to rds proxy');
// Create a security group to be used on the RDS instances
const rdsSecurityGroup = new ec2.SecurityGroup(this, 'Only Allow Access From RDS Proxy', {
vpc
});
rdsSecurityGroup.addIngressRule(rdsProxySecurityGroup, ec2.Port.tcp(5432), 'allow db connections from the rds proxy');
const rdsCredentials = rds.Credentials.fromSecret(rdsSecret);
const dbName = 'nflstadiums';
const postgreSql = new rds.DatabaseCluster(this, 'RdsProxyExampleCluster', {
instanceProps:
{
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED
},
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM),
securityGroups: [ rdsSecurityGroup ]
},
clusterIdentifier: 'RDSProxyExampleCluster',
engine: rds.DatabaseClusterEngine.auroraPostgres({
version: rds.AuroraPostgresEngineVersion.VER_11_9
}),
instances: 1,
backup: { retention: Duration.days(1) },
removalPolicy: RemovalPolicy.DESTROY,
credentials: rdsCredentials,
defaultDatabaseName: dbName,
});
const rdsProxy = postgreSql.addProxy('rdsProxyExample', {
secrets: [ rdsSecret ],
securityGroups: [ rdsProxySecurityGroup ],
debugLogging: true,
iamAuth: true,
vpc
});
const rdsProxyPopulateLambda: NodejsFunction = new NodejsFunction(this, id+'-populateLambda', {
memorySize: 1024,
timeout: cdk.Duration.seconds(5),
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'handler',
entry: path.join(__dirname, '../lambda/populate.ts'),
vpc: vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
securityGroups: [ lambdaSecurityGroup ],
environment: {
PGHOST: rdsProxy.endpoint,
PGDATABASE: dbName,
PGUSER: dbUsername
},
// Bundler removes these dependencies since they aren't imported explicitly
// Include them so sequelize can connect to Postgres
bundling: {
nodeModules: [ 'pg', 'pg-hstore' ]
}
});
const rdsProxyGetDataLambda: NodejsFunction = new NodejsFunction(this, id+'-getDataLambda', {
memorySize: 1024,
timeout: cdk.Duration.seconds(5),
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'handler',
entry: path.join(__dirname, '../lambda/getData.ts'),
vpc: vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
securityGroups: [ lambdaSecurityGroup ],
environment: {
PGHOST: rdsProxy.endpoint,
PGDATABASE: dbName,
PGUSER: dbUsername
},
// Bundler removes these dependencies since they aren't imported explicitly
// Include them so sequelize can connect to Postgres
bundling: {
nodeModules: [ 'pg', 'pg-hstore' ]
}
});
rdsProxy.grantConnect(rdsProxyPopulateLambda, dbUsername);
rdsProxy.grantConnect(rdsProxyGetDataLambda, dbUsername);
const httpApi: apigw.HttpApi = new apigw.HttpApi(this, 'HttpApi');
const populateLambdaIntegration = new LambdaProxyIntegration({
handler: rdsProxyPopulateLambda
});
const getDataLambdaIntegration = new LambdaProxyIntegration({
handler: rdsProxyGetDataLambda
});
httpApi.addRoutes({
path: '/populate',
methods: [HttpMethod.POST],
integration: populateLambdaIntegration
});
new CfnOutput(this, 'populateEndpointUrl', {
value: `${httpApi.url}populate`,
exportName: 'populateEndpointUrl'
});
httpApi.addRoutes({
path: '/',
methods: [HttpMethod.GET],
integration: getDataLambdaIntegration
});
new CfnOutput(this, 'stadiumsEndpointUrl', {
value: `${httpApi.url}`,
exportName: 'stadiumsEndpointUrl'
});
};