diff --git a/_outputs.tf b/_outputs.tf index 4611bfa..7f87ee2 100644 --- a/_outputs.tf +++ b/_outputs.tf @@ -2,3 +2,8 @@ output "lambda_arn" { description = "The ARN from lambda custom message" value = aws_lambda_function.lambda[*].arn } + +output "alarm_sns_topic" { + value = aws_sns_topic.alarms[0].arn # Output the ARN of the SNS topic created in the module + description = "SNS Topic ARN for CloudTrail Alarms" +} \ No newline at end of file diff --git a/_variables.tf b/_variables.tf index 5b5f4cb..81b7287 100644 --- a/_variables.tf +++ b/_variables.tf @@ -31,6 +31,11 @@ variable "endpoints" { default = [] type = list(string) } + +variable "alarm_sns_topic_arn" { + default = [] + type = list(string) +} variable "alarm_protocol" { default = "email" type = string diff --git a/aws-alarms.tf b/aws-alarms.tf index 1b8d335..2f93349 100644 --- a/aws-alarms.tf +++ b/aws-alarms.tf @@ -1,18 +1,512 @@ +locals { + resource_tags = merge(var.tags, { "Automation" = "Terraform" }) +} + +resource "aws_cloudwatch_log_metric_filter" "unauthorized_api_calls" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "UnauthorizedAPICalls" + pattern = "{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "UnauthorizedAPICalls" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "unauthorized_api_calls" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "UnauthorizedAPICalls" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.unauthorized_api_calls[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "10" + alarm_description = "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "no_mfa_console_signin_assumed_role" { + count = var.alarm_mode == "full" || var.alarm_mode == "light" ? 1 : 0 + + name = "NoMFAConsoleSigninAssume" + pattern = "{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "NoMFAConsoleSigninAssume" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "no_mfa_console_signin_assumed_role" { + count = var.alarm_mode == "full" || var.alarm_mode == "light" ? 1 : 0 + + alarm_name = "NoMFAConsoleSigninAssume" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.no_mfa_console_signin_assumed_role[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} +resource "aws_cloudwatch_log_metric_filter" "no_mfa_console_signin_no_assumed_role" { + count = var.alarm_mode == "full" || var.alarm_mode == "light" ? 1 : 0 + + name = "NoMFAConsoleSignin" + pattern = "{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ($.userIdentity.arn != \"*assumed-role*\") }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "NoMFAConsoleSignin" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "no_mfa_console_signin" { + count = var.alarm_mode == "full" || var.alarm_mode == "light" ? 1 : 0 + + alarm_name = "NoMFAConsoleSignin" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.no_mfa_console_signin_no_assumed_role[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "root_usage" { + count = var.alarm_mode == "full" || var.alarm_mode == "light" ? 1 : 0 + + name = "RootUsage" + pattern = "{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "RootUsage" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "root_usage" { + count = var.alarm_mode == "full" || var.alarm_mode == "light" ? 1 : 0 + + alarm_name = "RootUsage" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.root_usage[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring for root account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "iam_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "IAMChanges" + pattern = "{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "IAMChanges" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "iam_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "IAMChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.iam_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "cloudtrail_cfg_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "CloudTrailCfgChanges" + pattern = "{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "CloudTrailCfgChanges" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "cloudtrail_cfg_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "CloudTrailCfgChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.cloudtrail_cfg_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "console_signin_failures" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "ConsoleSigninFailures" + pattern = "{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "ConsoleSigninFailures" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "console_signin_failures" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "ConsoleSigninFailures" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.console_signin_failures[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "disable_or_delete_cmk" { + count = var.alarm_mode == "full" ? 1 : 0 -resource "random_string" "cloudtrail_alarm_suffix" { - length = 8 - special = false - lower = true - upper = false - numeric = false + name = "DisableOrDeleteCMK" + pattern = "{ ($.eventSource = kms.amazonaws.com) && (($.eventName = DisableKey) || ($.eventName = ScheduleKeyDeletion)) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "DisableOrDeleteCMK" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "disable_or_delete_cmk" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "DisableOrDeleteCMK" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.disable_or_delete_cmk[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Data encrypted with disabled or deleted keys will no longer be accessible." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "s3_bucket_policy_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "S3BucketPolicyChanges" + pattern = "{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "S3BucketPolicyChanges" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "s3_bucket_policy_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "S3BucketPolicyChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.s3_bucket_policy_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "aws_config_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "AWSConfigChanges" + pattern = "{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "AWSConfigChanges" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "aws_config_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "AWSConfigChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.aws_config_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "security_group_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "SecurityGroupChanges" + pattern = "{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup)}" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "SecurityGroupChanges" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "security_group_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "SecurityGroupChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.security_group_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "nacl_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "NACLChanges" + pattern = "{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "NACLChanges" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "nacl_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "NACLChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.nacl_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "network_gw_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "NetworkGWChanges" + pattern = "{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "NetworkGWChanges" + namespace = "CloudTrailMetrics" + value = "1" + } +} + +resource "aws_cloudwatch_metric_alarm" "network_gw_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "NetworkGWChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.network_gw_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "route_table_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "RouteTableChanges" + pattern = "{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "RouteTableChanges" + namespace = "CloudTrailMetrics" + value = "1" + } } -resource "aws_cloudformation_stack" "cloudtrail_alarm" { - name = "cloudtrail-alarm-${random_string.cloudtrail_alarm_suffix.result}" - template_body = var.alarm_mode == "full" ? file("${path.module}/cloudtrail-alarms-full.cf.json") : file("${path.module}/cloudtrail-alarms-light.cf.yml") +resource "aws_cloudwatch_metric_alarm" "route_table_changes" { + count = var.alarm_mode == "full" ? 1 : 0 - parameters = { - CloudTrailLogGroupName = var.cloudtrail_log_group_name - AlarmNotificationTopic = length(var.alarm_notification_sns_topic) > 0 ? var.alarm_notification_sns_topic : try(aws_sns_topic.alarms[0].arn, "") + alarm_name = "RouteTableChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.route_table_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} + +resource "aws_cloudwatch_log_metric_filter" "vpc_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + name = "VPCChanges" + pattern = "{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }" + log_group_name = var.cloudtrail_log_group_name + + metric_transformation { + name = "VPCChanges" + namespace = "CloudTrailMetrics" + value = "1" } } + +resource "aws_cloudwatch_metric_alarm" "vpc_changes" { + count = var.alarm_mode == "full" ? 1 : 0 + + alarm_name = "VPCChanges" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = aws_cloudwatch_log_metric_filter.vpc_changes[0].id + namespace = "CloudTrailMetrics" + period = "300" + statistic = "Sum" + threshold = "1" + alarm_description = "Monitoring changes to VPC will help ensure that all VPC traffic flows through an expected path." + alarm_actions = try([aws_sns_topic.alarms[0].arn], []) + ok_actions = try([aws_sns_topic.alarms[0].arn], []) + treat_missing_data = "notBreaching" + insufficient_data_actions = [] + + tags = local.resource_tags +} \ No newline at end of file diff --git a/cloudtrail-alarms-full.cf.json b/cloudtrail-alarms-full.cf.json deleted file mode 100644 index 8281859..0000000 --- a/cloudtrail-alarms-full.cf.json +++ /dev/null @@ -1,546 +0,0 @@ -{ - "AWSTemplateFormatVersion" : "2010-09-09", - "Description" : "AWS CloudTrail API Activity Alarm Template for CloudWatch Logs", - "Parameters" : { - "CloudTrailLogGroupName" : { - "Type" : "String", - "Default" : "CloudTrail/DefaultLogGroup", - "Description" : "Enter CloudWatch Logs log group name. Default is CloudTrail/DefaultLogGroup" - }, - "AlarmNotificationTopic" : { - "Type": "String", - "Description": "SNS Notification Topic to send alarms to" - } - }, - "Conditions": { - "HasAlarmNotificationTopic": { - "Fn::Not": [{ "Fn::Equals": [{ "Ref": "AlarmNotificationTopic" }, ""] }] - } - }, - "Resources" : { - "SecurityGroupChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "SecurityGroupEventCount", - "MetricValue": "1" - } - ] - } - }, - "SecurityGroupChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailSecurityGroupChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Security Group.", - "MetricName" : "SecurityGroupEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "NetworkAclChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "NetworkAclEventCount", - "MetricValue": "1" - } - ] - } - }, - "NetworkAclChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailNetworkAclChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Network ACL.", - "MetricName" : "NetworkAclEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "GatewayChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "GatewayEventCount", - "MetricValue": "1" - } - ] - } - }, - "GatewayChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailGatewayChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Customer or Internet Gateway.", - "MetricName" : "GatewayEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "VpcChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "VpcEventCount", - "MetricValue": "1" - } - ] - } - }, - "VpcChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailVpcChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, update or delete a VPC, VPC peering connection or VPC connection to classic.", - "MetricName" : "VpcEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "EC2InstanceChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = RunInstances) || ($.eventName = RebootInstances) || ($.eventName = StartInstances) || ($.eventName = StopInstances) || ($.eventName = TerminateInstances) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "EC2InstanceEventCount", - "MetricValue": "1" - } - ] - } - }, - "EC2InstanceChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailEC2InstanceChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, terminate, start, stop or reboot an EC2 instance.", - "MetricName" : "EC2InstanceEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "EC2LargeInstanceChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = RunInstances) && (($.requestParameters.instanceType = *.8xlarge) || ($.requestParameters.instanceType = *.4xlarge)) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "EC2LargeInstanceEventCount", - "MetricValue": "1" - } - ] - } - }, - "EC2LargeInstanceChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailEC2LargeInstanceChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, terminate, start, stop or reboot a 4x or 8x-large EC2 instance.", - "MetricName" : "EC2LargeInstanceEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "CloudTrailChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "CloudTrailEventCount", - "MetricValue": "1" - } - ] - } - }, - "CloudTrailChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, update or delete a CloudTrail trail, or to start or stop logging to a trail.", - "MetricName" : "CloudTrailEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - - "ConsoleSignInFailuresMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "ConsoleSignInFailureCount", - "MetricValue": "1" - } - ] - } - }, - "ConsoleSignInFailuresAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailConsoleSignInFailuresV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an unauthenticated API call is made to sign into the console.", - "MetricName" : "ConsoleSignInFailureCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "3" - } - }, - - "AuthorizationFailuresMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "AuthorizationFailureCount", - "MetricValue": "1" - } - ] - } - }, - "AuthorizationFailuresAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailAuthorizationFailuresV2", - "AlarmDescription" : "Alarms when an unauthorized API call is made.", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "MetricName" : "AuthorizationFailureCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "5" - - } - }, - - "IAMPolicyChangesMetricFilter": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "IAMPolicyEventCount", - "MetricValue": "1" - } - ] - } - }, - "IAMPolicyChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailIAMPolicyChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to change an IAM policy.", - "MetricName" : "IAMPolicyEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "RouteTableConfigChanges": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "RouteTableEventCount", - "MetricValue": "1" - } - ] - } - }, - "RouteTableConfigChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CloudTrailRouteTableChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Route Table.", - "MetricName" : "RouteTableEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "CMKChanges": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventSource = kms.amazonaws.com) && (($.eventName = DisableKey) || ($.eventName = ScheduleKeyDeletion)) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "CMKEventCount", - "MetricValue": "1" - } - ] - } - }, - "CMKChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "CMKChangesV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms each time when a CMK configuration change is made.", - "MetricName" : "CMKEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - "RootAccountUsage": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ $.userIdentity.type = Root && $.userIdentity.invokedBy NOT EXISTS && $.eventType != AwsServiceEvent }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "RootAccountUsageEventCount", - "MetricValue": "1" - } - ] - } - }, - "RootAccountUsageAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "RootAccountUsageAlarmV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Alarms each time when Root Account is used.", - "MetricName" : "RootAccountUsageEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - - - "AWSConfigChanges": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventSource = config.amazonaws.com) && (($.eventName = StopConfigurationRecorder)||($.eventName = DeleteDeliveryChannel)||($.eventName = PutDeliveryChannel)||($.eventName = PutConfigurationRecorder)) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "ConfigEventCount", - "MetricValue": "1" - } - ] - } - }, - "AWSConfigChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "AWSConfigChangesAlarmV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Triggered by AWS Config changes.", - "MetricName" : "ConfigEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - - - - "S3BucketConfigChanges": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "S3BucketEventCount", - "MetricValue": "1" - } - ] - } - }, - "S3BucketConfigChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "S3BucketConfigChangesAlarmV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Triggered by AWS S3 Bucket config changes.", - "MetricName" : "S3BucketEventCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - - - - - "ConsoleSignInWithoutMfaCount": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ $.eventName = ConsoleLogin && $.additionalEventData.MFAUsed = No && $.userIdentity.type = IAMUser && $.responseElements.ConsoleLogin = Success }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "ConsoleSignInWithoutMfaCount", - "MetricValue": "1" - } - ] - } - }, - "ConsoleSignInWithoutMfaAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "ConsoleSignInWithoutMfaAlarmV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Triggered by sign-in requests made without MFA.", - "MetricName" : "ConsoleSignInWithoutMfaCount", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - }, - - - - - - "OrganizationsChanges": { - "Type": "AWS::Logs::MetricFilter", - "Properties": { - "LogGroupName": { "Ref" : "CloudTrailLogGroupName" }, - "FilterPattern": "{ ($.eventSource = organizations.amazonaws.com) && ($.eventName = AcceptHandshake) || ($.eventName = AttachPolicy) || ($.eventName = CancelHandshake) || ($.eventName = CreateAccount) || ($.eventName = CreateOrganization) || ($.eventName = CreateOrganizationalUnit) || ($.eventName = CreatePolicy) || ($.eventName = DeclineHandshake) || ($.eventName = DeleteOrganization) || ($.eventName = DeleteOrganizationalUnit) || ($.eventName = DeletePolicy) || ($.eventName = EnableAllFeatures) || ($.eventName = EnablePolicyType) || ($.eventName = InviteAccountToOrganization) || ($.eventName = LeaveOrganization) || ($.eventName = DetachPolicy) || ($.eventName = DisablePolicyType) || ($.eventName = MoveAccount) || ($.eventName = RemoveAccountFromOrganization) || ($.eventName = UpdateOrganizationalUnit) || ($.eventName = UpdatePolicy) }", - "MetricTransformations": [ - { - "MetricNamespace": "CloudTrailMetrics", - "MetricName": "OrganizationsEvents", - "MetricValue": "1" - } - ] - } - }, - "OrganizationsChangesAlarm": { - "Type": "AWS::CloudWatch::Alarm", - "Properties": { - "AlarmName" : "OrganizationsChangesAlarmV2", - "AlarmActions": { "Fn::If" : [ "HasAlarmNotificationTopic", [{"Ref" : "AlarmNotificationTopic"}], { "Ref": "AWS::NoValue" } ] }, - "AlarmDescription" : "Triggered by AWS Organizations events.", - "MetricName" : "OrganizationsEvents", - "Namespace" : "CloudTrailMetrics", - "ComparisonOperator" : "GreaterThanOrEqualToThreshold", - "EvaluationPeriods" : "1", - "Period" : "300", - "Statistic" : "Sum", - "Threshold" : "1" - } - } - } - } \ No newline at end of file diff --git a/cloudtrail-alarms-light.cf.yml b/cloudtrail-alarms-light.cf.yml deleted file mode 100644 index f6077fb..0000000 --- a/cloudtrail-alarms-light.cf.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -AWSTemplateFormatVersion: 2010-09-09 -Description: "Cloudtrail Alarms (rev:2)" - -#==================================================================================================== -Parameters: -#==================================================================================================== - CloudTrailLogGroupName: - Type: String - Description: CloudTrail log group name when CloudTrail is already provisioned - AlarmNotificationTopic: - Type: String - Description: SNS Notification Topic to send alarms to - Default: "" - -Conditions: - HasAlarmNotificationTopic: !Not [!Equals [!Ref AlarmNotificationTopic, ""]] - -#==================================================================================================== -Resources: -#==================================================================================================== - - RootAccountUsageMetricFilter: - Type: 'AWS::Logs::MetricFilter' - Properties: - LogGroupName: !Ref CloudTrailLogGroupName - FilterPattern: '{$.userIdentity.type="Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType !="AwsServiceEvent"}' - MetricTransformations: - - MetricNamespace: CloudTrailMetrics - MetricName: RootAccountUsageEventCount - MetricValue: '1' - - RootAccountUsageAlarm: - Type: 'AWS::CloudWatch::Alarm' - Properties: - AlarmName: RootAccountUsage - AlarmDescription: (CIS-3.3) Alarms when Root Account is used - AlarmActions: !If [HasAlarmNotificationTopic, [!Ref AlarmNotificationTopic], !Ref AWS::NoValue] - MetricName: RootAccountUsageEventCount - Namespace: CloudTrailMetrics - ComparisonOperator: GreaterThanOrEqualToThreshold - EvaluationPeriods: 1 - Period: 300 - Statistic: Sum - Threshold: 1 - TreatMissingData: notBreaching - - NoMFALoginUsageMetricFilter: - Type: 'AWS::Logs::MetricFilter' - Properties: - LogGroupName: !Ref CloudTrailLogGroupName - FilterPattern: '{ ($.eventName ="ConsoleLogin") && ($.additionalEventData.MFAUsed != "Yes") }' - MetricTransformations: - - MetricNamespace: CloudTrailMetrics - MetricName: NoMFALoginEventCount - MetricValue: '1' - - NoMFALoginUsageAlarm: - Type: 'AWS::CloudWatch::Alarm' - Properties: - AlarmName: NoMFALogin - AlarmDescription: Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA. - AlarmActions: !If [HasAlarmNotificationTopic, [!Ref AlarmNotificationTopic], !Ref AWS::NoValue] - MetricName: NoMFALoginEventCount - Namespace: CloudTrailMetrics - ComparisonOperator: GreaterThanOrEqualToThreshold - EvaluationPeriods: 1 - Period: 300 - Statistic: Sum - Threshold: 1 - TreatMissingData: notBreaching