CloudWatch alarm missing for security group changes

Monitor changes to security groups and network access rules.

Description

Creating or deleting security groups and changing inbound or outbound rules can alter access to services. Monitor the relevant events to identify unauthorized changes or mistakes.

Potential impact

Without notifications, responding to unintended service exposure or blocked traffic may take longer.

Remediation

Create a log metric filter for security group creation or deletion and rule authorization or revocation events. Connect an alarm to the filter’s metric and configure notifications for the responsible team.

Examples

The examples correct the alarm to reference the metric emitted by the filter. Configure CloudTrail log delivery and notification recipients separately.

Before

hcl
resource "aws_cloudwatch_log_metric_filter" "example" {
  name           = "CIS-SecurityGroupChanges"
  pattern        = "{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup)}"
  log_group_name = aws_cloudwatch_log_group.CIS_CloudWatch_LogsGroup.name

  metric_transformation {
    name      = "CIS-SecurityGroupChanges"
    namespace = "CIS_Metric_Alarm_Namespace"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "example" {
  alarm_name          = "CIS-3.10-SecurityGroupChanges"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = "XXXX NOT YOUR FILTER XXXX"
  namespace           = "CIS_Metric_Alarm_Namespace"
  period              = "300"
  statistic           = "Sum"
  threshold           = "1"
}

After

hcl
resource "aws_cloudwatch_log_metric_filter" "example" {
  name           = "CIS-SecurityGroupChanges"
  pattern        = "{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup)}"
  log_group_name = aws_cloudwatch_log_group.CIS_CloudWatch_LogsGroup.name

  metric_transformation {
    name      = "CIS-SecurityGroupChanges"
    namespace = "CIS_Metric_Alarm_Namespace"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "example" {
  alarm_name          = "CIS-3.10-SecurityGroupChanges"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = aws_cloudwatch_log_metric_filter.example.id
  namespace           = "CIS_Metric_Alarm_Namespace"
  period              = "300"
  statistic           = "Sum"
  threshold           = "1"
}

References