Sign in
agent:

Analysing AWS CloudTrail Trails

There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

This runbook involves a two-step process aimed at optimizing AWS CloudTrail management. Initially, every trail within AWS CloudTrail is meticulously enumerated and listed, offering visibility into trail configurations across all available regions. The process then shifts focus to scrutinize each trail, identifying and highlighting any redundant trails that may exist. Redundant trails often result in unnecessary costs and complexities, and identifying them is crucial for efficient AWS resource management. The analysis is comprehensive, covering global trails, organizational trails, and multiple trails within the same region, ensuring that AWS CloudTrail is streamlined and cost-effective.

  1. 1

    List all AWS CloudTrail Trails

    There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

    This task involves enumerating and retrieving detailed information about every AWS CloudTrail trail that exists across all AWS regions within an AWS account. Each trail captures specific API activity and events, and having a comprehensive list helps in providing visibility into what actions are being logged, where the logs are stored, and how they are configured. This listing process is foundational for subsequent tasks like auditing, analysis, and optimization of AWS CloudTrail, aiding in efficient resource management and security compliance.

    import boto3 creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Set region to None for all regions, or specify a valid AWS region string for a specific region #target_region = None target_region = target_region if target_region else None try: # List all available AWS regions ec2_client = boto3.client('ec2',aws_access_key_id=access_key,aws_secret_access_key=secret_key,region_name='us-east-1') all_regions = [region['RegionName'] for region in ec2_client.describe_regions()['Regions']] except Exception as e: print(f"ERROR: An error occurred while listing AWS regions: {e}") all_regions = [] # Get trails for all regions or a specific region regions_to_check = all_regions if target_region is None else [target_region] all_trails = [] for region in regions_to_check: try: # List all trails in AWS CloudTrail for each region cloudtrail_client = boto3.client('cloudtrail', aws_access_key_id=access_key,aws_secret_access_key=secret_key,region_name=region) response = cloudtrail_client.describe_trails(includeShadowTrails=False) trails_in_region = response['trailList'] if not trails_in_region: print(f"INFO: No trails found in region {region}.") else: all_trails.extend(trails_in_region) except Exception as e: # Handle exceptions thrown while listing trails for a region print(f"ERROR: An error occurred while listing trails in region {region}: {e}") # Print all trails if not all_trails: print("INFO: No trails found in all specified regions.") else: try: #print(all_trails) # for downstream task for trail in all_trails: print(f"Trail Name: {trail['Name']}, Trail ARN: {trail['TrailARN']}, Home Region: {trail['HomeRegion']}") except KeyError as ke: print(f"ERROR: Missing key {ke} in trail information: {trail}") except Exception as e: print(f"ERROR: An error occurred while printing trail information: {e}") print(f"SUMMARY: Processed {len(regions_to_check)} regions and found a total of {len(all_trails)} trails.")
    copied
    1
  2. 2

    Filter out redundant AWS CloudTrail Trails

    There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

    AWS CloudTrail trails are designed to log and monitor AWS account activity, but having multiple trails with overlapping configurations or that are recording the same events in the same region can lead to confusion, inefficiency, and increased costs. This task systematically reviews each trail, checks for redundancy based on specific criteria like region, event types logged, and destination S3 bucket, and then flags the redundant trails for review or deletion. Streamlining your trails through this method enhances manageability, reduces costs, and improves the clarity of your audit logs.

    2
    1. 2.1

      Filter out redundant global AWS CloudTrail Trails

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This task aims to identify and filter out redundant global trails within AWS CloudTrail. A global trail is a trail that applies to all regions in an AWS account. Redundant global trails can capture duplicate events, leading to unnecessary data storage and processing costs. Our script carefully inspects all global trails in each AWS region and identifies redundancies, providing a clear report of any trails that are unnecessary or duplicative. This allows for streamlined management and potential cost savings by helping administrators easily spot and remove any redundant global trails.

      import boto3 # Replace the following line with the actual list of trails you have #all_trails = [{'Name': 'ctrail_123', 'S3BucketName': 'aws-cloudtrail-logs-355237452254-0d3050fa', 'IncludeGlobalServiceEvents': True, 'IsMultiRegionTrail': True, 'HomeRegion': 'us-east-1', 'TrailARN': 'arn:aws:cloudtrail:us-east-1:355237452254:trail/ctrail_123', 'LogFileValidationEnabled': True, 'HasCustomEventSelectors': True, 'HasInsightSelectors': True, 'IsOrganizationTrail': False}, {'Name': 'c_global', 'S3BucketName': 'aws-cloudtrail-logs-355237452254-0d3050fa', 'IncludeGlobalServiceEvents': True, 'IsMultiRegionTrail': True, 'HomeRegion': 'us-west-2', 'TrailARN': 'arn:aws:cloudtrail:us-west-2:355237452254:trail/c_global', 'LogFileValidationEnabled': False, 'HasCustomEventSelectors': True, 'HasInsightSelectors': False, 'IsOrganizationTrail': False}, {'Name': 'ctrail_oregon', 'S3BucketName': 'aws-cloudtrail-logs-355237452254-0d3050fa', 'IncludeGlobalServiceEvents': False, 'IsMultiRegionTrail': False, 'HomeRegion': 'us-west-2', 'TrailARN': 'arn:aws:cloudtrail:us-west-2:355237452254:trail/ctrail_oregon', 'LogFileValidationEnabled': True, 'HasCustomEventSelectors': True, 'HasInsightSelectors': True, 'IsOrganizationTrail': False}] if all_trails: try: # Filtering global trails that are in their home region global_trails = [trail for trail in all_trails if trail['IsMultiRegionTrail'] and trail['HomeRegion'] == trail['HomeRegion']] # Grouping global trails per account account_trail_map = {} for trail in global_trails: account_id = trail['TrailARN'].split(':')[4] account_trail_map.setdefault(account_id, []).append(trail) # Identifying and printing redundant global trails redundant_trails_found = False for account_id, trails in account_trail_map.items(): if len(trails) > 1: redundant_trails_found = True print(f"Alarm: Account {account_id} has {len(trails)} global trails which is redundant.") for i, trail in enumerate(trails): redundant_to = ', '.join([t['Name'] for idx, t in enumerate(trails) if idx != i]) print(f" - Resource: {trail['TrailARN']}, Reason: {trail['Name']} is redundant to {redundant_to}, Region: {trail['HomeRegion']}") if not redundant_trails_found: print("No redundant global trails found.") except Exception as e: # Log any general exception that occurs print(f"An unexpected error occurred: {e}") else: print("No trails were provided.")
      copied
      2.1
    2. 2.2

      Filter out redundant regional AWS CloudTrail Trails

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This task detects redundant regional trails within AWS CloudTrail. Occasionally, users might inadvertently create multiple trails in the same region, which not only results in redundant data collection but also incurs additional costs. These unnecessary trails can capture identical events and consume extra storage, leading to inefficiency and clutter. This task scans through all the regional trails in each AWS region and pinpoints the redundant ones. By identifying redundant trails, the script aids administrators in optimizing their AWS CloudTrail configuration, thereby promoting efficient resource utilization and cost-effectiveness.

      import boto3 #all_trails = [{'Name': 'ctrail_123', 'S3BucketName': 'aws-cloudtrail-logs-355237452254-0d3050fa', 'IncludeGlobalServiceEvents': True, 'IsMultiRegionTrail': True, 'HomeRegion': 'us-east-1', 'TrailARN': 'arn:aws:cloudtrail:us-east-1:355237452254:trail/ctrail_123', 'LogFileValidationEnabled': True, 'HasCustomEventSelectors': True, 'HasInsightSelectors': True, 'IsOrganizationTrail': False}, {'Name': 'c_global', 'S3BucketName': 'aws-cloudtrail-logs-355237452254-0d3050fa', 'IncludeGlobalServiceEvents': True, 'IsMultiRegionTrail': True, 'HomeRegion': 'us-west-2', 'TrailARN': 'arn:aws:cloudtrail:us-west-2:355237452254:trail/c_global', 'LogFileValidationEnabled': False, 'HasCustomEventSelectors': True, 'HasInsightSelectors': False, 'IsOrganizationTrail': False}, {'Name': 'ctrail_oregon', 'S3BucketName': 'aws-cloudtrail-logs-355237452254-0d3050fa', 'IncludeGlobalServiceEvents': False, 'IsMultiRegionTrail': False, 'HomeRegion': 'us-west-2', 'TrailARN': 'arn:aws:cloudtrail:us-west-2:355237452254:trail/ctrail_oregon', 'LogFileValidationEnabled': True, 'HasCustomEventSelectors': True, 'HasInsightSelectors': True, 'IsOrganizationTrail': False}] if all_trails: # Identifying global and organization trails global_trails = [trail for trail in all_trails if trail['IsMultiRegionTrail']] org_trails = [trail for trail in all_trails if trail.get('IsOrganizationTrail', False)] print(f"INFO: Identified {len(global_trails)} global trails and {len(org_trails)} organization trails") # Counting regional trails per region regional_trails_count = {} for trail in all_trails: if not trail['IsMultiRegionTrail'] and not trail.get('IsOrganizationTrail', False): regional_trails_count[trail['HomeRegion']] = regional_trails_count.get(trail['HomeRegion'], 0) + 1 print(f"INFO: Count of regional trails per region: {regional_trails_count}") # Identifying and printing redundant regional trails redundant_trails_found = False for trail in all_trails: try: if not trail['IsMultiRegionTrail'] and not trail.get('IsOrganizationTrail', False): status = 'alarm' if (len(global_trails) > 0 or len(org_trails) > 0 or regional_trails_count[trail['HomeRegion']] > 1) else 'ok' redundant_trails_found = True if status == 'alarm' else redundant_trails_found reason = f"{trail['Name']} is redundant to: " if len(global_trails) > 0: reason += f"Global Trails: {', '.join([gt['Name'] for gt in global_trails])} " if len(org_trails) > 0: reason += f"Organization Trails: {', '.join([ot['Name'] for ot in org_trails])} " if regional_trails_count[trail['HomeRegion']] > 1: reason += f"other {regional_trails_count[trail['HomeRegion']]-1} regional trails in {trail['HomeRegion']}." print(f"Resource: {trail['TrailARN']}, Status: {status}, Reason: {reason}, Region: {trail['HomeRegion']}, Account ID: {trail['TrailARN'].split(':')[4]}") except Exception as e: print(f"ERROR: An error occurred while processing trail {trail['Name']}: {e}") if not redundant_trails_found: print("INFO: No redundant trails found") else: print("No trails were provided.")
      copied
      2.2