Recently while working the customer, I was asked if there is any way to find all the Security groups that are NOT attached to any resources. It was more from housekeeping perspective.
Ofcourse one can find it from within the AWS Console but the problem multiplies many fold if you are operating out of hundreds of AWS Accounts and across multiple AWS regions.
I wrote a simple python which can be run against multiple accounts and regions and generate a report in CSV format.
Script Name – getListOfUnusedSecGroup.py
#!/usr/bin/env python
import boto3
import json
import csv
import argparse
import os
from datetime import datetime, timedelta, timezone
import logging
from botocore.exceptions import ClientError
DEFAULT_REGION="us-east-1"
date_time_now = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
def ec2_client(region):
"""
Connects to EC2, returns a connection object
"""
try:
conn = boto3.client('ec2', region_name=region)
except Exception as e:
sys.stderr.write(
'Could not connect to region: %s. Exception: %s\n' % (region, e))
conn = None
return conn
def parse_commandline_arguments():
global REGION
global ACCOUNT_ID
global report_filename
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description='Create a CSV Report for listing unused Security Groups.')
parser.add_argument("-id", "--accountID", dest="account_id", type=str,required=True,
help="The AWS Account Name for which the RDS info is neeeded")
parser.add_argument("-r", "--region", dest="region", type=str,
default=DEFAULT_REGION, help="Specify the global region to pull the report")
parser.add_argument("-f", "--report", dest="reportname", type=str,
help="Specify the report file Name with path")
args = parser.parse_args()
ACCOUNT_ID= args.account_id
REGION = args.region
report_filename = args.reportname
def get_unused_security_groups(ec2Client):
try:
# get all of the security groups
print_string = ""
response = ec2Client.describe_security_groups()
for group in response['SecurityGroups']:
group_id = group['GroupId']
group_name = group['GroupName']
# Check if SG is attached to any network interface
ec2nwIntfresponse = ec2Client.describe_network_interfaces(Filters=[{'Name': 'group-id', 'Values': [group_id]}])
if not ec2nwIntfresponse['NetworkInterfaces']:
print_string = ACCOUNT_ID + "," + REGION + "," + group_name + "," + group_id + "," + date_time_now
file.write(print_string + "\n")
except Exception as e:
logging.error(e)
if __name__ == '__main__':
try:
parse_commandline_arguments()
client = ec2_client(REGION)
if not os.path.isfile(report_filename):
file = open(report_filename, 'w+')
print_string_hdr = "AccountID,Region,SecurityGroupName,SecurityGroupID,Reporting_Date_Time\n"
file.write(print_string_hdr)
else:
file = open(report_filename, 'a')
get_unused_security_groups(client)
file.close()
print("CSV File generated listing Un-used Security Groups.... - {}" .format(report_filename))
except Exception as error:
print(str(error))
How to run the script:
Make sure you have python3 installed and configured and is in path. Script takes takes 3 arguments
- AWS Account ID against which you need to get the list of Security Groups
- AWS Region
- & CSV File name with complete path
Usage: python getListOfUnusedSecGroup -id 123456789 -r us-east-1 -f /tmp/UnusedSecgroups.csv
You can run this python script against all of your AWS Accounts and all of the region by –
Invoking this python script from within a shell script with a control file that has all the AWS Accounts and their corresponding regions. Shell script will loop through all the AWS accounts and region and hen generate a consolidated CSV file.
Hope this helps.
Keep reading and happy learning.
~Anand M.
Leave a Reply