Browse Source

Merge pull request #57 from mdr-engineering/feature/ftd_MSOCI-1314_cloudwatch_alarms

Adds CloudWatch Alerts for CIS Compliance
Frederick Damstra 4 years ago
parent
commit
72df3df03a

+ 1 - 1
base/account_standards/CIS_conformance_pack.tf

@@ -10,7 +10,7 @@ resource "aws_cloudformation_stack" "CIS-Conformance-Pack" {
   parameters = {
   }
 
-  template_body = file("files/CIS_conformance_pack.cft")
+  template_body = file("files/CIS_conformance_pack.${var.aws_partition}.cft")
 
   tags = merge(var.standard_tags, var.tags)
 }

+ 1 - 1
base/account_standards/cloudtrail.tf

@@ -6,7 +6,7 @@ module "cloudtrail-logging" {
   cloudtrail_bucket = "xdr-cloudtrail-logs-${local.logging_environment}"
   iam_path          = "/aws_services/"
   kms_key_id        = var.cloudtrail_key_arn
-  log_group_name    = "cloudtrail-local-account"
+  log_group_name    = var.log_group_name
   retention_in_days = 7 # Days available in the local account cloudtrail logs. See the S3 bucket for retention there.
   # Uncomment to enable object level logging. If specifying individual buckets, be sure to end with a `/'
   # This is not enabled by default due to the recursive nature: A log is written, splunk reads it, which results in a log being written.

+ 73 - 100
base/account_standards/to_be_reviewed/section-3.tf → base/account_standards/cloudwatch_metrics_and_alarms.tf

@@ -1,45 +1,18 @@
-# TODO: This could probably be centralized?
-resource "aws_sns_topic" "alarms" {
-  name = var.sns_topic_name
-}
-
-resource "aws_sqs_queue" "alarms_sqs" {
-  name = var.sqs_queue_name
-}
-
-resource "aws_sns_topic_subscription" "dps_alarm_target" {
-  topic_arn = aws_sns_topic.alarms.arn
-  protocol  = "sqs"
-  endpoint  = aws_sqs_queue.alarms_sqs.arn
-}
-
-resource "aws_iam_role" "cloudtrail_cloudwatchlogs_role" {
-  name               = "cloudtrail_cloudwatchlogs_role"
-  path               = "/aws_services/"
-  assume_role_policy = file("${path.module}/templates/${lookup(local.workspace-dps-cloudtrail-cloudwatch-logs-role,var.environment,"")}")
-}
-
-resource "aws_iam_role_policy" "cloudtrail_cloudwatch_policy" {
-  name   = "cloudtrail_cloudwatch_policy"
-  role   = aws_iam_role.cloudtrail_cloudwatchlogs_role.id
-  policy = file("${path.module}/templates/${lookup(local.workspace-dps-cloudtrail-cloudwatch-logs-policy,var.environment,"")}")
-}
-
-resource "aws_cloudwatch_log_group" "aws-cis-logs" { 
-  name = var.cloudtrail_log_group_name
+locals {
+  alarm_namespace = "cis"
 }
 
 resource "aws_cloudwatch_log_metric_filter" "unauthorized_api_calls" {
   name           = "UnauthorizedAPICalls"
   pattern        = "{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "UnauthorizedAPICalls"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "unauthorized_api_calls" {
@@ -47,27 +20,27 @@ resource "aws_cloudwatch_metric_alarm" "unauthorized_api_calls" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.unauthorized_api_calls.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   period                    = "300"
   statistic                 = "Sum"
   threshold                 = "50"
   alarm_description         = "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity."
-  alarm_actions             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_log_metric_filter" "no_mfa_console_signin" {
   name           = "NoMFAConsoleSignin"
   pattern        = "{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "NoMFAConsoleSignin"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "no_mfa_console_signin" {
@@ -75,26 +48,26 @@ resource "aws_cloudwatch_metric_alarm" "no_mfa_console_signin" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.no_mfa_console_signin.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "root_usage" {
   name           = "RootUsage"
   pattern        = "{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "RootUsage"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "root_usage" {
@@ -102,26 +75,26 @@ resource "aws_cloudwatch_metric_alarm" "root_usage" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.root_usage.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "iam_changes" {
   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
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "IAMChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "iam_changes" {
@@ -129,27 +102,27 @@ resource "aws_cloudwatch_metric_alarm" "iam_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.iam_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   period                    = "300"
   statistic                 = "Sum"
   threshold                 = "1"
   alarm_description         = "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact."
-  alarm_actions             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "cloudtrail_cfg_changes" {
   name           = "CloudTrailCfgChanges"
   pattern        = "{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "CloudTrailCfgChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
 
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "cloudtrail_cfg_changes" {
@@ -157,26 +130,26 @@ resource "aws_cloudwatch_metric_alarm" "cloudtrail_cfg_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.cloudtrail_cfg_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "console_signin_failures" {
   name           = "ConsoleSigninFailures"
   pattern        = "{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "ConsoleSigninFailures"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "console_signin_failures" {
@@ -184,26 +157,26 @@ resource "aws_cloudwatch_metric_alarm" "console_signin_failures" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.console_signin_failures.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "disable_or_delete_cmk" {
   name           = "DisableOrDeleteCMK"
   pattern        = "{ ($.eventSource = kms.amazonaws.com) && (($.eventName = DisableKey) || ($.eventName = ScheduleKeyDeletion)) }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "DisableOrDeleteCMK"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "disable_or_delete_cmk" {
@@ -211,26 +184,26 @@ resource "aws_cloudwatch_metric_alarm" "disable_or_delete_cmk" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.disable_or_delete_cmk.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "s3_bucket_policy_changes" {
   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
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "S3BucketPolicyChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "s3_bucket_policy_changes" {
@@ -238,26 +211,26 @@ resource "aws_cloudwatch_metric_alarm" "s3_bucket_policy_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.s3_bucket_policy_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "aws_config_changes" {
   name           = "AWSConfigChanges"
   pattern        = "{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "AWSConfigChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "aws_config_changes" {
@@ -265,26 +238,26 @@ resource "aws_cloudwatch_metric_alarm" "aws_config_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.aws_config_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "security_group_changes" {
   name           = "SecurityGroupChanges"
   pattern        = "{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup)}"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "SecurityGroupChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "security_group_changes" {
@@ -292,26 +265,26 @@ resource "aws_cloudwatch_metric_alarm" "security_group_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.security_group_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "nacl_changes" {
   name           = "NACLChanges"
   pattern        = "{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "NACLChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "nacl_changes" {
@@ -319,26 +292,26 @@ resource "aws_cloudwatch_metric_alarm" "nacl_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.nacl_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "network_gw_changes" {
   name           = "NetworkGWChanges"
   pattern        = "{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }"
-  log_group_name = var.cloudtrail_log_group_name
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "NetworkGWChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "network_gw_changes" {
@@ -346,26 +319,26 @@ resource "aws_cloudwatch_metric_alarm" "network_gw_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.network_gw_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "route_table_changes" {
   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
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "RouteTableChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "route_table_changes" {
@@ -373,26 +346,26 @@ resource "aws_cloudwatch_metric_alarm" "route_table_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.route_table_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }
 
 resource "aws_cloudwatch_log_metric_filter" "vpc_changes" {
   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
+  log_group_name = var.log_group_name
 
   metric_transformation {
     name      = "VPCChanges"
-    namespace = var.alarm_namespace
+    namespace = local.alarm_namespace
     value     = "1"
   }
-  depends_on = [ aws_cloudwatch_log_group.aws-cis-logs ]
+  depends_on = [ module.cloudtrail-logging ]
 }
 
 resource "aws_cloudwatch_metric_alarm" "vpc_changes" {
@@ -400,11 +373,11 @@ resource "aws_cloudwatch_metric_alarm" "vpc_changes" {
   comparison_operator       = "GreaterThanOrEqualToThreshold"
   evaluation_periods        = "1"
   metric_name               = aws_cloudwatch_log_metric_filter.vpc_changes.id
-  namespace                 = var.alarm_namespace
+  namespace                 = local.alarm_namespace
   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             = [aws_sns_topic.alarms.arn]
+  alarm_actions             = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"]
   insufficient_data_actions = []
 }

+ 0 - 0
base/account_standards/files/CIS_conformance_pack.cft → base/account_standards/files/CIS_conformance_pack.aws-us-gov.cft


+ 288 - 0
base/account_standards/files/CIS_conformance_pack.aws.cft

@@ -0,0 +1,288 @@
+################################################################################
+#
+#   Conformance Pack:
+#     Operational Best Practices for CIS
+#
+#   This conformance pack helps verify compliance with CIS requirements. Note that
+#   this will not cover all CIS requirements but only those that can be covered
+#   using AWS Config Rules.
+#
+# XDR Notes:
+#
+#   Source: https://docs.aws.amazon.com/config/latest/developerguide/cis-conformance-pack.html
+#
+#   Changelog:
+#      * 2020-08-26 FTD Added these notes
+#      * 2020-08-27 FTD Removed ROOT_ACCOUNT_HARDWARE_MFA_ENABLED and ROOT_ACCOUNT_MFA_ENABLED
+#
+#   Recommend you do a 'diff' with the .dist to see all changes
+#
+################################################################################
+       
+Resources:
+  MFAEnabledForIamConsoleAccess:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: MFAEnabledForIamConsoleAccess
+      Description: Checks whether AWS Multi-Factor Authentication (MFA) is enabled
+        for all AWS Identity and Access Management (IAM) users that use a console
+        password. The rule is compliant if MFA is enabled.
+      Source:
+        Owner: AWS
+        SourceIdentifier: MFA_ENABLED_FOR_IAM_CONSOLE_ACCESS
+      MaximumExecutionFrequency: Twelve_Hours
+  IAMUserUnusedCredentialCheck:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: IAMUserUnusedCredentialCheck
+      Description: Checks whether your AWS Identity and Access Management (IAM) users
+        have passwords or active access keys that have not been used within the specified
+        number of days you provided.
+      InputParameters:
+        maxCredentialUsageAge: 90
+      Source:
+        Owner: AWS
+        SourceIdentifier: IAM_USER_UNUSED_CREDENTIALS_CHECK
+      MaximumExecutionFrequency: Twelve_Hours
+  AccessKeysRotated:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: AccessKeysRotated
+      Description: Checks whether the active access keys are rotated within the number
+        of days specified in maxAccessKeyAge. The rule is non-compliant if the access
+        keys have not been rotated for more than maxAccessKeyAge number of days.
+      InputParameters:
+        maxAccessKeyAge: 90
+      Source:
+        Owner: AWS
+        SourceIdentifier: ACCESS_KEYS_ROTATED
+      MaximumExecutionFrequency: Twelve_Hours
+  IAMPasswordPolicyCheck:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: IAMPasswordPolicyCheck
+      Description: Checks whether the account password policy for IAM users meets
+        the specified requirements.
+      InputParameters:
+        RequireUppercaseCharacters: true
+        RequireLowercaseCharacters: true
+        RequireSymbols: true
+        RequireNumbers: true
+        MinimumPasswordLength: 14
+        PasswordReusePrevention: 24
+        MaxPasswordAge: 90
+      Source:
+        Owner: AWS
+        SourceIdentifier: IAM_PASSWORD_POLICY
+      MaximumExecutionFrequency: Twelve_Hours
+  IAMRootAccessKeyCheck:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: IAMRootAccessKeyCheck
+      Description: Checks whether the root user access key is available.
+        The rule is compliant if the user access key does not exist.
+      Source:
+        Owner: AWS
+        SourceIdentifier: IAM_ROOT_ACCESS_KEY_CHECK
+      MaximumExecutionFrequency: Twelve_Hours
+# These next two are only in commercial, since no root logon is allowed in govcloud.
+  RootAccountMFAEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: RootAccountMFAEnabled
+      Description: Checks whether the root user of your AWS account requires multi-factor
+        authentication for console sign-in.
+      Source:
+        Owner: AWS
+        SourceIdentifier: ROOT_ACCOUNT_MFA_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+  RootAccountHardwareMFAEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: RootAccountHardwareMFAEnabled
+      Description: Checks whether your AWS account is enabled to use multi-factor
+        authentication (MFA) hardware device to sign in with root credentials.
+      Source:
+        Owner: AWS
+        SourceIdentifier: ROOT_ACCOUNT_HARDWARE_MFA_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+# Resuming rules in both govcloud and commercial
+  IAMUserNoPoliciesCheck:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: IAMUserNoPoliciesCheck
+      Description: Checks that none of your IAM users have policies attached. IAM
+        users must inherit permissions from IAM groups or roles.
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::IAM::User
+      Source:
+        Owner: AWS
+        SourceIdentifier: IAM_USER_NO_POLICIES_CHECK
+  IAMSupportPolicyInUse:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: IAMSupportPolicyInUse
+      Description: Checks that the 'AWSSupportAccess' managed policy is attached to any IAM user, group, or role
+      InputParameters:
+        policyARN: arn:aws:iam::aws:policy/AWSSupportAccess
+        policyUsageType: ANY
+      Source:
+        Owner: AWS
+        SourceIdentifier: IAM_POLICY_IN_USE
+      MaximumExecutionFrequency: Twelve_Hours
+  IAMPolicyNoStatementWithAdminAccess:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: IAMPolicyNoStatementWithAdminAccess
+      Description: Checks whether the default version of AWS Identity and Access
+        Management (IAM) policies do not have administrator access.
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::IAM::Policy
+      Source:
+        Owner: AWS
+        SourceIdentifier: IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS
+  MultiRegionCloudTrailEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: MultiRegionCloudTrailEnabled
+      Description: Checks that there is at least one multi-region AWS CloudTrail.
+        The rule is non-compliant if the trails do not match input parameters
+      Source:
+        Owner: AWS
+        SourceIdentifier: MULTI_REGION_CLOUD_TRAIL_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+  CloudTrailLogFileValidationEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: CloudTrailLogFileValidationEnabled
+      Description: Checks whether AWS CloudTrail creates a signed digest file with
+        logs
+      Source:
+        Owner: AWS
+        SourceIdentifier: CLOUD_TRAIL_LOG_FILE_VALIDATION_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+  S3BucketPublicReadProhibited:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: S3BucketPublicReadProhibited
+      Description: Checks that your Amazon S3 buckets do not allow public read access.
+        The rule checks the Block Public Access settings, the bucket policy, and the
+        bucket access control list (ACL).
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::S3::Bucket
+      Source:
+        Owner: AWS
+        SourceIdentifier: S3_BUCKET_PUBLIC_READ_PROHIBITED
+      MaximumExecutionFrequency: Twelve_Hours
+  S3BucketPublicWriteProhibited:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: S3BucketPublicWriteProhibited
+      Description: Checks that your Amazon S3 buckets do not allow public write access.
+        The rule checks the Block Public Access settings, the bucket policy, and the
+        bucket access control list (ACL).
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::S3::Bucket
+      Source:
+        Owner: AWS
+        SourceIdentifier: S3_BUCKET_PUBLIC_WRITE_PROHIBITED
+      MaximumExecutionFrequency: Twelve_Hours
+  CloudTrailCloudWatchLogsEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: CloudTrailCloudWatchLogsEnabled
+      Description: Checks whether AWS CloudTrail trails are configured to send logs
+        to Amazon CloudWatch logs.
+      Source:
+        Owner: AWS
+        SourceIdentifier: CLOUD_TRAIL_CLOUD_WATCH_LOGS_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+  S3BucketLoggingEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: S3BucketLoggingEnabled
+      Description: Checks whether logging is enabled for your S3 buckets.
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::S3::Bucket
+      Source:
+        Owner: AWS
+        SourceIdentifier: S3_BUCKET_LOGGING_ENABLED
+  CloudTrailEncryptionEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: CloudTrailEncryptionEnabled
+      Description: Checks whether AWS CloudTrail is configured to use the server side
+        encryption (SSE) AWS Key Management Service (AWS KMS) customer master key
+        (CMK) encryption.
+      Source:
+        Owner: AWS
+        SourceIdentifier: CLOUD_TRAIL_ENCRYPTION_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+  CMKBackingKeyRotationEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: CMKBackingKeyRotationEnabled
+      Description: Checks that key rotation is enabled for each key and matches to
+        the key ID of the customer created customer master key (CMK). The rule is
+        compliant, if the key rotation is enabled for specific key object.
+      Source:
+        Owner: AWS
+        SourceIdentifier: CMK_BACKING_KEY_ROTATION_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+  VPCFlowLogsEnabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: VPCFlowLogsEnabled
+      Description: Checks whether Amazon Virtual Private Cloud flow logs are found
+        and enabled for Amazon VPC.
+      InputParameters:
+        trafficType: REJECT
+      Source:
+        Owner: AWS
+        SourceIdentifier: VPC_FLOW_LOGS_ENABLED
+      MaximumExecutionFrequency: Twelve_Hours
+  IncomingSSHDisabled:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: IncomingSSHDisabled
+      Description: Checks whether the incoming SSH traffic for the security groups is accessible.
+        The rule is COMPLIANT when the IP addresses of the incoming SSH traffic in the security
+        groups are restricted. This rule applies only to IPv4.
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::EC2::SecurityGroup
+      Source:
+        Owner: AWS
+        SourceIdentifier: INCOMING_SSH_DISABLED
+  RestrictedIncomingTraffic:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: RestrictedIncomingTraffic
+      Description: Checks whether security groups that are in use disallow unrestricted
+        incoming TCP traffic to the specified ports.
+      InputParameters:
+        blockedPort1: 3389
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::EC2::SecurityGroup
+      Source:
+        Owner: AWS
+        SourceIdentifier: RESTRICTED_INCOMING_TRAFFIC
+  VPCDefaultSecurityGroupClosed:
+    Type: AWS::Config::ConfigRule
+    Properties:
+      ConfigRuleName: VPCDefaultSecurityGroupClosed
+      Description: Checks that the default security group of any Amazon Virtual Private
+        Cloud (VPC) does not allow inbound or outbound traffic. The rule is non-compliant
+        if the default security group has one or more inbound or outbound traffic.
+      Scope:
+        ComplianceResourceTypes:
+          - AWS::EC2::SecurityGroup
+      Source:
+        Owner: AWS
+        SourceIdentifier: VPC_DEFAULT_SECURITY_GROUP_CLOSED

+ 6 - 138
base/account_standards/vars.tf

@@ -26,6 +26,12 @@ variable extra_ebs_key_attachers {
   default = [ ]
 }
 
+variable "log_group_name" {
+  description = "Cloudtrail Log Group Name to Use. Keep the default unless you have a good reason."
+  type = string
+  default = "cloudtrail-local-account"
+}
+
 
 # ----------------------------------
 # Below this line are variables inherited from higher levels, so they
@@ -47,141 +53,3 @@ locals {
   c2_account = var.c2_accounts[var.aws_partition]
   is_c2 = var.aws_account_id == local.c2_account ? true : false
 }
-
-# Carried over from TF11, may not be used or accurate:
-variable "alarm_namespace" {
-  description = "The namespace in which all alarms are set up."
-  default     = "dps-alarm-benchmark"
-}
-
-variable "cloudtrail_log_group_name" {
-  description = "The name of the CloudWatch Logs group to which CloudTrail events are delivered."
-  default     = "aws-cis-logs"
-}
-
-variable "sns_topic_name" {
-  description = "The name of the SNS Topic which will be notified when any alarm is performed."
-  default     = "dps-alarm"
-}
-
-variable "sqs_queue_name" {
-  description = "The name of the SQS queue to receive alerts from cloudwatch"
-  default     = "dps-alarm-sqs"
-}
-
-variable "resource_name_prefix" {
-  description = "All the resources will be prefixed with this varible"
-  default     = "aws-cis"
-}
-
-variable "lambda_timeout" {
-  description = "Default timeout of lambda fucntions"
-  default     = 180
-}
-
-variable "lambda_dry_run" {
-  description = "Sets DRY_RUN environment variable for all lambda functions"
-  default     = false
-}
-
-variable "lambda_aggressive" {
-  description = "Sets AGGRESSIVE mode as true for lambda fucntions"
-  default     = true
-}
-
-variable "lambda_mfa_checker_user_prefix" {
-  description = "Comma separated list of prefixes that mfa checker lambda helper will ignore"
-  default     = ""
-}
-
-variable "lambda_mfa_checker_user_suffix" {
-  description = "Comma separated list of suffixes that mfa checker lambda helper will ignore"
-  default     = ""
-}
-
-variable "lambda_user_inactivity_limit" {
-  description = "Disable inactive users more than N days"
-  default     = 90
-}
-
-variable "lambda_access_key_age_max" {
-  description = "Expire access keys after N days"
-  default     = 90
-}
-
-variable "lambda_access_key_age_notify" {
-  description = "Start to send notifications for expiring keys N before"
-  default     = 7
-}
-
-variable "lambda_cron_schedule" {
-  description = "Default Cron schedule for lambda helpers"
-  default     = "cron(0 6 * * ? *)"
-}
-
-variable "temp_artifacts_dir" {
-  description = "The path for creating the zip file"
-  default     = "/tmp/terraform-aws-cis-fundatentals/artifacts"
-}
-
-variable "iam_require_uppercase_characters" {
-  description = "Require at least one uppercase letter in passwords"
-  default     = true
-}
-
-variable "iam_require_lowercase_characters" {
-  description = "Require at least one lowercase letter in passwords"
-  default     = true
-}
-
-variable "iam_require_symbols" {
-  description = "Require at least one symbol in passwords"
-  default     = true
-}
-
-variable "iam_require_numbers" {
-  description = "Require at least one number in passwords"
-  default     = true
-}
-
-variable "iam_minimum_password_length" {
-  description = "Require minimum lenght of password"
-  default     = 14
-}
-
-variable "iam_password_reuse_prevention" {
-  description = "Prevent password reuse N times"
-  default     = 24
-}
-
-variable "iam_max_password_age" {
-  description = "Passwords expire in N days"
-  default     = 90
-}
-
-variable "iam_allow_users_to_change_password" {
-  description = "Can users change their own password"
-  default     = true
-}
-
-variable "iam_hard_expiry" {
-  description = "Everyone needs hard reset for expired passwords"
-  default     = true
-}
-
-variable "billing_s3_bucket_policy" {
-  description = "Custom S3 bucket policy for billing logs. The default policy will be used if not defined"
-  default     = ""
-}
-
-# The default policy will be used if this left empty
-variable "cloudtrail_kms_policy" {
-  description = "KMS policy for Cloudtrail logs."
-  default     = ""
-}
-
-# "ReadOnly", "WriteOnly", "All".
-variable "clodtrail_event_selector_type" {
-  description = "Log type for event selectors"
-  default     = "All"
-}

+ 118 - 1
base/account_standards_c2/account_alerts.tf

@@ -20,6 +20,123 @@ data "aws_iam_policy_document" "account-alerts" {
       identifiers = [ for a in var.responsible_accounts[var.environment]: "arn:${var.aws_partition}:iam::${a}:root" ]
     }
   }
+  statement {
+    sid = "AllowCloudWatchToPublic"
+    actions = [ "SNS:Publish" ]
+    effect = "Allow"
+    resources = [ aws_sns_topic.account-alerts.arn ]
+    principals {
+      type = "Service"
+      identifiers = [ "cloudwatch.amazonaws.com" ]
+    }
+  }
+}
+
+# Unfortunately, terraform does not support email destinations, so we can't manage subscriptions here.
+
+# SQS to get alerts into Splunk
+resource "aws_sqs_queue" "account-alerts" {
+  name                       = "account-alerts"
+  visibility_timeout_seconds = 300 # wait 5 minutes before allowing a different splunk instance to process the same message
+  message_retention_seconds  = 604800 # Keep a message in the queue for 7 days
+  receive_wait_time_seconds  = 0 # how long to wait for a message before returning
+  redrive_policy             = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.account-alerts-dlq.arn}\",\"maxReceiveCount\":4}"
+  tags                       = merge(var.standard_tags, var.tags)
+  kms_master_key_id          = aws_kms_key.account-alerts-key.id
+  kms_data_key_reuse_period_seconds = 3600
+}
+
+data "aws_iam_policy_document" "account-alerts-sns-topic-can-publish" {
+  statement {
+    effect = "Allow"
+
+    principals {
+      identifiers = [ "*" ]
+      type = "AWS"
+    }
+
+    actions = [ "SQS:SendMessage" ]
+
+    resources = [ aws_sqs_queue.account-alerts.arn ]
+
+    condition {
+      test = "ArnEquals"
+      values = [ aws_sns_topic.account-alerts.arn ]
+      variable = "aws:SourceArn"
+    }
+  }
+}
+
+// Dead Letter queue, use same parameters as main queue
+resource "aws_sqs_queue" "account-alerts-dlq" {
+  name                      = "account-alerts-dlq"
+  message_retention_seconds = 300
+  receive_wait_time_seconds = 0
+  tags                      = merge(var.standard_tags, var.tags)
+  kms_master_key_id         = aws_kms_key.account-alerts-key.id
+  kms_data_key_reuse_period_seconds = 3600
+}
+
+resource "aws_sqs_queue_policy" "account-alerts-can-publish" {
+  policy    = data.aws_iam_policy_document.account-alerts-sns-topic-can-publish.json
+  queue_url = aws_sqs_queue.account-alerts.id
+}
+
+resource "aws_sns_topic_subscription" "account-alerts-to-queue" {
+  topic_arn = aws_sns_topic.account-alerts.arn
+  protocol  = "sqs"
+  endpoint  = aws_sqs_queue.account-alerts.arn
+}
+
+resource "aws_kms_key" "account-alerts-key" {
+  description             = "Encryption of SNS and SQS queue for account alerts notifications"
+  policy                  = data.aws_iam_policy_document.account-alerts-kms-policy.json
+  enable_key_rotation     = true
+}
+
+data "aws_iam_policy_document" "account-alerts-kms-policy" {
+  statement {
+    sid = "AllowServices"
+    effect = "Allow"
+    principals {
+      identifiers = ["cloudwatch.amazonaws.com", "sns.amazonaws.com", "sqs.amazonaws.com"]
+      type = "Service"
+    }
+    actions = [
+      "kms:GenerateDataKey",
+      "kms:Decrypt"
+    ]
+    resources = [ "*" ]
+  }
+  statement {
+    sid = "AllowOtherAccounts"
+    effect = "Allow"
+    principals {
+      type = "AWS"
+      identifiers = [ for a in var.responsible_accounts[var.environment]: "arn:${var.aws_partition}:iam::${a}:root" ]
+    }
+    actions = [
+      "kms:GenerateDataKey",
+      "kms:Encrypt"
+    ]
+    resources = [ "*" ]
+  }
+  # allow account to modify/manage key
+  statement {
+    sid = "AllowThisAccount"
+    effect = "Allow"
+    principals {
+      identifiers = ["arn:${var.aws_partition}:iam::${var.aws_account_id}:root"]
+      type = "AWS"
+    }
+    actions = [
+      "kms:*"
+    ]
+    resources = ["*"]
+  }
 }
 
-# Unfortunately, terraform does not support email destinations
+resource "aws_kms_alias" "account-alerts-key-alias" {
+  name          = "alias/account-alerts-key"
+  target_key_id = aws_kms_key.account-alerts-key.key_id
+}

+ 1 - 1
base/account_standards_c2/config_aggregator.tf

@@ -35,7 +35,7 @@ resource "aws_sqs_queue" "config-notifications" {
   visibility_timeout_seconds = 300 # wait 5 minutes before allowing a different splunk instance to process the same message
   message_retention_seconds  = 604800 # Keep a message in the queue for 7 days
   receive_wait_time_seconds  = 0 # how long to wait for a message before returning
-  redrive_policy             = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.dlq.arn}\",\"maxReceiveCount\":4}"
+  redrive_policy             = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.config-notifications-dlq.arn}\",\"maxReceiveCount\":4}"
   tags                       = merge(var.standard_tags, var.tags)
   kms_master_key_id          = aws_kms_key.config-notifications-key.id
   kms_data_key_reuse_period_seconds = 3600