How To Update AWS Security Groups Automatically With Python

Recently I was working on a project and had a little complication during the process. The database from which I had to read data was hidden behind the firewall because of security reasons. And I had to connect to it from the server that doesn’t have stable IP, but does have a static DNS.

The script to develop had to connect to db several times per day, so manually changing security groups on AWS didn’t make any sense. Also as I find out during the research, you can’t put DNS in AWS security group. So the only solution that remain was to create a script that will check the settings and will update security groups accordingly when IP of the server with the script changes.

If you are familiar with AWS CLI you know you can do that using few commands and done! Then you put those commands in bash script and you have an automated process. Actually, there is no need for me to explain all these here, because if the person is looking for this solution, this person will definitely find this StackOverflow post. In one of the answers there is a script that totally solves this. Also in other posts there are useful links to the documentation that explain how the things work.

But I have no clue how bash scripts work… Also I am using Windows and again, have no clue how to encapsulate AWS CLI commands into a script. So I started to look for solution using Python. And I found it. It is called – boto3. This is the library that provides you with the interface to AWS CLI and allows you to do the same things using Python.

Install and configure AWS-CLI

First what you need is to install and configure AWS-CLI. At the current moment Amazon is working on aws-cli version 2 and it is still in developer’s mode. But as I am the person that looks into the future, the script that was developed is using this version of CLI.

All the instructions regarding the installation you can find in AWS docs. Just follow it and you will have AWS-CLI installed on your machine. Next step will be to configure it. To do this just type the following command in your terminal:

aws2 configure

Pretty obvious, no? :D. During the configuration process just pass your credentials: Access Key and Secret Key, set up default region and default format (I have chosen JSON here).

Once it is done it’s time to set up our Python environment.

Install Boto3

Using your Python package manager install Boto3. I use Pip so in my case it was

pip install boto3

Use the following template to create your script

Here below I will leave the link to my github with entire code, but the logic is pretty simple: we check our IP, then using boto3 we check the current security groups rules, if IP that is set there is the same as ours – we’re ok, if not, we change the rule.

Script in Github. Script here. Depends on what you prefer 😉

import requests

import boto3

from botocore.exceptions import ClientError

 

GROUP_ID = 'GROUP-ID'

RULE_DESCRIPTION = 'Rule Description'

NEW_IP = requests.get('http://checkip.amazonaws.com').text[:-1] + '/32'

OLD_IP = ''

 

ec2 = boto3.client('ec2')

 

try:

    response = ec2.describe_security_groups(GroupIds=[GROUP_ID])

except ClientError as e:

    print(e)

 

sg = response['SecurityGroups']

for el in range(len(sg)):

    if sg[el]['GroupId'] == GROUP_ID:

        ip_pems = sg[el]['IpPermissions']

        for i in range(len(ip_pems)):

            if ip_pems[i]['IpRanges'][0]['Description'] == RULE_DESCRIPTION:

                OLD_IP = ip_pems[i]['IpRanges'][0]['CidrIp']

                print('Old office Ip %s' % OLD_IP)

 

if (OLD_IP != NEW_IP) & (OLD_IP != ''):

    try:

        d = ec2.revoke_security_group_ingress(

            GroupId = GROUP_ID,

            IpPermissions=[

                {

                    'FromPort': 3306,

                    'ToPort': 3306,

                    'IpProtocol': 'tcp',

                    'IpRanges': [

                        {

                            'CidrIp': OLD_IP,

                            'Description': RULE_DESCRIPTION

                        }

                    ]

                }

            ]

        )

        print('Ingress successfully removed %s' % d)

    except ClientError as e:

        print(e)

    

    try:

        d = ec2.authorize_security_group_ingress(

            GroupId = GROUP_ID,

            IpPermissions=[

                {

                    'FromPort': 3306,

                    'ToPort': 3306,

                    'IpProtocol': 'tcp',

                    'IpRanges': [

                        {

                            'CidrIp': NEW_IP,

                            'Description': RULE_DESCRIPTION

                        }

                    ]

                }

            ]

        )

        print('Ingress successfully set %s' % d)

    except ClientError as e:

        print(e) 

Leave a Reply

Your email address will not be published. Required fields are marked *