1- from aws_cdk import Duration , aws_apigateway
1+ import aws_cdk .aws_sns as sns
2+ from aws_cdk import Duration , aws_apigateway , CfnOutput
23from aws_cdk import aws_dynamodb as dynamodb
34from aws_cdk import aws_lambda as _lambda
4- from cdk_monitoring_constructs import CustomMetricGroup , ErrorRateThreshold , LatencyThreshold , MetricStatistic , MonitoringFacade
5+ from cdk_monitoring_constructs import (
6+ AlarmFactoryDefaults ,
7+ CustomMetricGroup ,
8+ ErrorRateThreshold ,
9+ LatencyThreshold ,
10+ MetricStatistic ,
11+ MonitoringFacade ,
12+ SnsAlarmActionStrategy ,
13+ )
14+ from aws_cdk import aws_kms as kms
515from constructs import Construct
6-
16+ from aws_cdk import aws_iam as iam
717from cdk .service import constants
818
919
@@ -20,11 +30,39 @@ def __init__(
2030 ) -> None :
2131 super ().__init__ (scope , id_ )
2232 self .id_ = id_
23- self ._build_high_level_dashboard (crud_api )
24- self ._build_low_level_dashboard (db , idempotency_table , functions )
33+ self .notification_topic = self ._build_topic ()
34+ self ._build_high_level_dashboard (crud_api , self .notification_topic )
35+ self ._build_low_level_dashboard (db , idempotency_table , functions , self .notification_topic )
36+
37+ def _build_topic (self ) -> sns .Topic :
38+ key = kms .Key (
39+ self ,
40+ 'MyKey' ,
41+ description = 'KMS Key for SNS Topic Encryption' ,
42+ enable_key_rotation = True # Enables automatic key rotation
43+ )
44+ topic = sns .Topic (self , f'{ self .id_ } alarms' , display_name = f'{ self .id_ } alarms' , master_key = key )
45+ # Grant CloudWatch permissions to publish to the SNS topic
46+ topic .add_to_resource_policy (
47+ statement = iam .PolicyStatement (
48+ actions = ['sns:Publish' ],
49+ effect = iam .Effect .ALLOW ,
50+ principals = [iam .ServicePrincipal ('cloudwatch.amazonaws.com' )],
51+ resources = [topic .topic_arn ],
52+ ))
53+ CfnOutput (self , id = constants .MONITORING_TOPIC , value = topic .topic_name ).override_logical_id (constants .MONITORING_TOPIC )
54+ return topic
2555
26- def _build_high_level_dashboard (self , crud_api : aws_apigateway .RestApi ):
27- high_level_facade = MonitoringFacade (self , f'{ self .id_ } HighFacade' )
56+ def _build_high_level_dashboard (self , crud_api : aws_apigateway .RestApi , topic : sns .Topic ):
57+ high_level_facade = MonitoringFacade (
58+ self ,
59+ f'{ self .id_ } HighFacade' ,
60+ alarm_factory_defaults = AlarmFactoryDefaults (
61+ actions_enabled = True ,
62+ alarm_name_prefix = self .id_ ,
63+ action = SnsAlarmActionStrategy (on_alarm_topic = topic ),
64+ ),
65+ )
2866 high_level_facade .add_large_header ('Order REST API High Level Dashboard' )
2967 high_level_facade .monitor_api_gateway (
3068 api = crud_api ,
@@ -43,8 +81,16 @@ def _build_high_level_dashboard(self, crud_api: aws_apigateway.RestApi):
4381 group = CustomMetricGroup (metrics = [create_metric ], title = 'Daily Order Requests' )
4482 high_level_facade .monitor_custom (metric_groups = [group ], human_readable_name = 'Daily KPIs' , alarm_friendly_name = 'KPIs' )
4583
46- def _build_low_level_dashboard (self , db : dynamodb .Table , idempotency_table : dynamodb .Table , functions : list [_lambda .Function ]):
47- low_level_facade = MonitoringFacade (self , f'{ self .id_ } LowFacade' )
84+ def _build_low_level_dashboard (self , db : dynamodb .Table , idempotency_table : dynamodb .Table , functions : list [_lambda .Function ], topic : sns .Topic ):
85+ low_level_facade = MonitoringFacade (
86+ self ,
87+ f'{ self .id_ } LowFacade' ,
88+ alarm_factory_defaults = AlarmFactoryDefaults (
89+ actions_enabled = True ,
90+ alarm_name_prefix = self .id_ ,
91+ action = SnsAlarmActionStrategy (on_alarm_topic = topic ),
92+ ),
93+ )
4894 low_level_facade .add_large_header ('Orders REST API Low Level Dashboard' )
4995 for func in functions :
5096 low_level_facade .monitor_lambda_function (
0 commit comments