Add ALARM-only CloudWatch alarms routed to the shared site-alerts SNS topic (imported once via Topic.fromTopicArn and injected into both constructs via props). All alarms use treatMissingData NOT_BREACHING and have no OK / InsufficientData actions, mirroring the proposal-system alarm construct. Lambda (fetch-classify, daily-digest, conversation): - Errors (Sum >= 1, eval 1) - Throttles (Sum >= 1, eval 1) - Duration (p99, eval 3 / datapoints 2, ~80% of timeout: 96000ms for the 120s fns, 144000ms for conversation's 180s) -- thresholds pending Adam sign-off. DynamoDB exec-aide table: - ThrottledRequests and SystemErrors. These metrics are NOT published at the bare TableName dimension (CDK's metricThrottledRequests / metricSystemErrors are deprecated as invalid); they are keyed by the Operation dimension. Used the *ForOperations math helpers scoped to the 6 operations this single-table app issues (GetItem/PutItem/Query/Scan/ UpdateItem/DeleteItem) to stay within the 10-metric math-expr cap. ECS exec-aide-listener Fargate service (AWS/ECS, no Container Insights): - CPU and Memory utilization (Average > 80%, eval 3 / datapoints 2). - Service assigned to a const (logical id 'Service' unchanged) so metrics can reference it. The RunningTaskCount alarm (requires Container Insights) is intentionally deferred to a separate sign-off-gated commit.
37 lines
1.3 KiB
TypeScript
37 lines
1.3 KiB
TypeScript
import * as cdk from 'aws-cdk-lib';
|
|
import * as sns from 'aws-cdk-lib/aws-sns';
|
|
import { Construct } from 'constructs';
|
|
import { EmailPipelineConstruct } from './constructs/email-pipeline';
|
|
import { SocketModeConstruct } from './constructs/socket-mode';
|
|
|
|
export class ExecAideStack extends cdk.Stack {
|
|
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
super(scope, id, props);
|
|
|
|
// Shared cross-stack site-alerts SNS topic for all CloudWatch ALARM actions.
|
|
// Managed by seahaven-account-baseline and encrypted with the
|
|
// alias/seahaven-alarm-topics CMK (CloudWatch cannot publish to topics using
|
|
// alias/aws/sns — silent failure). Imported ONCE here and injected into both
|
|
// constructs via props, the same way the DynamoDB table is wired through.
|
|
const alarmTopic = sns.Topic.fromTopicArn(
|
|
this,
|
|
'SiteAlerts',
|
|
`arn:aws:sns:${this.region}:${this.account}:site-alerts`,
|
|
);
|
|
|
|
const emailPipeline = new EmailPipelineConstruct(this, 'EmailPipeline', {
|
|
alarmTopic,
|
|
});
|
|
|
|
new SocketModeConstruct(this, 'SocketMode', {
|
|
table: emailPipeline.table,
|
|
conversationFnArn: emailPipeline.conversationFn.functionArn,
|
|
alarmTopic,
|
|
});
|
|
|
|
new cdk.CfnOutput(this, 'TableName', {
|
|
value: emailPipeline.table.tableName,
|
|
description: 'DynamoDB table name',
|
|
});
|
|
}
|
|
}
|