Skip to content

Instantly share code, notes, and snippets.

@bwhaley
Created July 23, 2014 20:48
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 bwhaley/5ccbc7fa761d984e6013 to your computer and use it in GitHub Desktop.
Save bwhaley/5ccbc7fa761d984e6013 to your computer and use it in GitHub Desktop.
sg_clone.py
# Quick and dirty code to clone an AWS security group
# Examines a provided source group for all its rules and adds those to a specified destination group
# Caveats:
# - If the destination group does not exist, it will be created as an EC2 group (e.g. not in a VPC)
# - Existing rules in the destination group are NOT deleted
import sys
import argparse
import re
import collections
import boto.ec2
SecurityGroupRule = collections.namedtuple("SecurityGroupRule", ["ip_protocol", "from_port", "to_port", "cidr_ip"])
def connect(region):
return boto.ec2.connect_to_region(region)
def do_clone(c, dest, rules):
sg = get_or_create(c, dest)
modify_sg(c, sg, rules)
def is_id(group):
if re.search('^sg-[0-9a-z]{8}$', group):
return True
else:
return False
def get_or_create(c, group, description=""):
sg = get_group(c, group)
if not sg:
if is_id(group):
raise Exception("Group does not exist and not creating group named %s" % group)
print "Creating group '%s'..." % group
sg = c.create_security_group(group, "A group for %s" % group)
return sg
def get_group(c, group):
groups = [g for g in c.get_all_security_groups() if g.name == group or g.id == group]
if not groups:
return None
if len(groups) == 1:
return groups.pop(0)
else:
raise Exception("Multiple groups found for %s" % group)
def modify_sg(c, group, rules):
for rule in rules:
group.authorize(ip_protocol=rule.ip_protocol,
from_port=rule.from_port,
to_port=rule.to_port,
cidr_ip=rule.cidr_ip)
def source_group_rules(c, group):
sg = get_group(c, group)
rules = []
for rule in sg.rules:
for grant in rule.grants:
rules.append(SecurityGroupRule(rule.ip_protocol, rule.from_port, rule.to_port, grant.cidr_ip))
return rules
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Clone an AWS security group')
parser.add_argument('-s', '--source', help='Source security group name or ID', required=True)
parser.add_argument('-d', '--dest', help='Destination security group name or ID. ' \
'Group will be created if it does not exist', required=True)
parser.add_argument('-r', '--region', help='AWS region (defaults to us-east-1)', default="us-east-1")
args = parser.parse_args()
c = connect(args.region)
rules = source_group_rules(c, args.source)
do_clone(c, args.dest, rules)
print "Done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment