diff --git a/local-app/python-tools/cross-organization/check_security_groups.py b/local-app/python-tools/cross-organization/check_security_groups.py new file mode 100644 index 00000000..ddab6b95 --- /dev/null +++ b/local-app/python-tools/cross-organization/check_security_groups.py @@ -0,0 +1,48 @@ +import boto3 + +# --- VERSIONING --- +__version__ = "1.0.0" + +def account_task(account_session, account_id, account_name, region): + """ + Scans each region for Security Groups and collects metadata. + """ + results = {"alias": "N/A", "data": {}} + 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', [])} + + # 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}", + "vpc_id": sg.get('VpcId', 'N/A'), + "owner_id": sg.get('OwnerId', 'N/A'), + "group_name": sg.get('GroupName', 'N/A'), + "description": sg.get('Description', 'N/A'), + "group_id": group_id, + "region": reg, + "tags": tags + } + except Exception: + # Skip regions that may have restricted access + continue + + results["data"]["account_summary"] = {"_summary": f"SG_COUNT:{len(results['data'])}"} + + except Exception as e: + results["error"] = str(e) + + return results