From ad0ca929b58a8c18d40c0f2737b0d90aac0d470e Mon Sep 17 00:00:00 2001 From: Maykel Moya Date: Thu, 20 Mar 2014 16:38:54 +0100 Subject: [PATCH] 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 --- cloud/ec2_group | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/cloud/ec2_group b/cloud/ec2_group index d685b29aa06..ede8050c0a9 100644 --- a/cloud/ec2_group +++ b/cloud/ec2_group @@ -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