Compare commits

..

No commits in common. "b75b4cc130c09f8b7d065bafaed0d4fe5e5bf86d" and "f6b105a9fd9d5e42a535f046b0861b03c1c8eee1" have entirely different histories.

3 changed files with 40 additions and 64 deletions

View file

@ -1,7 +1,5 @@
import * as cdk from "aws-cdk-lib";
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
import * as cloudwatch_actions from "aws-cdk-lib/aws-cloudwatch-actions";
import * as sns from "aws-cdk-lib/aws-sns";
import * as events from "aws-cdk-lib/aws-events";
import * as events_targets from "aws-cdk-lib/aws-events-targets";
import * as iam from "aws-cdk-lib/aws-iam";
@ -101,48 +99,15 @@ export class BackupVerification extends Construct {
],
});
// Errors alarm: only fires when the function actually runs and errors.
// The function runs once daily, so for ~23h there is no data. Treating
// missing data as BREACHING flipped this alarm OK->ALARM every day around
// 11:01 UTC even though no error ever occurred. NOT_BREACHING means "no
// data = no errors = healthy"; the separate not-running alarm below covers
// the "verification never ran" case.
// Org operational alarm topic (site-alerts, CMK-encrypted — never
// alias/aws/sns, which CloudWatch cannot publish to). Alarm action only,
// no OK action, per org convention.
const alertTopic = sns.Topic.fromTopicArn(
this,
"AlertTopic",
"arn:aws:sns:us-east-1:328440206208:site-alerts"
);
const errorAlarm = new cloudwatch.Alarm(this, "ErrorAlarm", {
new cloudwatch.Alarm(this, "ErrorAlarm", {
alarmName: "forgejo-backup-verification-errors",
alarmDescription: "Backup verification Lambda is failing — Slack notifications may not be firing",
metric: fn.metricErrors({ period: cdk.Duration.hours(1) }),
threshold: 1,
evaluationPeriods: 1,
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
treatMissingData: cloudwatch.TreatMissingData.BREACHING,
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
});
errorAlarm.addAlarmAction(new cloudwatch_actions.SnsAction(alertTopic));
// Not-running alarm: fires if the daily verification did not invoke at all
// in a 24h window. This is the real "missing run" guard that the errors
// alarm's BREACHING setting was previously (and incorrectly) providing.
const notRunningAlarm = new cloudwatch.Alarm(this, "NotRunningAlarm", {
alarmName: "forgejo-backup-verification-not-running",
alarmDescription: "Backup verification Lambda has not run in the last 24h — daily verification may be broken",
metric: fn.metricInvocations({
period: cdk.Duration.hours(24),
statistic: cloudwatch.Stats.SUM,
}),
threshold: 1,
evaluationPeriods: 1,
treatMissingData: cloudwatch.TreatMissingData.BREACHING,
comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD,
});
notRunningAlarm.addAlarmAction(new cloudwatch_actions.SnsAction(alertTopic));
this.functionArn = fn.functionArn;
}

63
package-lock.json generated
View file

@ -9,7 +9,7 @@
"version": "1.0.0",
"dependencies": {
"@aws-cdk/aws-lambda-python-alpha": "2.257.0-alpha.0",
"aws-cdk-lib": "2.258.0",
"aws-cdk-lib": "2.257.0",
"constructs": "^10.0.0"
},
"bin": {
@ -23,9 +23,9 @@
}
},
"node_modules/@aws-cdk/asset-awscli-v1": {
"version": "2.2.282",
"resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.282.tgz",
"integrity": "sha512-7hKMi5tTxDcKGIMIOq14PnY0GBcugW33Uh/2YHDZiEwSxLeFOCYBwhR+BFXONb/EJeVI3RETFgailNZbkcKF6g==",
"version": "2.2.273",
"resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.273.tgz",
"integrity": "sha512-X57HYUtHt9BQrlrzUNcMyRsDUCoakYNnY6qh5lNwRCHPtQoTfXmuISkfLk0AjLkcbS5lw1LLTQFiQhTDXfiTvg==",
"license": "Apache-2.0"
},
"node_modules/@aws-cdk/asset-node-proxy-agent-v6": {
@ -48,9 +48,9 @@
}
},
"node_modules/@aws-cdk/cloud-assembly-schema": {
"version": "54.2.0",
"resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-54.2.0.tgz",
"integrity": "sha512-u3lFXmiXSBozxGBmKTCVD/2mTDsaXzLZH3KYiIQKcB+zPldXOeE5TnooBgKV9ih2jVTo8ML0HpkhfAq2eiv0eQ==",
"version": "53.28.0",
"resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-53.28.0.tgz",
"integrity": "sha512-pZS+9bLGv2tCqcgxfA0WD3XjcqT3yE4ICvKeJEicw6aTdCxBl8FQ/AUsorY/6f2JrMS3kUQgvhXxA30MWcji0A==",
"bundleDependencies": [
"jsonschema",
"semver"
@ -58,7 +58,7 @@
"license": "Apache-2.0",
"dependencies": {
"jsonschema": "^1.5.0",
"semver": "^7.8.1"
"semver": "^7.8.0"
},
"engines": {
"node": ">= 18.0.0"
@ -73,7 +73,7 @@
}
},
"node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": {
"version": "7.8.1",
"version": "7.8.0",
"inBundle": true,
"license": "ISC",
"bin": {
@ -107,9 +107,9 @@
}
},
"node_modules/aws-cdk-lib": {
"version": "2.258.0",
"resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.258.0.tgz",
"integrity": "sha512-OfFfg30ikBRJ3dimlzsWhPIrj6qug1p2XYsdB38CtMtcur7SufzoUczgI6kWjbQkOVcQgYzhzN29DErV0yZG7A==",
"version": "2.257.0",
"resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.257.0.tgz",
"integrity": "sha512-GoHfWklrBJcMwLtDlY64pvaT7cD2KyDXC8sik89DR6jHl6nQsBtYTKSJCM+C/k4jgXaecbv8myNX75FySejq0A==",
"bundleDependencies": [
"@balena/dockerignore",
"@aws-cdk/cloud-assembly-api",
@ -126,19 +126,19 @@
],
"license": "Apache-2.0",
"dependencies": {
"@aws-cdk/asset-awscli-v1": "2.2.282",
"@aws-cdk/asset-node-proxy-agent-v6": "^2.1.2",
"@aws-cdk/cloud-assembly-api": "^2.2.5",
"@aws-cdk/cloud-assembly-schema": "^54.0.0",
"@aws-cdk/asset-awscli-v1": "2.2.273",
"@aws-cdk/asset-node-proxy-agent-v6": "^2.1.1",
"@aws-cdk/cloud-assembly-api": "^2.2.4",
"@aws-cdk/cloud-assembly-schema": "^53.25.0",
"@balena/dockerignore": "^1.0.2",
"case": "1.6.3",
"fs-extra": "^11.3.5",
"fs-extra": "^11.3.3",
"ignore": "^5.3.2",
"jsonschema": "^1.5.0",
"mime-types": "^2.1.35",
"minimatch": "^10.2.5",
"minimatch": "^10.2.3",
"punycode": "^2.3.1",
"semver": "^7.8.1",
"semver": "^7.7.4",
"table": "^6.9.0",
"yaml": "1.10.3"
},
@ -150,7 +150,7 @@
}
},
"node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api": {
"version": "2.2.5",
"version": "2.2.4",
"inBundle": true,
"license": "Apache-2.0",
"dependencies": {
@ -161,7 +161,18 @@
"node": ">= 18.0.0"
},
"peerDependencies": {
"@aws-cdk/cloud-assembly-schema": ">=53.28.0"
"@aws-cdk/cloud-assembly-schema": ">=53.25.0"
}
},
"node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api/node_modules/semver": {
"version": "7.8.0",
"inBundle": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": {
@ -170,7 +181,7 @@
"license": "Apache-2.0"
},
"node_modules/aws-cdk-lib/node_modules/ajv": {
"version": "8.20.0",
"version": "8.18.0",
"inBundle": true,
"license": "MIT",
"dependencies": {
@ -223,7 +234,7 @@
}
},
"node_modules/aws-cdk-lib/node_modules/brace-expansion": {
"version": "5.0.6",
"version": "5.0.5",
"inBundle": true,
"license": "MIT",
"dependencies": {
@ -283,7 +294,7 @@
"license": "BSD-3-Clause"
},
"node_modules/aws-cdk-lib/node_modules/fs-extra": {
"version": "11.3.5",
"version": "11.3.3",
"inBundle": true,
"license": "MIT",
"dependencies": {
@ -322,7 +333,7 @@
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/jsonfile": {
"version": "6.2.1",
"version": "6.2.0",
"inBundle": true,
"license": "MIT",
"dependencies": {
@ -395,7 +406,7 @@
}
},
"node_modules/aws-cdk-lib/node_modules/semver": {
"version": "7.8.1",
"version": "7.7.4",
"inBundle": true,
"license": "ISC",
"bin": {

View file

@ -19,7 +19,7 @@
},
"dependencies": {
"@aws-cdk/aws-lambda-python-alpha": "2.257.0-alpha.0",
"aws-cdk-lib": "2.258.0",
"aws-cdk-lib": "2.257.0",
"constructs": "^10.0.0"
}
}