ec2_group: Auto create missing groups referenced in rules

Suppose a pair of groups, A and B, depending on each other. One solution
for breaking the circular dependency at playbook level:

    - declare group A without dependencies
    - declare group B depending on A
    - declare group A depending on B

This patch breaks the dependency at module level. Whenever a depended-on
group is missing it's first created. This approach requires only two tasks:

    - declare group A depending on B (group B will be auto created)
    - declare group B depending on A

When creating a group EC2 requires you to pass the group description. In
order to fullfil this, rules now accept the `group_desc` param. Note
that group description can't be changed once the group is created so
it's nice to keep descriptions in sync.

Concrete example:

- ec2_group:
    name: mysql-client
    description: MySQL Client
    rules_egress:
      - proto: tcp
        from_port: 3306
        to_port: 3306
        group_name: mysql-server
        group_desc: MySQL Server

- ec2_group:
    name: mysql-server
    description: MySQL Server
    rules:
      - proto: tcp
        from_port: 3306
        to_port: 3306
        group_name: mysql-client
This commit is contained in:
Maykel Moya 2014-03-20 16:38:54 +01:00
parent 77d7165dde
commit 649fcd3e1c

View file

@ -145,6 +145,7 @@ def get_target_from_rule(rule, name, groups):
group_id = None
group_name = None
ip = None
target_group_created = False
if 'group_id' in rule and 'cidr_ip' in rule:
module.fail_json(msg="Specify group_id OR cidr_ip, not both")
elif 'group_name' in rule and 'cidr_ip' in rule:
@ -161,10 +162,19 @@ def get_target_from_rule(rule, name, groups):
group_id = group.id
groups[group_id] = group
groups[group_name] = group
else:
if not rule.get('group_desc', '').strip():
module.fail_json(msg="group %s will be automatically created by rule %s and no description was provided" % (group_name, rule))
if not module.check_mode:
auto_group = ec2.create_security_group(group_name, rule['group_desc'], vpc_id=vpc_id)
group_id = auto_group.id
groups[group_id] = auto_group
groups[group_name] = auto_group
target_group_created = True
elif 'cidr_ip' in rule:
ip = rule['cidr_ip']
return group_id, ip
return group_id, ip, target_group_created
def main():
@ -252,7 +262,9 @@ def main():
# Now, go through all provided rules and ensure they are there.
if rules:
for rule in rules:
group_id, ip = get_target_from_rule(rule, name, groups)
group_id, ip, target_group_created = get_target_from_rule(rule, name, groups)
if target_group_created:
changed = True
if rule['proto'] == 'all':
rule['proto'] = -1
@ -290,7 +302,9 @@ def main():
# Now, go through all provided rules and ensure they are there.
if rules_egress:
for rule in rules_egress:
group_id, ip = get_target_from_rule(rule, name, groups)
group_id, ip, target_group_created = get_target_from_rule(rule, name, groups)
if target_group_created:
changed = True
if rule['proto'] == 'all':
rule['proto'] = -1