From 8869909d20aaf19684a3432da640c9d0cb345e41 Mon Sep 17 00:00:00 2001 From: Mike O'Brien Date: Thu, 11 Nov 2021 13:10:12 +0000 Subject: [PATCH] Bugfix for CIS 3.1-3.14 --- CHANGELOG.md | 6 + deployment/build-s3-dist.sh | 2 +- source/package.json | 6 +- .../ssmdocs/scripts/cis_get_input_values.py | 117 +++++++++--------- .../scripts/CreateLogMetricFilterAndAlarm.py | 13 +- ...eateLogMetricFilterAndAlarm_createtopic.py | 105 ++++++++++++++++ .../test_createlogmetricfilterandalarm.py | 13 +- .../scripts/test/test_enablevpcflowlogs.py | 4 +- .../solution_deploy/lib/sharr_member-stack.ts | 1 + .../__snapshots__/member_stack.test.ts.snap | 11 ++ .../__snapshots__/runbook_stack.test.ts.snap | 15 ++- 11 files changed, 211 insertions(+), 82 deletions(-) create mode 100644 source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm_createtopic.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dcdabd4..de7c22b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.3.2] - 2021-11-09 +- Corrected CIS 3.1 filter pattern +- Corrected SNS Access Policy for SO0111-SHARR-LocalAlarmNotification +- Corrected KMS CMK Access Policy used by the SNS topic to allow CloudWatch use +- EvaluationPeriods for CIS 3.x alarms changed from 240 (20 hours) to 12 (1 hour) + ## [1.3.1] - 2021-09-10 ### Changed diff --git a/deployment/build-s3-dist.sh b/deployment/build-s3-dist.sh index a86b15a7..6522f646 100755 --- a/deployment/build-s3-dist.sh +++ b/deployment/build-s3-dist.sh @@ -20,7 +20,7 @@ # This controls the CDK and AWS Solutions Constructs version. Solutions # Constructs versions map 1:1 to CDK versions. When setting this value, # choose the latest AWS Solutions Constructs version. -required_cdk_version=1.117.0 +required_cdk_version=1.132.0 # Functions to reduce repetitive code # do_cmd will exit if the command has a non-zero return code. diff --git a/source/package.json b/source/package.json index d66b023b..e249bbc2 100644 --- a/source/package.json +++ b/source/package.json @@ -19,12 +19,10 @@ }, "devDependencies": { "@aws-cdk/assert": "~###CDK###", - "@types/node": "16.7.1", + "@types/node": "16.11.7", "aws-cdk": "~###CDK###", "ts-node": "^10.2.1", - "typescript": "^4.3.5" - }, - "dependencies": { + "typescript": "^4.3.5", "@aws-cdk/aws-events": "~###CDK###", "@aws-cdk/aws-iam": "~###CDK###", "@aws-cdk/aws-kms": "~###CDK###", diff --git a/source/playbooks/CIS120/ssmdocs/scripts/cis_get_input_values.py b/source/playbooks/CIS120/ssmdocs/scripts/cis_get_input_values.py index 619d2804..bca25d6d 100644 --- a/source/playbooks/CIS120/ssmdocs/scripts/cis_get_input_values.py +++ b/source/playbooks/CIS120/ssmdocs/scripts/cis_get_input_values.py @@ -16,130 +16,129 @@ CIS_mappings = { "3.1": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_1", - "filter_pattern": '{$.errorCode = "AccessDenied" || $.errorCode = "UnauthorizedOperation"}', - "metric_name": "SHARR_CIS_1_2_Finding_3_1_UnauthorizedAPICalls", + "filter_name": "UnauthorizedAPICalls", + "filter_pattern": '{($.errorCode="*UnauthorizedOperation") || ($.errorCode="AccessDenied*")}', + "metric_name": "UnauthorizedAPICalls", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_1_UnauthorizedAPICalls", - "alarm_desc": "Alarm for CIS finding 3.1-UnauthorizedAPICalls", + "alarm_name": "UnauthorizedAPICalls", + "alarm_desc": "Alarm for UnauthorizedAPICalls > 0", "alarm_threshold": 1 }, "3.2": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_2_ConsoleSigninWithoutMFA", + "filter_name": "ConsoleSigninWithoutMFA", "filter_pattern": '{($.eventName="ConsoleLogin") && ($.additionalEventData.MFAUsed !="Yes")}', - "metric_name": "SHARR_CIS_1_2_Finding_3_2_ConsoleSigninWithoutMFA", + "metric_name": "ConsoleSigninWithoutMFA", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_2_ConsoleSigninWithoutMFA", - "alarm_desc": "Alarm for CIS finding 3.2 ConsoleSigninWithoutMFA", + "alarm_name": "ConsoleSigninWithoutMFA", + "alarm_desc": "Alarm for ConsoleSigninWithoutMFA > 0", "alarm_threshold": 1 }, "3.3": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_3_RootAccountUsage", + "filter_name": "RootAccountUsage", "filter_pattern": '{$.userIdentity.type="Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType !="AwsServiceEvent"}', - "metric_name": "SHARR_CIS_1_2_Finding_3_3_RootAccountUsage", + "metric_name": "RootAccountUsage", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_3_RootAccountUsage", - "alarm_desc": "Alarm for CIS finding 3.3 RootAccountUsage", + "alarm_name": "RootAccountUsage", + "alarm_desc": "Alarm for RootAccountUsage > 0", "alarm_threshold": 1 - }, "3.4": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_4_IAMPolicyChanges", + "filter_name": "IAMPolicyChanges", "filter_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)}', - "metric_name": "SHARR_CIS_1_2_Finding_3_4_IAMPolicyChanges", + "metric_name": "IAMPolicyChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_4_IAMPolicyChanges", - "alarm_desc": "Alarm for CIS finding 3.4 IAMPolicyChanges", + "alarm_name": "IAMPolicyChanges", + "alarm_desc": "Alarm for IAMPolicyChanges > 0", "alarm_threshold": 1 }, "3.5": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_5_CloudTrailChanges", + "filter_name": "CloudTrailChanges", "filter_pattern": '{($.eventName=CreateTrail) || ($.eventName=UpdateTrail) || ($.eventName=DeleteTrail) || ($.eventName=StartLogging) || ($.eventName=StopLogging)}', - "metric_name": "SHARR_CIS_1_2_Finding_3_5_CloudTrailChanges", + "metric_name": "CloudTrailChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_5_CloudTrailChanges", - "alarm_desc": "Alarm for CIS finding 3.5 CloudTrailChanges", + "alarm_name": "CloudTrailChanges", + "alarm_desc": "Alarm for CloudTrailChanges > 0", "alarm_threshold": 1 }, "3.6": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_6_ConsoleAuthenticationFailure", + "filter_name": "ConsoleAuthenticationFailure", "filter_pattern": '{($.eventName=ConsoleLogin) && ($.errorMessage="Failed authentication")}', - "metric_name": "SHARR_CIS_1_2_Finding_3_6_ConsoleAuthenticationFailure", + "metric_name": "ConsoleAuthenticationFailure", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_6_ConsoleAuthenticationFailure", - "alarm_desc": "Alarm for CIS finding 3.6 ConsoleAuthenticationFailure", + "alarm_name": "ConsoleAuthenticationFailure", + "alarm_desc": "Alarm for ConsoleAuthenticationFailure > 0", "alarm_threshold": 1 }, "3.7": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_7_DisableOrDeleteCMK", + "filter_name": "DisableOrDeleteCMK", "filter_pattern": '{($.eventSource=kms.amazonaws.com) && (($.eventName=DisableKey) || ($.eventName=ScheduleKeyDeletion))}', - "metric_name": "SHARR_CIS_1_2_Finding_3_7_DisableOrDeleteCMK", + "metric_name": "DisableOrDeleteCMK", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_7_DisableOrDeleteCMK", - "alarm_desc": "Alarm for CIS finding 3.7 DisableOrDeleteCMK", + "alarm_name": "DisableOrDeleteCMK", + "alarm_desc": "Alarm for DisableOrDeleteCMK > 0", "alarm_threshold": 1 }, "3.8": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_8_S3BucketPolicyChanges", + "filter_name": "S3BucketPolicyChanges", "filter_pattern": '{($.eventSource=s3.amazonaws.com) && (($.eventName=PutBucketAcl) || ($.eventName=PutBucketPolicy) || ($.eventName=PutBucketCors) || ($.eventName=PutBucketLifecycle) || ($.eventName=PutBucketReplication) || ($.eventName=DeleteBucketPolicy) || ($.eventName=DeleteBucketCors) || ($.eventName=DeleteBucketLifecycle) || ($.eventName=DeleteBucketReplication))}', - "metric_name": "SHARR_CIS_1_2_Finding_3_8_S3BucketPolicyChanges", + "metric_name": "S3BucketPolicyChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_8_S3BucketPolicyChanges", - "alarm_desc": "Alarm for CIS finding 3.8 S3BucketPolicyChanges", + "alarm_name": "S3BucketPolicyChanges", + "alarm_desc": "Alarm for S3BucketPolicyChanges > 0", "alarm_threshold": 1 }, "3.9": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_9_AWSConfigChanges", + "filter_name": "AWSConfigChanges", "filter_pattern": '{($.eventSource=config.amazonaws.com) && (($.eventName=StopConfigurationRecorder) || ($.eventName=DeleteDeliveryChannel) || ($.eventName=PutDeliveryChannel) || ($.eventName=PutConfigurationRecorder))}', - "metric_name": "SHARR_CIS_1_2_Finding_3_9_AWSConfigChanges", + "metric_name": "AWSConfigChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_9_AWSConfigChanges", - "alarm_desc": "Alarm for CIS finding 3.9 AWSConfigChanges", + "alarm_name": "AWSConfigChanges", + "alarm_desc": "Alarm for AWSConfigChanges > 0", "alarm_threshold": 1 }, "3.10": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_10_SecurityGroupChanges", + "filter_name": "SecurityGroupChanges", "filter_pattern": '{($.eventName=AuthorizeSecurityGroupIngress) || ($.eventName=AuthorizeSecurityGroupEgress) || ($.eventName=RevokeSecurityGroupIngress) || ($.eventName=RevokeSecurityGroupEgress) || ($.eventName=CreateSecurityGroup) || ($.eventName=DeleteSecurityGroup)}', - "metric_name": "SHARR_CIS_1_2_Finding_3_10_SecurityGroupChanges", + "metric_name": "SecurityGroupChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_10_SecurityGroupChanges", - "alarm_desc": "Alarm for CIS finding 3.10 SecurityGroupChanges", + "alarm_name": "SecurityGroupChanges", + "alarm_desc": "Alarm for SecurityGroupChanges > 0", "alarm_threshold": 1 }, "3.11": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_11_NetworkACLChanges", + "filter_name": "NetworkACLChanges", "filter_pattern": '{($.eventName=CreateNetworkAcl) || ($.eventName=CreateNetworkAclEntry) || ($.eventName=DeleteNetworkAcl) || ($.eventName=DeleteNetworkAclEntry) || ($.eventName=ReplaceNetworkAclEntry) || ($.eventName=ReplaceNetworkAclAssociation)}', - "metric_name": "SHARR_CIS_1_2_Finding_3_11_NetworkACLChanges", + "metric_name": "NetworkACLChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_11_NetworkACLChanges", - "alarm_desc": "Alarm for CIS finding 3.11 NetworkACLChanges", + "alarm_name": "NetworkACLChanges", + "alarm_desc": "Alarm for NetworkACLChanges > 0", "alarm_threshold": 1 }, "3.12": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_12_NetworkGatewayChanges", + "filter_name": "NetworkGatewayChanges", "filter_pattern": '{($.eventName=CreateCustomerGateway) || ($.eventName=DeleteCustomerGateway) || ($.eventName=AttachInternetGateway) || ($.eventName=CreateInternetGateway) || ($.eventName=DeleteInternetGateway) || ($.eventName=DetachInternetGateway)}', - "metric_name": "SHARR_CIS_1_2_Finding_3_12_NetworkGatewayChanges", + "metric_name": "NetworkGatewayChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_12_NetworkGatewayChanges", - "alarm_desc": "Alarm for CIS finding 3.12 NetworkGatewayChanges", + "alarm_name": "NetworkGatewayChanges", + "alarm_desc": "Alarm for NetworkGatewayChanges > 0", "alarm_threshold": 1 }, "3.13": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_13_RouteTableChanges", + "filter_name": "RouteTableChanges", "filter_pattern": '{($.eventName=CreateRoute) || ($.eventName=CreateRouteTable) || ($.eventName=ReplaceRoute) || ($.eventName=ReplaceRouteTableAssociation) || ($.eventName=DeleteRouteTable) || ($.eventName=DeleteRoute) || ($.eventName=DisassociateRouteTable)}', - "metric_name": "SHARR_CIS_1_2_Finding_3_13_RouteTableChanges", + "metric_name": "RouteTableChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_13_RouteTableChanges", - "alarm_desc": "Alarm for CIS finding 3.13 RouteTableChanges", + "alarm_name": "RouteTableChanges", + "alarm_desc": "Alarm for RouteTableChanges > 0", "alarm_threshold": 1 }, "3.14": { - "filter_name": "SHARR_Filter_CIS_1_2_Finding_3_14_VPCChanges", + "filter_name": "VPCChanges", "filter_pattern": '{($.eventName=CreateVpc) || ($.eventName=DeleteVpc) || ($.eventName=ModifyVpcAttribute) || ($.eventName=AcceptVpcPeeringConnection) || ($.eventName=CreateVpcPeeringConnection) || ($.eventName=DeleteVpcPeeringConnection) || ($.eventName=RejectVpcPeeringConnection) || ($.eventName=AttachClassicLinkVpc) || ($.eventName=DetachClassicLinkVpc) || ($.eventName=DisableVpcClassicLink) || ($.eventName=EnableVpcClassicLink)}', - "metric_name": "SHARR_CIS_1_2_Finding_3_14_VPCChanges", + "metric_name": "VPCChanges", "metric_value": 1, - "alarm_name": "SHARR_Alarm_CIS_1_2_Finding_3_14_VPCChanges", - "alarm_desc": "Alarm for CIS finding 3.14 VPCChanges", + "alarm_name": "VPCChanges", + "alarm_desc": "Alarm for VPCChanges > 0", "alarm_threshold": 1 } } @@ -147,4 +146,4 @@ def verify(event, context): - return CIS_mappings.get(event['ControlId'], None) + return CIS_mappings.get(event['ControlId'], None) \ No newline at end of file diff --git a/source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm.py b/source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm.py index 8206e24d..264647fd 100644 --- a/source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm.py +++ b/source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm.py @@ -63,8 +63,9 @@ def put_metric_filter(cw_log_group, filter_name, filter_pattern, metric_name, me { 'metricName': metric_name, 'metricNamespace': metric_namespace, - 'metricValue': str(metric_value) - }, + 'metricValue': str(metric_value), + 'unit': 'Count' + } ] ) except Exception as e: @@ -99,10 +100,12 @@ def put_metric_alarm(alarm_name, alarm_desc, alarm_threshold, metric_name, metri Namespace=metric_namespace, Statistic='Sum', Period=300, - Unit='Seconds', - EvaluationPeriods=240, + Unit='Count', + EvaluationPeriods=12, + DatapointsToAlarm=1, Threshold=alarm_threshold, - ComparisonOperator='GreaterThanOrEqualToThreshold' + ComparisonOperator='GreaterThanOrEqualToThreshold', + TreatMissingData='notBreaching' ) except Exception as e: exit("Exception occurred while putting metric alarm: " + str(e)) diff --git a/source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm_createtopic.py b/source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm_createtopic.py new file mode 100644 index 00000000..0572c52b --- /dev/null +++ b/source/remediation_runbooks/scripts/CreateLogMetricFilterAndAlarm_createtopic.py @@ -0,0 +1,105 @@ +#!/usr/bin/python +############################################################################### +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # +# # +# Licensed under the Apache License Version 2.0 (the "License"). You may not # +# use this file except in compliance with the License. A copy of the License # +# is located at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# or in the "license" file accompanying this file. This file is distributed # +# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express # +# or implied. See the License for the specific language governing permis- # +# sions and limitations under the License. # +############################################################################### + +import json +import boto3 +from botocore.config import Config +from botocore.exceptions import ClientError + +boto_config = Config( + retries ={ + 'mode': 'standard' + } +) + +def connect_to_sns(): + return boto3.client('sns', config=boto_config) + +def connect_to_ssm(): + return boto3.client('ssm', config=boto_config) + +def create_encrypted_topic(event, context): + + kms_key_arn = event['kms_key_arn'] + new_topic = False + topic_arn = '' + topic_name = event['topic_name'] + + try: + sns = connect_to_sns() + topic_arn = sns.create_topic( + Name=topic_name, + Attributes={ + 'KmsMasterKeyId': kms_key_arn.split('key/')[1] + } + )['TopicArn'] + new_topic = True + + except ClientError as client_exception: + exception_type = client_exception.response['Error']['Code'] + if exception_type == 'InvalidParameter': + print(f'Topic {topic_name} already exists. This remediation may have been run before.') + print('Ignoring exception - remediation continues.') + topic_arn = sns.create_topic( + Name=topic_name + )['TopicArn'] + else: + exit(f'ERROR: Unhandled client exception: {client_exception}') + + except Exception as e: + exit(f'ERROR: could not create SNS Topic {topic_name}: {str(e)}') + + if new_topic: + try: + ssm = connect_to_ssm() + ssm.put_parameter( + Name='/Solutions/SO0111/SNS_Topic_CIS3.x', + Description='SNS Topic for AWS Config updates', + Type='String', + Overwrite=True, + Value=topic_arn + ) + except Exception as e: + exit(f'ERROR: could not create SNS Topic {topic_name}: {str(e)}') + + create_topic_policy(topic_arn) + + return {"topic_arn": topic_arn} + +def create_topic_policy(topic_arn): + sns = connect_to_sns() + try: + topic_policy = { + "Id": "Policy_ID", + "Statement": [ + { + "Sid": "AWSConfigSNSPolicy", + "Effect": "Allow", + "Principal": { + "Service": "cloudwatch.amazonaws.com" + }, + "Action": "SNS:Publish", + "Resource": topic_arn, + }] + } + + sns.set_topic_attributes( + TopicArn=topic_arn, + AttributeName='Policy', + AttributeValue=json.dumps(topic_policy) + ) + except Exception as e: + exit(f'ERROR: Failed to SetTopicAttributes for {topic_arn}: {str(e)}') diff --git a/source/remediation_runbooks/scripts/test/test_createlogmetricfilterandalarm.py b/source/remediation_runbooks/scripts/test/test_createlogmetricfilterandalarm.py index 0963eb3c..46ae964e 100644 --- a/source/remediation_runbooks/scripts/test/test_createlogmetricfilterandalarm.py +++ b/source/remediation_runbooks/scripts/test/test_createlogmetricfilterandalarm.py @@ -85,8 +85,9 @@ def test_put_metric_filter_pass(mocker): { 'metricName': event['MetricName'], 'metricNamespace':event['MetricNamespace'], - 'metricValue': str (event['MetricValue']) - }, + 'metricValue': str (event['MetricValue']), + 'unit': 'Count' + } ] } ) @@ -179,10 +180,12 @@ def test_put_metric_alarm(mocker): 'Namespace': event['MetricNamespace'], 'Statistic': 'Sum', 'Period': 300, - 'Unit': 'Seconds', - 'EvaluationPeriods': 240, + 'Unit': 'Count', + 'EvaluationPeriods': 12, + 'DatapointsToAlarm': 1, 'Threshold': (event['AlarmThreshold']), - 'ComparisonOperator': 'GreaterThanOrEqualToThreshold' + 'ComparisonOperator': 'GreaterThanOrEqualToThreshold', + 'TreatMissingData': 'notBreaching' } ) cloudwatch_stubber.activate() diff --git a/source/remediation_runbooks/scripts/test/test_enablevpcflowlogs.py b/source/remediation_runbooks/scripts/test/test_enablevpcflowlogs.py index e9c073b2..6798b710 100644 --- a/source/remediation_runbooks/scripts/test/test_enablevpcflowlogs.py +++ b/source/remediation_runbooks/scripts/test/test_enablevpcflowlogs.py @@ -54,7 +54,7 @@ def test_EnableVPCFlowLogs_success(mocker): 'FlowLogs': [ { "CreationTime": "2020-10-27T19:37:52.871000+00:00", - "DeliverLogsPermissionArn": f'arn:aws:iam::733881326153:role/{event["remediation_role"]}_{my_region}', + "DeliverLogsPermissionArn": f'arn:aws:iam::111122223333:role/{event["remediation_role"]}_{my_region}', "DeliverLogsStatus": "SUCCESS", "FlowLogId": "fl-0a3f6513bef12ff9a", "FlowLogStatus": "ACTIVE", @@ -174,7 +174,7 @@ def test_EnableVPCFlowLogs_loggroup_exists(mocker): 'FlowLogs': [ { "CreationTime": "2020-10-27T19:37:52.871000+00:00", - "DeliverLogsPermissionArn": f'arn:aws:iam::733881326153:role/{event["remediation_role"]}_{my_region}', + "DeliverLogsPermissionArn": f'arn:aws:iam::111122223333:role/{event["remediation_role"]}_{my_region}', "DeliverLogsStatus": "SUCCESS", "FlowLogId": "fl-0a3f6513bef12ff9a", "FlowLogStatus": "ACTIVE", diff --git a/source/solution_deploy/lib/sharr_member-stack.ts b/source/solution_deploy/lib/sharr_member-stack.ts index 17b07f53..5c35b2f6 100644 --- a/source/solution_deploy/lib/sharr_member-stack.ts +++ b/source/solution_deploy/lib/sharr_member-stack.ts @@ -67,6 +67,7 @@ export class OrchestratorMemberRole extends cdk.Construct { kmsPerms.addPrincipals(new ServicePrincipal('s3.amazonaws.com')) kmsPerms.addPrincipals(new ServicePrincipal(`logs.${stack.region}.${stack.urlSuffix}`)) kmsPerms.addPrincipals(new ServicePrincipal(`cloudtrail.${stack.urlSuffix}`)) + kmsPerms.addPrincipals(new ServicePrincipal(`cloudwatch.${stack.urlSuffix}`)) kmsKeyPolicy.addStatements(kmsPerms) const kmsKey:Key = new Key(this, 'SHARR Remediation Key', { diff --git a/source/test/__snapshots__/member_stack.test.ts.snap b/source/test/__snapshots__/member_stack.test.ts.snap index de7e0d89..dc516694 100644 --- a/source/test/__snapshots__/member_stack.test.ts.snap +++ b/source/test/__snapshots__/member_stack.test.ts.snap @@ -317,6 +317,17 @@ Object { ], ], }, + Object { + "Fn::Join": Array [ + "", + Array [ + "cloudwatch.", + Object { + "Ref": "AWS::URLSuffix", + }, + ], + ], + }, ], }, "Resource": "*", diff --git a/source/test/__snapshots__/runbook_stack.test.ts.snap b/source/test/__snapshots__/runbook_stack.test.ts.snap index f6e680a4..9e3253f7 100644 --- a/source/test/__snapshots__/runbook_stack.test.ts.snap +++ b/source/test/__snapshots__/runbook_stack.test.ts.snap @@ -3714,7 +3714,7 @@ def create_topic_policy(topic_arn): \\"Sid\\": \\"AWSConfigSNSPolicy\\", \\"Effect\\": \\"Allow\\", \\"Principal\\": { - \\"Service\\": \\"logs.amazonaws.com\\" + \\"Service\\": \\"cloudwatch.amazonaws.com\\" }, \\"Action\\": \\"SNS:Publish\\", \\"Resource\\": topic_arn, @@ -3820,8 +3820,9 @@ def put_metric_filter(cw_log_group, filter_name, filter_pattern, metric_name, me { 'metricName': metric_name, 'metricNamespace': metric_namespace, - 'metricValue': str(metric_value) - }, + 'metricValue': str(metric_value), + 'unit': 'Count' + } ] ) except Exception as e: @@ -3856,10 +3857,12 @@ def put_metric_alarm(alarm_name, alarm_desc, alarm_threshold, metric_name, metri Namespace=metric_namespace, Statistic='Sum', Period=300, - Unit='Seconds', - EvaluationPeriods=240, + Unit='Count', + EvaluationPeriods=12, + DatapointsToAlarm=1, Threshold=alarm_threshold, - ComparisonOperator='GreaterThanOrEqualToThreshold' + ComparisonOperator='GreaterThanOrEqualToThreshold', + TreatMissingData='notBreaching' ) except Exception as e: exit(\\"Exception occurred while putting metric alarm: \\" + str(e))