Package: simplesecuritygroups
OverviewManaging your Amazon Web Services (AWS) Security groups through Cloudformation templates is a great way of handling the creation & updating of all your rules.
But it’s a horribly longwinded way of writing out your rules, and get’s a bit unwieldy once you hit a certain number.There are great api’s out there (like boto), that let you programatically create your security group objects, but then you then have the headache of writing code to apply them and update tehm, and the inevitable debugging that ensues.  Not to mention the horror you face when you hit the maximum API requests/s.simplesecuritygroups aim to give you the power and flexibility of python when defining your rules, but rather than directly setting them up, output a familiar Cloudformation template you can use to apply your rules.Define your security groups using simplesecurity groupsOutput the Cloudformation templateApply using your normal methods!InstallationUsing pip:$ pip install simplesecuritygroupsGeneral Things You should KnowMost methods support chaining.  i.e. they return the class instance when they’re called. This allows for method chaining like you’ll see in the methods below.When adding a rule, most parameters can be lists.  This includes ports, protocols, targets.When adding ingress / egress rules outside of a security group, you can suggest a name for the rule.  I say suggest, because if you provide any of the parameters as lists, it’s going to ignore it and output a horribly descriptive name :)Port syntax.  simplesecuritygroups don’t care if you pass the port as a string or an integer.  It’ll still get output as a string in the template.  You can specify a from and to range using the syntax: “8000..8005”Example UsageThese examples all assume you’re using VPC security groups.  Some old accounts may be using old style EC2 security groups, in which case I’m not sure if this library will work for you!  I hope to test at some point…Create a basic security group template with a webserver security group that allows incomming access on http / https portsfromsimplesecuritygroups.templateimportSecurityGroups,SecurityGroupmytemplate=(SecurityGroups("Example Security Group Template").add_resource(SecurityGroup("WebserverSecurityGroup","My Webserver Security Group","[MyAWSVPCID]").ingress("tcp",[80,443])))printmytemplateResult:{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Example Security Group Template",
    "Parameters": {},
    "Resources": {
        "WebserverSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "My Webserver Security Group",
                "VpcId": "[MyAWSVPCID]",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "80",
                        "ToPort": "80",
                        "CidrIp": "0.0.0.0/0"
                    },
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "443",
                        "ToPort": "443",
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        }
    }
}Use a Cloudformation template parameter so the template can be re-used for multiple environmentsfromsimplesecuritygroups.templateimportSecurityGroups,SecurityGroupmytemplate=(SecurityGroups("Example Security Group Template").add_parameter("VPCID","The ID of your VPC").add_resource(SecurityGroup("WebserverSecurityGroup","My Webserver Security Group",{"Ref":"VPCID"}).ingress("tcp",[80,443])))printmytemplateAdd a rule outside of a Security Group(This is often necessary to avoid cirucular dependencies)fromsimplesecuritygroups.templateimportSecurityGroups,SecurityGroupmytemplate=(SecurityGroups("Example Security Group Template").add_parameter("VPCID","The ID of your VPC").add_resource(SecurityGroup("WebserverSecurityGroup","My Webserver Security Group",{"Ref":"VPCID"}).ingress("tcp",[80,443])).add_resource(SecurityGroup("LogserverSecurityGroup","My Logserver Security Group, {"Ref": "VPCID"})).pair("WebserverSecurityGroup","tcp",20154,"LogServerSecurityGroup","WebserverLogserverLogging"))printmytemplateNOTE: the .pair is just a timesaver method, equivilent to doing:.ingress("LogserverSecurityGroup","tcp",20154,"WebserverSecurityGroup").egress("WebserverSecurityGroup","tcp",20154,"LogserverSecurityGroup")Result:{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Example Security Group Template",
    "Parameters": {
        "VPCID": {
            "Description": "The ID of your VPC",
            "Type": "String"
        }
    },
    "Resources": {
        "WebserverSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "My Webserver Security Group",
                "VpcId": {
                    "Ref": "VPCID"
                },
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "80",
                        "ToPort": "80",
                        "CidrIp": "0.0.0.0/0"
                    },
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "443",
                        "ToPort": "443",
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        },
        "WebserverLogserverLoggingIngress": {
            "Type": "AWS::EC2::SecurityGroupIngress",
            "Properties": {
                "GroupId": {
                    "Ref": "LogServerSecurityGroup"
                },
                "IpProtocol": "tcp",
                "FromPort": "20154",
                "ToPort": "20154",
                "SourceSecurityGroupId": {
                    "Ref": "WebserverSecurityGroup"
                }
            }
        },
        "WebserverLogserverLoggingEgress": {
            "Type": "AWS::EC2::SecurityGroupEgress",
            "Properties": {
                "GroupId": {
                    "Ref": "WebserverSecurityGroup"
                },
                "IpProtocol": "tcp",
                "FromPort": "20154",
                "ToPort": "20154",
                "DestinationSecurityGroupId": {
                    "Ref": "LogServerSecurityGroup"
                }
            }
        }
    }
}