front-integrations/template.yaml
Adam Moussa 7dcd2d7ccc
Some checks failed
Deploy / deploy (push) Has been cancelled
Add CloudWatch alarm coverage for front-integrations (#11)
* Add CloudWatch alarm coverage for front-integrations

Both Lambdas and the front-sla-alerts table previously had zero alarm
coverage, so failures or runaway runs went unnoticed until someone
checked logs. Wire a standard alarm set to the shared site-alerts SNS
topic (ALARM-only, TreatMissingData notBreaching) per Wave 1 conventions.

- Lambda Errors + Throttles alarms for front-sla-monitor and
  front-user-sync (Sum, threshold 0).
- Lambda Duration alarms (Max, threshold 270000 = 90% of the shared
  300s timeout) for both functions.
- DynamoDB ThrottledRequests + SystemErrors alarms on front-sla-alerts.

Document the alarm set in the README.

* Fix DynamoDB throttle alarm metric: use Read/WriteThrottleEvents

ThrottledRequests and SystemErrors are not emitted at the TableName-only
dimension (only TableName+Operation), so these table-level alarms would sit
permanently in INSUFFICIENT_DATA and never fire. Replace with
ReadThrottleEvents and WriteThrottleEvents, which AWS/DynamoDB emits at the
TableName dimension.

* Fix README DynamoDB alarm rows to match shipped alarms

Replace stale front-sla-alerts-throttled-requests / -system-errors rows
with the alarms actually shipped: front-sla-alerts-read-throttle
(ReadThrottleEvents) and front-sla-alerts-write-throttle
(WriteThrottleEvents).
2026-06-17 14:45:58 -04:00

327 lines
11 KiB
YAML

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Front platform integrations — SLA monitoring and Google Workspace user sync
Parameters:
FrontApiTokenSecretArn:
Type: String
Description: ARN of the Secrets Manager secret containing the Front API token
SlackBotTokenSecretArn:
Type: String
Description: ARN of the Secrets Manager secret containing the Slack bot token
GoogleServiceAccountSecretArn:
Type: String
Description: ARN of the Secrets Manager secret containing the Google service account JSON key
SlackAlertChannel:
Type: String
Description: Slack channel ID for the front-sla-alerts channel
AdamEmail:
Type: String
Default: adam@seahavenind.com
Description: Email address for Tier 2 escalation
AckSlaMinutes:
Type: Number
Default: 60
Description: Business minutes before Tier 1 alert (1 hour)
ActionSlaMinutes:
Type: Number
Default: 1440
Description: Business minutes before Tier 2 alert (1 business day)
MonitorInboxes:
Type: String
Default: "Triage,California,West Coast,Central,East Coast,Vendors"
Description: Comma-separated inbox names to monitor (empty = all shared)
SlaMonitorStartDate:
Type: String
Default: "2026-05-14"
Description: Date when SLA monitoring begins (YYYY-MM-DD, Eastern time)
GoogleAdminEmail:
Type: String
Default: adam@seahavenind.com
Description: Google Workspace admin email to impersonate for Directory API
GoogleOrgUnits:
Type: String
Default: "/Office/Scheduling,/Office/Operations"
Description: Comma-separated Google Workspace org unit paths to sync
Globals:
Function:
Runtime: python3.12
Timeout: 300
MemorySize: 256
Architectures:
- arm64
PermissionsBoundary: arn:aws:iam::328440206208:policy/seahaven-lambda-execution-boundary
Resources:
# ---------------------------------------------------------------------------
# SLA Monitor
# ---------------------------------------------------------------------------
AlertsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: front-sla-alerts
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: conversationId
AttributeType: S
KeySchema:
- AttributeName: conversationId
KeyType: HASH
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
SlaMonitorLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/lambda/front-sla-monitor
RetentionInDays: 60
SlaMonitorFunction:
Type: AWS::Serverless::Function
DependsOn: SlaMonitorLogGroup
Properties:
FunctionName: front-sla-monitor
Handler: app.handler
CodeUri: src/sla_monitor/
Environment:
Variables:
FRONT_SECRET_NAME: !Ref FrontApiTokenSecretArn
SLACK_SECRET_NAME: !Ref SlackBotTokenSecretArn
SLACK_ALERT_CHANNEL: !Ref SlackAlertChannel
ADAM_EMAIL: !Ref AdamEmail
TABLE_NAME: !Ref AlertsTable
ACK_SLA_MINUTES: !Ref AckSlaMinutes
ACTION_SLA_MINUTES: !Ref ActionSlaMinutes
MONITOR_INBOXES: !Ref MonitorInboxes
START_DATE: !Ref SlaMonitorStartDate
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref AlertsTable
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
- !Ref FrontApiTokenSecretArn
- !Ref SlackBotTokenSecretArn
Events:
SlaCheck:
Type: Schedule
Properties:
Schedule: cron(0/15 12-22 ? * MON-FRI *)
Description: Check Front conversations for SLA breaches every 15 min during business hours
Enabled: true
# SLA Monitor alarms
SlaMonitorErrorsAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-sla-monitor-errors
AlarmDescription: front-sla-monitor invocation errors
Namespace: AWS/Lambda
MetricName: Errors
Dimensions:
- Name: FunctionName
Value: !Ref SlaMonitorFunction
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
SlaMonitorThrottlesAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-sla-monitor-throttles
AlarmDescription: front-sla-monitor invocations throttled
Namespace: AWS/Lambda
MetricName: Throttles
Dimensions:
- Name: FunctionName
Value: !Ref SlaMonitorFunction
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
SlaMonitorDurationAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-sla-monitor-duration
AlarmDescription: front-sla-monitor approaching its 300s timeout (>90%)
Namespace: AWS/Lambda
MetricName: Duration
Dimensions:
- Name: FunctionName
Value: !Ref SlaMonitorFunction
Statistic: Maximum
Period: 300
EvaluationPeriods: 1
Threshold: 270000
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
# DynamoDB alarms — front-sla-alerts table
# ReadThrottleEvents / WriteThrottleEvents are emitted at the TableName
# dimension, so these alarms transition normally. (ThrottledRequests and
# SystemErrors are only emitted at TableName+Operation granularity, never
# TableName-only, so alarms on them sit permanently in INSUFFICIENT_DATA
# and never fire — these are the correct table-level throttle signals.)
AlertsTableReadThrottleAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-sla-alerts-read-throttle
AlarmDescription: front-sla-alerts DynamoDB table had one or more read throttle events
Namespace: AWS/DynamoDB
MetricName: ReadThrottleEvents
Dimensions:
- Name: TableName
Value: !Ref AlertsTable
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
AlertsTableWriteThrottleAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-sla-alerts-write-throttle
AlarmDescription: front-sla-alerts DynamoDB table had one or more write throttle events
Namespace: AWS/DynamoDB
MetricName: WriteThrottleEvents
Dimensions:
- Name: TableName
Value: !Ref AlertsTable
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
# ---------------------------------------------------------------------------
# Google User Sync
# ---------------------------------------------------------------------------
UserSyncLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/lambda/front-user-sync
RetentionInDays: 60
UserSyncFunction:
Type: AWS::Serverless::Function
DependsOn: UserSyncLogGroup
Properties:
FunctionName: front-user-sync
Handler: app.handler
CodeUri: src/user_sync/
Timeout: 300
Environment:
Variables:
GOOGLE_SECRET_NAME: !Ref GoogleServiceAccountSecretArn
FRONT_SECRET_NAME: !Ref FrontApiTokenSecretArn
GOOGLE_ADMIN_EMAIL: !Ref GoogleAdminEmail
GOOGLE_OUS: !Ref GoogleOrgUnits
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
- !Ref GoogleServiceAccountSecretArn
- !Ref FrontApiTokenSecretArn
Events:
DailySync:
Type: Schedule
Properties:
Schedule: cron(0 11 ? * MON-FRI *)
Description: Sync Google Workspace user profiles to Front daily at 6 AM ET
Enabled: true
# User Sync alarms
UserSyncErrorsAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-user-sync-errors
AlarmDescription: front-user-sync invocation errors
Namespace: AWS/Lambda
MetricName: Errors
Dimensions:
- Name: FunctionName
Value: !Ref UserSyncFunction
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
UserSyncThrottlesAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-user-sync-throttles
AlarmDescription: front-user-sync invocations throttled
Namespace: AWS/Lambda
MetricName: Throttles
Dimensions:
- Name: FunctionName
Value: !Ref UserSyncFunction
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
UserSyncDurationAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: front-user-sync-duration
AlarmDescription: front-user-sync approaching its 300s timeout (>90%)
Namespace: AWS/Lambda
MetricName: Duration
Dimensions:
- Name: FunctionName
Value: !Ref UserSyncFunction
Statistic: Maximum
Period: 300
EvaluationPeriods: 1
Threshold: 270000
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:site-alerts
Outputs:
SlaMonitorFunctionArn:
Description: Front SLA Monitor Lambda ARN
Value: !GetAtt SlaMonitorFunction.Arn
UserSyncFunctionArn:
Description: Front User Sync Lambda ARN
Value: !GetAtt UserSyncFunction.Arn
AlertsTableName:
Description: DynamoDB alerts table name
Value: !Ref AlertsTable