From 2de2d4dc50a1a9c3e2f3d578872e959944fc6bd6 Mon Sep 17 00:00:00 2001 From: badra001 Date: Wed, 18 Mar 2026 12:47:34 -0400 Subject: [PATCH] add csv --- .../check_security_groups.py | 53 ++++++++++++++----- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/local-app/python-tools/cross-organization/check_security_groups.py b/local-app/python-tools/cross-organization/check_security_groups.py index ddab6b95..b5ecbee2 100644 --- a/local-app/python-tools/cross-organization/check_security_groups.py +++ b/local-app/python-tools/cross-organization/check_security_groups.py @@ -1,46 +1,71 @@ import boto3 +import csv +import os +from datetime import datetime # --- VERSIONING --- -__version__ = "1.0.0" +__version__ = "1.1.0" def account_task(account_session, account_id, account_name, region): """ - Scans each region for Security Groups and collects metadata. + Scans each region for Security Groups and generates a per-account CSV. """ results = {"alias": "N/A", "data": {}} + csv_rows = [] + try: - # Get all enabled regions for the account ec2_global = account_session.client('ec2', region_name=region) regions = [r['RegionName'] for r in ec2_global.describe_regions()['Regions']] for reg in regions: ec2 = account_session.client('ec2', region_name=reg) try: - # Describe security groups for the current region paginator = ec2.get_paginator('describe_security_groups') for page in paginator.paginate(): for sg in page['SecurityGroups']: group_id = sg['GroupId'] - # Extract all tags into a dictionary - tags = {t['Key']: t['Value'] for t in sg.get('Tags', [])} + # Extract and flatten tags for CSV + tags_dict = {t['Key']: t['Value'] for t in sg.get('Tags', [])} + tags_str = "|".join([f"{k}={v}" for k, v in tags_dict.items()]) - # Keyed by region:group_id for the global aggregator - results["data"][f"{reg}:{group_id}"] = { - "resource": f"arn:aws:ec2:{reg}:{account_id}:security-group/{group_id}", + sg_data = { + "account_id": account_id, + "region": reg, "vpc_id": sg.get('VpcId', 'N/A'), "owner_id": sg.get('OwnerId', 'N/A'), + "group_id": group_id, "group_name": sg.get('GroupName', 'N/A'), "description": sg.get('Description', 'N/A'), - "group_id": group_id, - "region": reg, - "tags": tags + "tags": tags_str } + + # JSON data structure + results["data"][f"{reg}:{group_id}"] = { + "resource": f"arn:aws:ec2:{reg}:{account_id}:security-group/{group_id}", + **sg_data, + "raw_tags": tags_dict # Keep dict for easier JSON processing + } + + csv_rows.append(sg_data) + except Exception: - # Skip regions that may have restricted access continue - results["data"]["account_summary"] = {"_summary": f"SG_COUNT:{len(results['data'])}"} + # Generate per-account CSV file + if csv_rows: + ds = datetime.now().strftime("%Y%m%dT%H%M%S") + csv_file = f"security_groups_{account_id}_{ds}.csv" + fields = ["account_id", "region", "vpc_id", "owner_id", "group_id", "group_name", "description", "tags"] + + with open(csv_file, 'w', newline='') as f: + writer = csv.DictWriter(f, fieldnames=fields) + writer.writeheader() + writer.writerows(csv_rows) + + print(f" Created: {csv_file}") + + results["data"]["account_summary"] = {"_summary": f"SG_COUNT:{len(results['data'])-1}"} except Exception as e: results["error"] = str(e)