mirror of
https://github.com/Sea-Haven-Industries/seahaven-door-unlock-api.git
synced 2026-09-30 05:53:12 +00:00
Add CloudWatch Errors alarms to all door-unlock Lambdas (#34)
Physical access control has no error visibility — a Lambda failure could leave unlock/lockdown/authorizer silently broken. Add ALARM-only Errors alarms (Sum > 0, 5-min period, NOT_BREACHING) for all four Lambdas, routed to the cross-stack site-alerts SNS topic encrypted with alias/seahaven-alarm-topics. No OK/recovery actions per org convention. Refs: INFRA-101
This commit is contained in:
parent
4265ad90fe
commit
86f078de72
1 changed files with 66 additions and 0 deletions
|
|
@ -12,6 +12,9 @@ import * as route53 from "aws-cdk-lib/aws-route53";
|
|||
import * as route53Targets from "aws-cdk-lib/aws-route53-targets";
|
||||
import * as acm from "aws-cdk-lib/aws-certificatemanager";
|
||||
import * as logs from "aws-cdk-lib/aws-logs";
|
||||
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
|
||||
import * as cwactions from "aws-cdk-lib/aws-cloudwatch-actions";
|
||||
import * as sns from "aws-cdk-lib/aws-sns";
|
||||
import { Construct } from "constructs";
|
||||
import * as path from "path";
|
||||
|
||||
|
|
@ -329,5 +332,68 @@ export class DoorUnlockStack extends cdk.Stack {
|
|||
new cdk.CfnOutput(this, "LockdownApiUrl", {
|
||||
value: `https://doorunlock.seahaven.com/lockdown`,
|
||||
});
|
||||
|
||||
// ── CloudWatch error alarms (INFRA-101) ──────────────────────────────────
|
||||
// Import the cross-stack site-alerts SNS topic. This topic is managed by
|
||||
// seahaven-account-baseline and encrypted with alias/seahaven-alarm-topics
|
||||
// (CMK). Never use alias/aws/sns here — CloudWatch cannot publish to topics
|
||||
// using the AWS-managed SNS key (silent publish failure).
|
||||
// ALARM state only; no OK/recovery actions per Sea Haven preference.
|
||||
const siteAlerts = sns.Topic.fromTopicArn(
|
||||
this,
|
||||
"SiteAlerts",
|
||||
"arn:aws:sns:us-east-1:328440206208:site-alerts"
|
||||
);
|
||||
|
||||
interface AlarmSpec {
|
||||
readonly id: string;
|
||||
readonly fn: lambda.Function;
|
||||
readonly alarmName: string;
|
||||
readonly description: string;
|
||||
}
|
||||
|
||||
const alarmSpecs: AlarmSpec[] = [
|
||||
{
|
||||
id: "UnlockErrors",
|
||||
fn: unlockHandler,
|
||||
alarmName: "door-unlock-api-unlock-errors",
|
||||
description: "door-unlock-api-unlock Lambda is erroring — physical door unlock calls may be failing",
|
||||
},
|
||||
{
|
||||
id: "LockdownErrors",
|
||||
fn: lockdownHandler,
|
||||
alarmName: "door-unlock-api-lockdown-errors",
|
||||
description: "door-unlock-api-lockdown Lambda is erroring — lockdown commands may not be executing",
|
||||
},
|
||||
{
|
||||
id: "AuthorizerErrors",
|
||||
fn: authorizerHandler,
|
||||
alarmName: "door-unlock-api-authorizer-errors",
|
||||
description: "door-unlock-api-authorizer Lambda is erroring — all API requests will be rejected",
|
||||
},
|
||||
{
|
||||
id: "PollerErrors",
|
||||
fn: pollerHandler,
|
||||
alarmName: "door-unlock-api-lockdown-poller-errors",
|
||||
description: "door-unlock-api-lockdown-poller Lambda is erroring — lockdown state polling may be broken",
|
||||
},
|
||||
];
|
||||
|
||||
for (const spec of alarmSpecs) {
|
||||
const alarm = new cloudwatch.Alarm(this, spec.id, {
|
||||
alarmName: spec.alarmName,
|
||||
alarmDescription: spec.description,
|
||||
metric: spec.fn.metricErrors({
|
||||
period: cdk.Duration.minutes(5),
|
||||
statistic: "Sum",
|
||||
}),
|
||||
threshold: 0,
|
||||
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
||||
evaluationPeriods: 1,
|
||||
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
|
||||
});
|
||||
// ALARM-only: addAlarmAction only (no addOkAction / addInsufficientDataAction)
|
||||
alarm.addAlarmAction(new cwactions.SnsAction(siteAlerts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue