From 3beffde63eef30a18fe02688aea7eb97441ecdc4 Mon Sep 17 00:00:00 2001 From: Rai Nunes Date: Mon, 4 May 2020 04:07:06 -0300 Subject: [PATCH] Improved by adding EvenOrOdd tag allowing to have the double of security groups because of the limite of rules --- update_security_groups_lambda/README.md | 4 +- .../update_security_groups.py | 62 +++++++++++-------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/update_security_groups_lambda/README.md b/update_security_groups_lambda/README.md index 24a24dc..ffdb8aa 100644 --- a/update_security_groups_lambda/README.md +++ b/update_security_groups_lambda/README.md @@ -15,12 +15,14 @@ For each protocol, create 2 security groups and put the following 3 tags on each * **Name**: `cloudfront_g` * **AutoUpdate**: `true` * **Protocol**: `http` (or some other value, depends on what you name your protocols in the code) + * **EvenOrOdd**: `even` (or odd) 2. A regional ingress security group: * **Name**: `cloudfront_r` * **AutoUpdate**: `true` * **Protocol**: `http` (or some other value, depends on what you name your protocols in the code) + * **EvenOrOdd**: `even` (or odd) -If you allow both HTTP and HTTPS, for example, you will have 4 security groups that you will need to attach to your load balancer, EC2 instance, or other internet-facing ENI. +If you allow both HTTP and HTTPS, for example, you will have 8 security groups that you will need to attach to your load balancer, EC2 instance, or other internet-facing ENI. ## Event Source diff --git a/update_security_groups_lambda/update_security_groups.py b/update_security_groups_lambda/update_security_groups.py index 16e3f33..28b99b7 100644 --- a/update_security_groups_lambda/update_security_groups.py +++ b/update_security_groups_lambda/update_security_groups.py @@ -13,12 +13,13 @@ # Ports your application uses that need inbound permissions from the service for # If all you're doing is HTTPS, this can be simply { 'https': 443 } -INGRESS_PORTS = { 'http' : 80, 'https': 443, 'example': 8080 } +INGRESS_PORTS = { 'https': 443 } # Tags which identify the security groups you want to update # For a group to be updated it will need to have 3 properties that are true: # 1. It has to be tagged 'Protocol: X' (Where 'X' is one of your INGRESS_PORTS above) # 2. It has to be tagged 'Name: cloudfront_g' or 'Name: cloudfront_r' # 3. It has to be tagged 'AutoUpdate: true' +# 4. It has to be tagged 'EvenOrOdd: X' (Where 'X' is `even` or `odd`) # If any of these 3 are not true, the security group will be unmodified. GLOBAL_SG_TAGS = { 'Name': 'cloudfront_g', 'AutoUpdate': 'true' } REGION_SG_TAGS = { 'Name': 'cloudfront_r', 'AutoUpdate': 'true' } @@ -99,31 +100,35 @@ def update_security_groups(new_ranges, rangeType): # All the security groups we will need to find. allSGs = INGRESS_PORTS.keys() + allTypes = ['even', 'odd']; # Iterate over every group, doing its global and regional versions + for curGroup in allSGs: - tagToFind = {} - if rangeType == "GLOBAL": - tagToFind = GLOBAL_SG_TAGS - else: - tagToFind = REGION_SG_TAGS - tagToFind['Protocol'] = curGroup - rangeToUpdate = get_security_groups_for_update(client, tagToFind) - msg = 'tagged Name: {}, Protocol: {} to update'.format( tagToFind["Name"], curGroup ) - logging.info('Found {} groups {}'.format( str(len(rangeToUpdate)), msg ) ) - - if len(rangeToUpdate) == 0: - result.append( 'No groups {}'.format(msg) ) - logging.warning( 'No groups {}'.format(msg) ) - else: - if update_security_group(client, rangeToUpdate[0], new_ranges, INGRESS_PORTS[curGroup] ): - result.append('Security Group {} updated.'.format( rangeToUpdate[0]['GroupId'] ) ) + for curType in allTypes: + tagToFind = {} + if rangeType == "GLOBAL": + tagToFind = GLOBAL_SG_TAGS + else: + tagToFind = REGION_SG_TAGS + tagToFind['Protocol'] = curGroup + tagToFind['EvenOrOdd'] = curType + rangeToUpdate = get_security_groups_for_update(client, tagToFind) + msg = 'tagged Name: {}, Protocol: {} to update'.format( tagToFind["Name"], curGroup ) + logging.info('Found {} groups {}'.format( str(len(rangeToUpdate)), msg ) ) + + if len(rangeToUpdate) == 0: + result.append( 'No groups {}'.format(msg) ) + logging.warning( 'No groups {}'.format(msg) ) else: - result.append('Security Group {} unchanged.'.format( rangeToUpdate[0]['GroupId'] ) ) + if update_security_group(client, rangeToUpdate[0], new_ranges, INGRESS_PORTS[curGroup], curType ): + result.append('Security Group {} updated.'.format( rangeToUpdate[0]['GroupId'] ) ) + else: + result.append('Security Group {} unchanged.'.format( rangeToUpdate[0]['GroupId'] ) ) return result -def update_security_group(client, group, new_ranges, port): +def update_security_group(client, group, new_ranges, port, even_odd): added = 0 removed = 0 @@ -140,18 +145,25 @@ def update_security_group(client, group, new_ranges, port): to_revoke.append(range) logging.debug((group['GroupId'] + ": Revoking " + cidr + ":" + str(permission['ToPort']))) + x = 0 for range in new_ranges: - if old_prefixes.count(range) == 0: - to_add.append({ 'CidrIp': range }) - logging.debug((group['GroupId'] + ": Adding " + range + ":" + str(permission['ToPort']))) + x += 1 + if (even_odd == "even" and ((x % 2) == 0)) or (even_odd == "odd" and ((x % 2) == 1)): + if old_prefixes.count(range) == 0: + to_add.append({ 'CidrIp': range }) + logging.debug((group['GroupId'] + ": Adding " + range + ":" + str(permission['ToPort']))) removed += revoke_permissions(client, group, permission, to_revoke) added += add_permissions(client, group, permission, to_add) else: to_add = list() + x = 0 for range in new_ranges: - to_add.append({ 'CidrIp': range }) - logging.info((group['GroupId'] + ": Adding " + range + ":" + str(port))) + x += 1 + if (even_odd == "even" and ((x % 2) == 0)) or (even_odd == "odd" and ((x % 2) == 1)): + to_add.append({ 'CidrIp': range }) + logging.info((group['GroupId'] + ": Adding " + range + ":" + str(port))) + permission = { 'ToPort': port, 'FromPort': port, 'IpProtocol': 'tcp'} added += add_permissions(client, group, permission, to_add) @@ -227,4 +239,4 @@ def get_security_groups_for_update(client, security_group_tag): ] } -''' +''' \ No newline at end of file