Use Python to Add AWS Security Group Rules from a List of IPs

Have you ever had a list of IP addresses that you wanted to allow inbound traffic from in an AWS security group, but didn’t want to manually put them in one at a time? You’re in luck! Here’s a little Python script I wrote that will read in a list of IPs from a CSV file, and create security group rules for each address in the security group you specify, automatically.

First, here’s the Python script, then I’ll explain a bit about it (and some caveats) at the end….

import boto3
import csv

### Customizable variables:
profile = "prod"
security_group_id = "sg-11122333"
port = 25
region = "us-east-1"
CSV_file = 'O365 Exchange Online Protection.csv'
####

# Read in the list of IPs:
with open((CSV_file), 'r') as f:
reader = csv.reader(f)
IPlist = list(reader)

# Start a session, specifying profile credentials and region:
session = boto3.session.Session(profile_name=(profile),region_name=(region))
ec2 = session.resource('ec2')
SG = ec2.SecurityGroup(security_group_id)

# First, we remove all existing rules in the group:
SG.revoke_ingress(IpPermissions=SG.ip_permissions)

#Now, we add the new rules using IPs from the CSV:
for IP in IPlist:
IPstring = " ".join(str(x) for x in IP)
SG.authorize_ingress(IpProtocol="tcp",CidrIp=(IPstring),FromPort=(port),ToPort=(port))

OK, so that’s the very basic script, which obviously can have many alterations for your specific needs. To help get you going, there are a few things to note:

  • As of this writing, VPC security groups will only hold up to 50 rules, so if you have a longer list of IPs (if you’re whitelisting Microsoft Office 365 addresses, for example), then you’ll need to break up the IP list into chunks of 50, or you’ll get an error.
  • The variables are defined at the top.
    • You’ll want to set the profile variable to match whatever you called the profile you’re using for your computer/account.
    • This script expects the security group to already exist, so you must specify it up front.
    • Whatever port # you specify here will be given TCP inbound permission for every IP address in your CSV.
    • If you don’t provide an absolute path, then it will look for the CSV file to be in the same directory the script is in (as I have it above).
  • Notice about mid-way down in this script there is a line that removes ALL existing rules from this group. The idea here is that you’ve created a dedicated security group specifically to only hold these rules, so deleting everything already there is ok. The reason this line is necessary is because you may get an updated list in a few months and want to easily update your list. Rather than build in logic to leave existing rules and delete obsolete ones while adding new ones (and checking the total number remains under 50), it was easier to make this basic script just delete everything every time you have an updated list. Obviously, you wouldn’t want to do it this way if you’re adding rules to a security group with other rules already there that you care about. (If you end up with many groups (one for port 443, one for port 80, one for port 25, first 50 rules, second 50 rules, etc.) then what I do is create an “umbrella” group that allows traffic from all the individual groups, and just add that single umbrella group to things that need it in AWS. (And of course, if you have that many permutations, then you’d want to further automate this procedure to do all the ports, and files, etc., so you don’t have to run a bunch of individual scripts, but that’s beyond the scope of this basic post.))

That’s it – I hope this saves you a little time and headaches!

Steve