-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Chris Park
committed
Apr 19, 2024
1 parent
6c75d09
commit 13c3a52
Showing
13 changed files
with
1,452 additions
and
1,271 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# These are some examples of commonly ignored file patterns. | ||
# You should customize this list as applicable to your project. | ||
# Learn more about .gitignore: | ||
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore | ||
|
||
# Node artifact files | ||
node_modules/ | ||
dist/ | ||
|
||
# Compiled Java class files | ||
*.class | ||
|
||
# Compiled Python bytecode | ||
*.py[cod] | ||
|
||
# Log files | ||
*.log | ||
|
||
# Package files | ||
*.jar | ||
|
||
# Maven | ||
target/ | ||
dist/ | ||
|
||
# JetBrains IDE | ||
.idea/ | ||
|
||
# Unit test reports | ||
TEST*.xml | ||
|
||
# Generated by MacOS | ||
.DS_Store | ||
|
||
# Generated by Windows | ||
Thumbs.db | ||
|
||
# Applications | ||
*.app | ||
*.exe | ||
*.war | ||
|
||
# Large media files | ||
*.mp4 | ||
*.tiff | ||
*.avi | ||
*.flv | ||
*.mov | ||
*.wmv | ||
|
||
!jest.config.js | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out | ||
|
||
*.d.ts | ||
*.js | ||
|
||
# Lock files | ||
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"semi": true, | ||
"singleQuote": false, | ||
"arrowParens": "avoid" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,114 @@ | ||
#!/usr/bin/env node | ||
import 'source-map-support/register'; | ||
import { Stack, StackProps, App, Duration, aws_cloudwatch, aws_cloudwatch_actions, | ||
aws_rds, aws_ec2, aws_sns, aws_sns_subscriptions, aws_lambda, aws_lambda_nodejs, aws_ssm } from 'aws-cdk-lib'; | ||
import { Construct } from 'constructs'; | ||
import * as path from 'path'; | ||
import "source-map-support/register"; | ||
import { | ||
Stack, | ||
StackProps, | ||
App, | ||
Duration, | ||
aws_cloudwatch, | ||
aws_cloudwatch_actions, | ||
aws_rds, | ||
aws_ec2, | ||
aws_sns, | ||
aws_sns_subscriptions, | ||
aws_lambda, | ||
aws_lambda_nodejs, | ||
aws_ssm, | ||
} from "aws-cdk-lib"; | ||
import { Construct } from "constructs"; | ||
import * as path from "path"; | ||
// import { Subscription } from 'aws-cdk-lib/aws-sns'; | ||
|
||
const RDSINSTANCES = process.env.RDSINSTANCES as string; | ||
const SECURITYGROUP = process.env.SECURITYGROUP as string; | ||
const CDK_DEFAULT_ACCOUNT = process.env.CDK_DEFAULT_ACCOUNT | ||
const CDK_DEFAULT_REGION = process.env.CDK_DEFAULT_REGION | ||
const CDK_DEFAULT_ACCOUNT = process.env.CDK_DEFAULT_ACCOUNT; | ||
const CDK_DEFAULT_REGION = process.env.CDK_DEFAULT_REGION; | ||
const WEBHOOK_URL_PARAMETER = process.env.WEBHOOK_URL_PARAMETER as string; | ||
const ALERT_USERNAME = process.env.ALERT_USERNAME as string; | ||
const ALERT_CHANNEL = process.env.ALERT_CHANNEL as string; | ||
|
||
if (typeof RDSINSTANCES === 'string'){ | ||
var instances = RDSINSTANCES.split(','); | ||
if (typeof RDSINSTANCES === "string") { | ||
var instances = RDSINSTANCES.split(","); | ||
} | ||
|
||
export class CloudwatchRDSAlertStack extends Stack { | ||
constructor(scope: Construct, id: string, props?: StackProps) { | ||
super(scope, id, props); | ||
|
||
const topic = new aws_sns.Topic(this, 'SNS'); | ||
const topic = new aws_sns.Topic(this, "SNS"); | ||
|
||
for ( var i in instances) { | ||
const db = aws_rds.DatabaseInstance.fromDatabaseInstanceAttributes(this, instances[i], { | ||
instanceEndpointAddress: 'garbage value', // Can be an arbitrary value | ||
instanceIdentifier: instances[i], // CloudWatch looks out for this value | ||
port: 3306, // Can be an arbitrary value | ||
securityGroups: [aws_ec2.SecurityGroup.fromLookupById(this, instances[i]+'-sg', `${SECURITYGROUP}`)] // SG ID has to be valid | ||
}); | ||
for (var i in instances) { | ||
const db = aws_rds.DatabaseInstance.fromDatabaseInstanceAttributes( | ||
this, | ||
instances[i], | ||
{ | ||
instanceEndpointAddress: "garbage value", // Can be an arbitrary value | ||
instanceIdentifier: instances[i], // CloudWatch looks out for this value | ||
port: 3306, // Can be an arbitrary value | ||
securityGroups: [ | ||
aws_ec2.SecurityGroup.fromLookupById( | ||
this, | ||
instances[i] + "-sg", | ||
`${SECURITYGROUP}` | ||
), | ||
], // SG ID has to be valid | ||
} | ||
); | ||
// Only "Average over 5 minutes" is available, hence one evaluation only before firing the alarm off: | ||
// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_rds.DatabaseInstance.html#metricwbrcpuutilizationprops | ||
const alarm_cpu = new aws_cloudwatch.Alarm(this, instances[i]+'-alarm', { | ||
alarmName: instances[i]+' database CPU usage alert', // Notification title if sent to Slack | ||
evaluationPeriods: 1, // The number of periods over which data is compared to the specified threshold. ( 5 minute ) | ||
datapointsToAlarm: 1, // The number of datapoints that must be breaching to trigger the alarm. | ||
threshold: 30, // over x % | ||
metric: db.metricCPUUtilization(), | ||
treatMissingData: aws_cloudwatch.TreatMissingData.BREACHING | ||
}); | ||
const alarm_cpu = new aws_cloudwatch.Alarm( | ||
this, | ||
instances[i] + "-alarm", | ||
{ | ||
alarmName: instances[i] + " database CPU usage alert", // Notification title if sent to Slack | ||
evaluationPeriods: 1, // The number of periods over which data is compared to the specified threshold. ( 5 minute ) | ||
datapointsToAlarm: 1, // The number of datapoints that must be breaching to trigger the alarm. | ||
threshold: 30, // over x % | ||
metric: db.metricCPUUtilization(), | ||
treatMissingData: aws_cloudwatch.TreatMissingData.BREACHING, | ||
} | ||
); | ||
alarm_cpu.addAlarmAction(new aws_cloudwatch_actions.SnsAction(topic)); | ||
alarm_cpu.addOkAction(new aws_cloudwatch_actions.SnsAction(topic)); | ||
}; | ||
} | ||
|
||
const notifySlack = new aws_lambda_nodejs.NodejsFunction(this, 'notifySlack', { | ||
memorySize: 1024, | ||
timeout: Duration.seconds(5), | ||
runtime: aws_lambda.Runtime.NODEJS_14_X, | ||
handler: 'handler', | ||
entry: path.join(__dirname, `/../handlers/notifySlack.ts`), | ||
environment: { | ||
WEBHOOK_URL_PARAMETER: WEBHOOK_URL_PARAMETER, | ||
ALERT_USERNAME: ALERT_USERNAME, | ||
ALERT_CHANNEL: ALERT_CHANNEL | ||
const notifySlack = new aws_lambda_nodejs.NodejsFunction( | ||
this, | ||
"notifySlack", | ||
{ | ||
memorySize: 1024, | ||
timeout: Duration.seconds(5), | ||
runtime: aws_lambda.Runtime.NODEJS_14_X, | ||
handler: "handler", | ||
entry: path.join(__dirname, `/../handlers/notifySlack.ts`), | ||
environment: { | ||
WEBHOOK_URL_PARAMETER: WEBHOOK_URL_PARAMETER, | ||
ALERT_USERNAME: ALERT_USERNAME, | ||
ALERT_CHANNEL: ALERT_CHANNEL, | ||
}, | ||
} | ||
}); | ||
); | ||
|
||
const param = aws_ssm.StringParameter.fromSecureStringParameterAttributes(this, 'webhookurl', { | ||
parameterName: WEBHOOK_URL_PARAMETER, | ||
version: 1 | ||
}); | ||
const param = aws_ssm.StringParameter.fromSecureStringParameterAttributes( | ||
this, | ||
"webhookurl", | ||
{ | ||
parameterName: WEBHOOK_URL_PARAMETER, | ||
version: 1, | ||
} | ||
); | ||
param.grantRead(notifySlack); | ||
|
||
topic.addSubscription(new aws_sns_subscriptions.LambdaSubscription(notifySlack)); | ||
topic.addSubscription( | ||
new aws_sns_subscriptions.LambdaSubscription(notifySlack) | ||
); | ||
} | ||
} | ||
|
||
const app = new App(); | ||
new CloudwatchRDSAlertStack(app, 'CloudwatchRDSAlertStack', { | ||
new CloudwatchRDSAlertStack(app, "CloudwatchRDSAlertStack", { | ||
env: { | ||
account: `${CDK_DEFAULT_ACCOUNT}`, | ||
region: `${CDK_DEFAULT_REGION}` | ||
} | ||
}); | ||
region: `${CDK_DEFAULT_REGION}`, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.