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 # ThrottledRequests and SystemErrors are documented at dimensions # (TableName, Operation); CloudWatch also publishes the TableName-only # aggregate, which is what we alarm on here. Neither has emitted yet # (no throttle/5xx events to date), so the dimension was confirmed against # the AWS DynamoDB metrics reference rather than live data. AlertsTableThrottleAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: front-sla-alerts-throttled-requests AlarmDescription: front-sla-alerts DynamoDB table is throttling requests Namespace: AWS/DynamoDB MetricName: ThrottledRequests 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 AlertsTableSystemErrorsAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: front-sla-alerts-system-errors AlarmDescription: front-sla-alerts DynamoDB table returned HTTP 500 system errors Namespace: AWS/DynamoDB MetricName: SystemErrors 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