Search code examples
pythonamazon-web-servicesbotords

AWS DB security groups using boto (catching exceptions)


I'm creating db security groups using boto. I want something like this:

  • If the db security group exists, check for the given rule, in case it doesn't have it, authorize the group with the rule
  • If the group doesn't exists, create it, and authorize the group with the given rule

This is my code so far:

import boto.rds
conn = boto.rds.connect_to_region("{{region}}", aws_access_key_id = '{{ keyid }}', aws_secret_access_key = '{{ key }}')

group = conn.get_all_dbsecurity_groups('{{name}}')

if group:
    group[0].authorize({{ connection_type }} = '{{ details }}')
else: 
    sg = conn.create_dbsecurity_group('{{ name }}', '{{ description }}')
    sg.authorize({{ connection_type }} = '{{ details }}')

I'm getting this errors:

DBSecurityGroup not found

 Traceback (most recent call last):
    File "/usr/local/src/dbgroups.py", line 18, in <module>
        group = conn.get_all_dbsecurity_groups('kdkdkdk')
    File "/usr/local/lib/python2.7/site-packages/boto/rds/__init__.py", line 923, in get_all_dbsecurity_groups
        [('DBSecurityGroup', DBSecurityGroup)])
    File "/usr/local/lib/python2.7/site-packages/boto/connection.py", line 1186, in get_list
        raise self.ResponseError(response.status, response.reason, body)
    boto.exception.BotoServerError: BotoServerError: 404 Not Found
    <ErrorResponse xmlns="http://rds.amazonaws.com/doc/2013-05-15/">
        <Error>
            <Type>Sender</Type>
            <Code>DBSecurityGroupNotFound</Code>
            <Message>DBSecurityGroup dbgrouptesting not found.</Message>
        </Error>
        <RequestId>3b9af082-fe3c-11e4-bd53-e9bc444dcde5</RequestId>
    </ErrorResponse>

Authorization already exists

Traceback (most recent call last):
    File "/usr/local/src/dbgroups.py", line 24, in <module>
        group[0].authorize(cidr_ip = '0.0.0.0/0')
    File "/usr/local/lib/python2.7/site-packages/boto/rds/dbsecuritygroup.py", line 109, in authorize
        group_owner_id)
    File "/usr/local/lib/python2.7/site-packages/boto/rds/__init__.py", line 995, in authorize_dbsecurity_group
        DBSecurityGroup)
    File "/usr/local/lib/python2.7/site-packages/boto/connection.py", line 1208, in get_object
        raise self.ResponseError(response.status, response.reason, body)
    boto.exception.BotoServerError: BotoServerError: 400 Bad Request
    <ErrorResponse xmlns="http://rds.amazonaws.com/doc/2013-05-15/">
        <Error>
            <Type>Sender</Type>
            <Code>AuthorizationAlreadyExists</Code>
            <Message>Authorization already exists: 0.0.0.0/0</Message>
        </Error>
    <RequestId>5fc68ac7-fe3b-11e4-b082-0b206bb7b937</RequestId>
    </ErrorResponse>

Solution

  • Rather than return a nil or empty response, it looks like that boto function throws a DBSecurityGroupNotFound exception when the requested security group does not exist. So change your code to use try/except rather than 'if group'.

    Something like this:

    try:
      group = conn.get_all_dbsecurity_groups('{{name}}')
      group[0].authorize({{connection_type}} = '{{details}}')
    except boto.exception.BotoServerError as e:
      if (e.status == 400 && e.error_code == 'DBSecurityGroupNotFound'):
        sg = conn.create_dbsecurity_group('{{name}}', '{{description}}')
        sg.authorize({{connection_type}} = '{{details}}')
      else:
        raise;
    

    You'll also need to handle potential errors from the 'authorize' calls.

    Alternatively, get a list of all security groups upfront and then find the desired security group in that list and proceed accordingly.