Within my development environment, I have two stacks in place - one dedicated to creating an RDS DB and the other focused on managing cloudwatch alarms. My goal is to pass the dbInstance details seamlessly between these two stacks:
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import { StackProps } from 'aws-cdk-lib';
import { IMetric } from 'aws-cdk-lib/aws-cloudwatch';
export class DatabaseStack extends cdk.Stack {
public readonly dbName: rds.DatabaseInstance
public readonly dbCPUUsage: IMetric
public readonly dbInstance: any;
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
/* Created a VPC with a PUBLIC and an ISOLATED subnet groups.
RDS instance will be launched in an ISOLATED subnet because we'll be
connecting to it from our EC2 instance, which is in the same VPC. */
const vpc = new ec2.Vpc(this, 'my-cdk-vpc',{
...
});
const ec2InstanceSG = new ec2.SecurityGroup(this, 'ec2-instance-sg', {
vpc,
});
/* create security group for the EC2 instance with single inbound rule,
which allows SSH connections from anywhere. */
ec2InstanceSG.addIngressRule(
ec2.Peer.anyIpv4(),
ec2.Port.tcp(22),
'allow SSH connections from anywhere',
);
// Created a t2.micro EC2 instance with Amazon Linux 2 AMI and placed it in a PUBLIC subnet.
const ec2Instance = new ec2.Instance(this, 'ec2-instance', {
...
});
/* Create RDS instance */
const dbInstance = new rds.DatabaseInstance(this, 'db-instance',{
...
});
// Allow connections to our RDS instance, on port 5432, from the security group of the EC2 instance
dbInstance.connections.allowFrom(ec2Instance, ec2.Port.tcp(5432));
// Database hostname that we'll use to connect to our RDS instance
new cdk.CfnOutput(this, 'dbEndpoint', {
value:dbInstance.instanceEndpoint.hostname,
});
// Name of the secret that stores the password of the postgres user
new cdk.CfnOutput(this, 'secretName', {
value: dbInstance.secret?.secretName!,
});
new cloudwatch.Alarm(this, 'HighCPU', {
metric: dbInstance.metricCPUUtilization(),
threshold: 100,
evaluationPeriods: 2,
})
this.dbName = dbInstance;
this.dbCPUUsage = dbInstance.metricCPUUtilization();
}
;
}
export interface CloudwatchStackProps extends StackProps {
dbNameExport: rds.IDatabaseInstance;
dbCPUUsageExport: IMetric;
};
We then bridge this stack with:
import * as cdk from 'aws-cdk-lib';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import { IDatabaseInstance } from 'aws-cdk-lib/aws-rds';
import { Stack } from 'aws-cdk-lib';
import { CloudwatchStackProps } from '../lib/cdk-database-stack';
export class CloudwatchStack extends Stack {
private readonly dbInstance: IDatabaseInstance
constructor(scope: cdk.App, id: string, props: CloudwatchStackProps) {
super(scope, id, props);
const cpuUsage = props.dbCPUUsageExport
new cloudwatch.Alarm(this.dbInstance, 'CPUUsage', {
metric: cpuUsage(),
threshold: 100,
evaluationPeriods: 2,
});
}
}
As I execute CDK Diff, an error surfaces stating "Cannot read properties of undefined (reading 'metric'))."
Below is the content of the bin file included:
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { AmsAwsTestingGroundsStack } from '../lib/ams-aws-testing-grounds-stack';
import { CloudwatchStack } from '../lib/cdk-cloudwatch-stack';
import { DatabaseStack } from '../lib/cdk-database-stack';
const app = new cdk.App();
new AmsAwsTestingGroundsStack(app, 'AmsAwsTestingGroundsStack');
const databaseStack = new DatabaseStack(app, 'DatabaseStack');
const cloudwatchstack = new CloudwatchStack(app, 'CloudwatchStack', {
dbNameExport: databaseStack.dbName,
dbCPUUsageExport: databaseStack.dbCPUUsage,
});
Your assistance would be greatly appreciated, thank you!
EDIT - solution
new cloudwatch.Alarm(this, 'CPUUsage', {
metric: cpuUsage,
threshold: 100,
evaluationPeriods: 2,
});