Skip to content

Instantly share code, notes, and snippets.

@feldversuch
Forked from TomRyan-321/security-group-cleanup.py
Last active February 12, 2018 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save feldversuch/fd02c150eeb1f81862a421af04461254 to your computer and use it in GitHub Desktop.
Save feldversuch/fd02c150eeb1f81862a421af04461254 to your computer and use it in GitHub Desktop.
Security Group Cleanup using python3, boto3 +profile +ElasticCache
#!/usr/bin/env python3
import boto3
import argparse
def lookup_by_id(sgid):
sg = ec2.get_all_security_groups(group_ids=sgid)
return sg[0].name
# parse arguments
parser = argparse.ArgumentParser(description="Show unused security groups")
parser.add_argument("-p", "--profile", type=str, default="", help="add profile with -p <profile>*")
parser.add_argument("-r", "--region", type=str, default="eu-west-1", help="add profile with -r <region>*")
parser.add_argument("-d", "--delete", help="delete security groups from AWS", action="store_true")
args = parser.parse_args()
# set global region and profile
boto3.setup_default_session(profile_name=args.profile, region_name=args.region)
client = boto3.client('ec2')
ec2 = boto3.resource('ec2')
all_groups = []
security_groups_in_use = []
# Get ALL security groups names
security_groups_dict = client.describe_security_groups()
security_groups = security_groups_dict['SecurityGroups']
for groupobj in security_groups:
if groupobj['GroupName'] == 'default' or groupobj['GroupName'].startswith('d-') or groupobj['GroupName'].startswith('AWS-OpsWorks-'):
security_groups_in_use.append(groupobj['GroupId'])
all_groups.append(groupobj['GroupId'])
# Get all security groups used by instances
instances_dict = client.describe_instances()
reservations = instances_dict['Reservations']
network_interface_count = 0
for i in reservations:
for j in i['Instances']:
for k in j['SecurityGroups']:
if k['GroupId'] not in security_groups_in_use:
security_groups_in_use.append(k['GroupId'])
# Security Groups in use by Network Interfaces
eni_client = boto3.client('ec2')
eni_dict = eni_client.describe_network_interfaces()
for i in eni_dict['NetworkInterfaces']:
for j in i['Groups']:
if j['GroupId'] not in security_groups_in_use:
security_groups_in_use.append(j['GroupId'])
# Security groups used by classic ELBs
elb_client = boto3.client('elb')
elb_dict = elb_client.describe_load_balancers()
for i in elb_dict['LoadBalancerDescriptions']:
for j in i['SecurityGroups']:
if j not in security_groups_in_use:
security_groups_in_use.append(j)
# Security groups used by ALBs
elb2_client = boto3.client('elbv2')
elb2_dict = elb2_client.describe_load_balancers()
for i in elb2_dict['LoadBalancers']:
for j in i['SecurityGroups']:
if j not in security_groups_in_use:
security_groups_in_use.append(j)
# Security groups used by RDS
rds_client = boto3.client('rds')
rds_dict = rds_client.describe_db_instances()
for i in rds_dict['DBInstances']:
for j in i['VpcSecurityGroups']:
if j['VpcSecurityGroupId'] not in security_groups_in_use:
security_groups_in_use.append(j['VpcSecurityGroupId'])
# Security groups used by ElastiCache
cache_client = boto3.client('elasticache')
cache_dict = cache_client.describe_cache_clusters()
for i in cache_dict['CacheClusters']:
for j in i['SecurityGroups']:
if j['SecurityGroupId'] not in security_groups_in_use:
security_groups_in_use.append(j['SecurityGroupId'])
delete_candidates = []
for group in all_groups:
if group not in security_groups_in_use:
delete_candidates.append(group)
if args.delete:
print("We will now delete security groups identified to not be in use.")
for group in delete_candidates:
security_group = ec2.SecurityGroup(group)
try:
security_group.delete()
except Exception as e:
print(e)
print("{0} requires manual remediation.".format(security_group.group_name))
else:
print("The list of security groups to be removed is below.")
print("Run this again with `-d` to remove them")
for group in sorted(delete_candidates):
print(" " + group)
print("---------------")
print("Activity Report")
print("---------------")
print("Total number of Security Groups evaluated: {0:d}".format(len(all_groups)))
print("Total number of EC2 Instances evaluated: {0:d}".format(len(reservations)))
print("Total number of Load Balancers evaluated: {0:d}".format(len(elb_dict['LoadBalancerDescriptions']) +
len(elb2_dict['LoadBalancers'])))
print("* Sub Total number of ELB evaluated: {0:d}".format(len(elb_dict['LoadBalancerDescriptions'])))
print("* Sub Total number of ALB evaluated: {0:d}".format(len(elb2_dict['LoadBalancers'])))
print("Total number of RDS Instances evaluated: {0:d}".format(len(rds_dict['DBInstances'])))
print("Total number of Elasticache Clusters evaluated: {0:d}".format(len(cache_dict['CacheClusters'])))
print("Total number of Network Interfaces evaluated: {0:d}".format(len(eni_dict['NetworkInterfaces'])))
print("Total number of Security Groups in-use evaluated: {0:d}".format(len(security_groups_in_use)))
if args.delete:
print("Total number of Unused Security Groups deleted: {0:d}".format(len(delete_candidates)))
else:
print("Total number of Unused Security Groups targeted for removal: {0:d}".format(len(delete_candidates)))
# For each security group in the total list, if not in the "used" list, flag for deletion
# If running with a "--delete" flag, delete the ones flagged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment