Skip to content

Commit

Permalink
allow cloudbuster to run on a schedule
Browse files Browse the repository at this point in the history
  • Loading branch information
NovemberTang committed Oct 9, 2024
1 parent e669022 commit 2c760d6
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 184 deletions.
166 changes: 38 additions & 128 deletions packages/cdk/lib/__snapshots__/service-catalogue.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ exports[`The ServiceCatalogue stack matches the snapshot 1`] = `
"GuLambdaFunction",
"GuLambdaFunction",
"GuLambdaErrorPercentageAlarm",
"GuLambdaFunction",
"GuLambdaErrorPercentageAlarm",
"GuScheduledLambda",
],
"gu:cdk:version": "TEST",
},
Expand Down Expand Up @@ -19555,132 +19554,6 @@ spec:
},
"Type": "AWS::Lambda::Function",
},
"cloudbusterErrorPercentageAlarmForLambda3A9AF5A0": {
"Properties": {
"ActionsEnabled": true,
"AlarmActions": [
{
"Fn::Join": [
"",
[
"arn:aws:sns:",
{
"Ref": "AWS::Region",
},
":",
{
"Ref": "AWS::AccountId",
},
":devx-alerts",
],
],
},
],
"AlarmDescription": {
"Fn::Join": [
"",
[
{
"Ref": "cloudbuster8C461939",
},
" exceeded 0% error rate",
],
],
},
"AlarmName": {
"Fn::Join": [
"",
[
"High error percentage from ",
{
"Ref": "cloudbuster8C461939",
},
" lambda in TEST",
],
],
},
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": 1,
"Metrics": [
{
"Expression": "100*m1/m2",
"Id": "expr_1",
"Label": {
"Fn::Join": [
"",
[
"Error % of ",
{
"Ref": "cloudbuster8C461939",
},
],
],
},
},
{
"Id": "m1",
"MetricStat": {
"Metric": {
"Dimensions": [
{
"Name": "FunctionName",
"Value": {
"Ref": "cloudbuster8C461939",
},
},
],
"MetricName": "Errors",
"Namespace": "AWS/Lambda",
},
"Period": 60,
"Stat": "Sum",
},
"ReturnData": false,
},
{
"Id": "m2",
"MetricStat": {
"Metric": {
"Dimensions": [
{
"Name": "FunctionName",
"Value": {
"Ref": "cloudbuster8C461939",
},
},
],
"MetricName": "Invocations",
"Namespace": "AWS/Lambda",
},
"Period": 60,
"Stat": "Sum",
},
"ReturnData": false,
},
],
"Tags": [
{
"Key": "gu:cdk:version",
"Value": "TEST",
},
{
"Key": "gu:repo",
"Value": "guardian/service-catalogue",
},
{
"Key": "Stack",
"Value": "deploy",
},
{
"Key": "Stage",
"Value": "TEST",
},
],
"Threshold": 0,
"TreatMissingData": "notBreaching",
},
"Type": "AWS::CloudWatch::Alarm",
},
"cloudbusterServiceRoleDefaultPolicy173FB27F": {
"Properties": {
"PolicyDocument": {
Expand Down Expand Up @@ -19884,6 +19757,43 @@ spec:
},
"Type": "AWS::IAM::Role",
},
"cloudbustercloudbustercron309MONFRI0A90AE33E": {
"Properties": {
"ScheduleExpression": "cron(30 9 ? * MON-FRI *)",
"State": "ENABLED",
"Targets": [
{
"Arn": {
"Fn::GetAtt": [
"cloudbuster8C461939",
"Arn",
],
},
"Id": "Target0",
},
],
},
"Type": "AWS::Events::Rule",
},
"cloudbustercloudbustercron309MONFRI0AllowEventRuleServiceCataloguecloudbuster82FA89E4F5116C2E": {
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Fn::GetAtt": [
"cloudbuster8C461939",
"Arn",
],
},
"Principal": "events.amazonaws.com",
"SourceArn": {
"Fn::GetAtt": [
"cloudbustercloudbustercron309MONFRI0A90AE33E",
"Arn",
],
},
},
"Type": "AWS::Lambda::Permission",
},
"cloudqueryapikeyCCF82F53": {
"DeletionPolicy": "Delete",
"Properties": {
Expand Down
55 changes: 21 additions & 34 deletions packages/cdk/lib/cloudbuster.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { GuScheduledLambda } from '@guardian/cdk';
import type {
GuLambdaErrorPercentageMonitoringProps,
NoMonitoring,
} from '@guardian/cdk/lib/constructs/cloudwatch';
import type { GuStack } from '@guardian/cdk/lib/constructs/core';
import type { GuSecurityGroup } from '@guardian/cdk/lib/constructs/ec2';
import { GuLambdaFunction } from '@guardian/cdk/lib/constructs/lambda';
import { Duration } from 'aws-cdk-lib';
import type { IVpc } from 'aws-cdk-lib/aws-ec2';
// import { Rule, RuleTargetInput, Schedule } from 'aws-cdk-lib/aws-events';
// import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
import type { Schedule } from 'aws-cdk-lib/aws-events';
import { Architecture, LoggingFormat, Runtime } from 'aws-cdk-lib/aws-lambda';
import type { DatabaseInstance } from 'aws-cdk-lib/aws-rds';
import type { ITopic } from 'aws-cdk-lib/aws-sns';
Expand All @@ -14,14 +17,25 @@ type CloudBusterProps = {
dbAccess: GuSecurityGroup;
db: DatabaseInstance;
anghammaradTopic: ITopic;
monitoringConfiguration:
| NoMonitoring
| GuLambdaErrorPercentageMonitoringProps;
schedule: Schedule;
};

export class CloudBuster {
constructor(stack: GuStack, props: CloudBusterProps) {
const { vpc, dbAccess, db, anghammaradTopic } = props;
const {
vpc,
dbAccess,
db,
anghammaradTopic,
monitoringConfiguration,
schedule,
} = props;
const app = 'cloudbuster';

const lambda = new GuLambdaFunction(stack, 'cloudbuster', {
const lambda = new GuScheduledLambda(stack, 'cloudbuster', {
app,
vpc,
architecture: Architecture.ARM_64,
Expand All @@ -36,39 +50,12 @@ export class CloudBuster {
},
timeout: Duration.minutes(5),
memorySize: 1024,
errorPercentageMonitoring: {
toleratedErrorPercentage: 0,
snsTopicName: 'devx-alerts',
},
monitoringConfiguration,
loggingFormat: LoggingFormat.TEXT,
rules: [{ schedule }],
});

anghammaradTopic.grantPublish(lambda);

// new Rule(stack, `cloudbuster-critical`, {
// description: `Daily execution of the Cloudbuster lambda for critical findings`,
// schedule: Schedule.cron({ minute: '0', hour: '9' }),
// targets: [
// new LambdaFunction(lambda, {
// event: RuleTargetInput.fromObject({
// severities: ['CRITICAL'],
// }),
// }),
// ],
// });

// new Rule(stack, `cloudbuster-high`, {
// description: `Weekly execution of the Cloudbuster lambda for high findings`,
// schedule: Schedule.cron({ weekDay: 'TUE', hour: '9', minute: '0' }),
// targets: [
// new LambdaFunction(lambda, {
// event: RuleTargetInput.fromObject({
// severities: ['HIGH'],
// }),
// }),
// ],
// });

db.grantConnect(lambda, 'cloudbuster');
}
}
60 changes: 38 additions & 22 deletions packages/cdk/lib/service-catalogue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,35 @@ import { addPrismaMigrateTask } from './prisma-migrate-task';
import { addRefreshMaterializedViewLambda } from './refresh-materialized-view';
import { Repocop } from './repocop';

function createProdMonitoringConfiguration(
app: string,
): GuLambdaErrorPercentageMonitoringProps {
return {
toleratedErrorPercentage: 50,
lengthOfEvaluationPeriod: Duration.minutes(1),
numberOfEvaluationPeriodsAboveThresholdBeforeAlarm: 1,
snsTopicName: 'devx-alerts',
alarmDescription: `${app} error percentage is too high. Find the logs here ${getCentralElkLink(
{
filters: {
stage: 'PROD',
app,
},
},
)}`,
};
}

function createLambdaMonitoringConfiguration(
stage: string,
app: string,
): NoMonitoring | GuLambdaErrorPercentageMonitoringProps {
if (stage === 'PROD') {
return createProdMonitoringConfiguration(app);
} else {
return { noMonitoring: true };
}
}
interface ServiceCatalogueProps extends GuStackProps {
//TODO add fields for every kind of job to make schedule explicit at a glance.
//For code environments, data accuracy is not the main priority.
Expand Down Expand Up @@ -196,26 +225,6 @@ export class ServiceCatalogue extends GuStack {
const anghammaradTopicParameter =
GuAnghammaradTopicParameter.getInstance(this);

const repocopProdMonitoring: GuLambdaErrorPercentageMonitoringProps = {
toleratedErrorPercentage: 50,
lengthOfEvaluationPeriod: Duration.minutes(1),
numberOfEvaluationPeriodsAboveThresholdBeforeAlarm: 1,
snsTopicName: 'devx-alerts',
alarmDescription: `RepoCop error percentage is too high. Find the logs here ${getCentralElkLink(
{
filters: {
stage,
app: 'repocop',
},
},
)}`,
};

const repocopCodeMonitoring: NoMonitoring = { noMonitoring: true };

const repocopMonitoringConfiguration =
stage === 'PROD' ? repocopProdMonitoring : repocopCodeMonitoring;

const interactiveMonitor = new InteractiveMonitor(this, gitHubOrg);

const anghammaradTopic = Topic.fromTopicArn(
Expand All @@ -238,12 +247,14 @@ export class ServiceCatalogue extends GuStack {
minute: '30',
});

const securityAlertSchedule = nonProdSchedule ?? prodSchedule;

new Repocop(
this,
nonProdSchedule ?? prodSchedule,
securityAlertSchedule,
anghammaradTopic,
db,
repocopMonitoringConfiguration,
createLambdaMonitoringConfiguration(stage, 'repocop'),
vpc,
interactiveMonitor.topic,
applicationToPostgresSecurityGroup,
Expand Down Expand Up @@ -288,6 +299,11 @@ export class ServiceCatalogue extends GuStack {
db,
dbAccess: applicationToPostgresSecurityGroup,
anghammaradTopic,
monitoringConfiguration: createLambdaMonitoringConfiguration(
stage,
'cloudbuster',
),
schedule: securityAlertSchedule,
});
}
}

0 comments on commit 2c760d6

Please sign in to comment.