22# Written by Marc Straubinger - Overhauled for Security-First Best Practices
33
44# SNS Topic for CloudWatch Alarms
5- # PSA Compliance: Req 3.50-01 (Encryption)
65resource "aws_sns_topic" "cloudwatch_alarms" {
7- name = " ${ var . name_prefix } -cloudwatch-alarms"
6+ name = " ${ local . name_prefix } -cloudwatch-alarms"
87 kms_master_key_id = var. enable_sns_encryption ? var. sns_kms_key_id : null
98
10- tags = merge (var . tags , {
11- " Name" = " ${ var . name_prefix } -cloudwatch-alarms"
9+ tags = merge (local . common_tags , {
10+ " Name" = " ${ local . name_prefix } -cloudwatch-alarms"
1211 " PSA-Compliant" = " true"
1312 })
1413}
@@ -66,10 +65,11 @@ resource "aws_sns_topic_subscription" "email" {
6665}
6766
6867# CloudWatch Alarms for EC2 Instances
68+ # PSA Compliance: Req 8 (monitoring and alerting)
6969resource "aws_cloudwatch_metric_alarm" "ec2_high_cpu" {
7070 for_each = toset (var. ec2_instance_ids )
7171
72- alarm_name = " ${ var . name_prefix } -ec2-${ each . key } -high-cpu"
72+ alarm_name = " ${ local . name_prefix } -ec2-${ each . key } -high-cpu"
7373 comparison_operator = " GreaterThanThreshold"
7474 evaluation_periods = var. alarm_evaluation_periods
7575 datapoints_to_alarm = var. alarm_datapoints_to_alarm
@@ -87,47 +87,77 @@ resource "aws_cloudwatch_metric_alarm" "ec2_high_cpu" {
8787 insufficient_data_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
8888 ok_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
8989
90- tags = merge (var. tags , {
91- " Name" = " ${ var . name_prefix } -ec2-${ each . key } -high-cpu"
90+ tags = merge (local. common_tags , {
91+ " Name" = " ${ local . name_prefix } -ec2-${ each . key } -high-cpu"
92+ " PSA-Compliant" = " true"
93+ })
94+ }
95+
96+ # PSA Compliance: Req 8 (monitoring and alerting)
97+ resource "aws_cloudwatch_metric_alarm" "ec2_low_cpu" {
98+ for_each = toset (var. ec2_instance_ids )
99+
100+ alarm_name = " ${ local . name_prefix } -ec2-${ each . key } -low-cpu"
101+ comparison_operator = " LessThanThreshold"
102+ evaluation_periods = var. alarm_evaluation_periods
103+ datapoints_to_alarm = var. alarm_datapoints_to_alarm
104+ metric_name = " CPUUtilization"
105+ namespace = " AWS/EC2"
106+ period = var. alarm_period
107+ statistic = " Average"
108+ threshold = var. ec2_low_cpu_threshold
109+ alarm_description = " EC2 instance ${ each . key } low CPU utilization"
110+ dimensions = {
111+ InstanceId = each.key
112+ }
113+
114+ alarm_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
115+ insufficient_data_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
116+ ok_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
117+
118+ tags = merge (local. common_tags , {
119+ " Name" = " ${ local . name_prefix } -ec2-${ each . key } -low-cpu"
92120 " PSA-Compliant" = " true"
93121 })
94122}
95123
96124# Custom Metric Alarms
125+ # PSA Compliance: Req 8 (monitoring and alerting)
97126resource "aws_cloudwatch_metric_alarm" "custom" {
98127 for_each = var. custom_metrics
99128
100- alarm_name = " ${ var . name_prefix } -custom-${ each . key } "
129+ alarm_name = " ${ local . name_prefix } -custom-${ each . key } "
101130 comparison_operator = each. value . comparison_operator
102131 evaluation_periods = each. value . evaluation_periods
132+ datapoints_to_alarm = try (each. value . datapoints_to_alarm , var. alarm_datapoints_to_alarm )
103133 metric_name = each. value . metric_name
104134 namespace = each. value . namespace
105135 period = each. value . period
106136 statistic = each. value . statistic
107137 threshold = each. value . threshold
108- alarm_description = each. value . description
138+ alarm_description = each. value . description != " " ? each . value . description : " Custom alarm for ${ each . key } "
109139 dimensions = each. value . dimensions
110140
111141 alarm_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
112142 insufficient_data_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
113143 ok_actions = [aws_sns_topic . cloudwatch_alarms . arn ]
114144
115- tags = merge (var . tags , {
116- " Name" = " ${ var . name_prefix } -custom-${ each . key } "
145+ tags = merge (local . common_tags , {
146+ " Name" = " ${ local . name_prefix } -custom-${ each . key } "
117147 " PSA-Compliant" = " true"
118148 })
119149}
120150
121151# CloudWatch Logs Group
122- # PSA Compliance: Req 3.66-05 (Logging obligatory with encryption )
152+ # PSA Compliance: Req 1 (audit logging )
123153resource "aws_cloudwatch_log_group" "application_logs" {
124154 count = var. enable_application_logs ? 1 : 0
125- name = " /aws/app/${ var . name_prefix } /logs"
155+ name = " /aws/app/${ local . name_prefix } /logs"
126156 retention_in_days = var. log_retention_days
127157 kms_key_id = var. log_group_kms_key_id
128158
129- tags = merge (var . tags , {
130- " Name" = " ${ var . name_prefix } -application-logs"
159+ tags = merge (local . common_tags , {
160+ " Name" = " ${ local . name_prefix } -application-logs"
131161 " PSA-Compliant" = " true"
132162 })
133163}
0 commit comments