From eaa45dcbd9e0deef3b78145afa86d7fe7c8500fb Mon Sep 17 00:00:00 2001 From: Bret Martin Date: Fri, 4 Sep 2015 19:44:35 -0400 Subject: [PATCH 1/5] Add network_interfaces parameter to ec2 module to support launch-time ENIs --- cloud/amazon/ec2.py | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/cloud/amazon/ec2.py b/cloud/amazon/ec2.py index 9ad64c8e9fb..1b97d908b4a 100644 --- a/cloud/amazon/ec2.py +++ b/cloud/amazon/ec2.py @@ -240,6 +240,13 @@ options: required: false default: null aliases: [] + network_interfaces: + version_added: "2.0" + description: + - A list of existing network interfaces to attach to the instance at launch. When specifying existing network interfaces, none of the assign_public_ip, private_ip, vpc_subnet_id, group, or group_id parameters may be used. (Those parameters are for creating a new network interface at launch.) + required: false + default: null + aliases: [] author: - "Tim Gerla (@tgerla)" @@ -826,11 +833,21 @@ def create_instances(module, ec2, vpc, override_count=None): count_tag = module.params.get('count_tag') source_dest_check = module.boolean(module.params.get('source_dest_check')) termination_protection = module.boolean(module.params.get('termination_protection')) + network_interfaces = module.params.get('network_interfaces') # group_id and group_name are exclusive of each other if group_id and group_name: module.fail_json(msg = str("Use only one type of parameter (group_name) or (group_id)")) + if (network_interfaces and + (assign_public_ip or private_ip or vpc_subnet_id + or group_name or group_id)): + module.fail_json( + msg=str("network_interfaces must not be set when specifying " + + "assign_public_ip, private_ip, vpc_subnet_id, group, " + + "or group_id, which are used to create a new network " + + "interface.")) + vpc_id = None if vpc_subnet_id: if not vpc: @@ -926,11 +943,21 @@ def create_instances(module, ec2, vpc, override_count=None): interfaces = boto.ec2.networkinterface.NetworkInterfaceCollection(interface) params['network_interfaces'] = interfaces else: - params['subnet_id'] = vpc_subnet_id - if vpc_subnet_id: - params['security_group_ids'] = group_id + if network_interfaces: + interfaces = [] + for i, network_interface_id in enumerate(network_interfaces): + interface = boto.ec2.networkinterface.NetworkInterfaceSpecification( + network_interface_id=network_interface_id, + device_index=i) + interfaces.append(interface) + params['network_interfaces'] = \ + boto.ec2.networkinterface.NetworkInterfaceCollection(*interfaces) else: - params['security_groups'] = group_name + params['subnet_id'] = vpc_subnet_id + if vpc_subnet_id: + params['security_group_ids'] = group_id + else: + params['security_groups'] = group_name if volumes: bdm = BlockDeviceMapping() @@ -1284,6 +1311,7 @@ def main(): volumes = dict(type='list'), ebs_optimized = dict(type='bool', default=False), tenancy = dict(default='default'), + network_interfaces = dict(type='list') ) ) From a20a78a50c07214565b6e3859e9b6531d9ed6d0c Mon Sep 17 00:00:00 2001 From: Bret Martin Date: Sun, 6 Sep 2015 13:03:04 -0400 Subject: [PATCH 2/5] Remove aliases specification from documentation since there are none --- cloud/amazon/ec2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cloud/amazon/ec2.py b/cloud/amazon/ec2.py index 1b97d908b4a..3b2e59577d6 100644 --- a/cloud/amazon/ec2.py +++ b/cloud/amazon/ec2.py @@ -246,7 +246,6 @@ options: - A list of existing network interfaces to attach to the instance at launch. When specifying existing network interfaces, none of the assign_public_ip, private_ip, vpc_subnet_id, group, or group_id parameters may be used. (Those parameters are for creating a new network interface at launch.) required: false default: null - aliases: [] author: - "Tim Gerla (@tgerla)" From 5db3f14e94e88597d9f2f058a57b4512775d41eb Mon Sep 17 00:00:00 2001 From: Bret Martin Date: Sun, 6 Sep 2015 13:18:20 -0400 Subject: [PATCH 3/5] Add network_interfaces example --- cloud/amazon/ec2.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cloud/amazon/ec2.py b/cloud/amazon/ec2.py index 3b2e59577d6..420fac28f5f 100644 --- a/cloud/amazon/ec2.py +++ b/cloud/amazon/ec2.py @@ -358,6 +358,13 @@ EXAMPLES = ''' vpc_subnet_id: subnet-29e63245 assign_public_ip: yes +# Example using pre-existing network interfaces +- ec2: + key_name: mykey + instance_type: t2.small + image: ami-f005ba11 + network_interfaces: ['eni-deadbeef', 'eni-5ca1ab1e'] + # Launch instances, runs some tasks # and then terminate them From 44f3618dd3c06ef6b1af2b196c46a2d7575c35f8 Mon Sep 17 00:00:00 2001 From: Bret Martin Date: Sun, 6 Sep 2015 13:53:28 -0400 Subject: [PATCH 4/5] Add alias `network_interface` and accept a string for a single ENI --- cloud/amazon/ec2.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cloud/amazon/ec2.py b/cloud/amazon/ec2.py index 420fac28f5f..bd51bcd7ed3 100644 --- a/cloud/amazon/ec2.py +++ b/cloud/amazon/ec2.py @@ -246,6 +246,7 @@ options: - A list of existing network interfaces to attach to the instance at launch. When specifying existing network interfaces, none of the assign_public_ip, private_ip, vpc_subnet_id, group, or group_id parameters may be used. (Those parameters are for creating a new network interface at launch.) required: false default: null + aliases: ['network_interface'] author: - "Tim Gerla (@tgerla)" @@ -358,7 +359,13 @@ EXAMPLES = ''' vpc_subnet_id: subnet-29e63245 assign_public_ip: yes -# Example using pre-existing network interfaces +# Examples using pre-existing network interfaces +- ec2: + key_name: mykey + instance_type: t2.small + image: ami-f005ba11 + network_interface: eni-deadbeef + - ec2: key_name: mykey instance_type: t2.small @@ -950,6 +957,8 @@ def create_instances(module, ec2, vpc, override_count=None): params['network_interfaces'] = interfaces else: if network_interfaces: + if isinstance(network_interfaces, basestring): + network_interfaces = [network_interfaces] interfaces = [] for i, network_interface_id in enumerate(network_interfaces): interface = boto.ec2.networkinterface.NetworkInterfaceSpecification( @@ -1317,7 +1326,7 @@ def main(): volumes = dict(type='list'), ebs_optimized = dict(type='bool', default=False), tenancy = dict(default='default'), - network_interfaces = dict(type='list') + network_interfaces = dict(type='list', aliases=['network_interface']) ) ) From 27e9318ffea622136d34a8c7832312b46d6e6aaa Mon Sep 17 00:00:00 2001 From: Bret Martin Date: Sun, 6 Sep 2015 14:00:35 -0400 Subject: [PATCH 5/5] Use general-purpose parameter mutual exclusion code for network_interfaces --- cloud/amazon/ec2.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/cloud/amazon/ec2.py b/cloud/amazon/ec2.py index bd51bcd7ed3..14b278e76ba 100644 --- a/cloud/amazon/ec2.py +++ b/cloud/amazon/ec2.py @@ -852,15 +852,6 @@ def create_instances(module, ec2, vpc, override_count=None): if group_id and group_name: module.fail_json(msg = str("Use only one type of parameter (group_name) or (group_id)")) - if (network_interfaces and - (assign_public_ip or private_ip or vpc_subnet_id - or group_name or group_id)): - module.fail_json( - msg=str("network_interfaces must not be set when specifying " + - "assign_public_ip, private_ip, vpc_subnet_id, group, " + - "or group_id, which are used to create a new network " + - "interface.")) - vpc_id = None if vpc_subnet_id: if not vpc: @@ -1335,7 +1326,12 @@ def main(): mutually_exclusive = [ ['exact_count', 'count'], ['exact_count', 'state'], - ['exact_count', 'instance_ids'] + ['exact_count', 'instance_ids'], + ['network_interfaces', 'assign_public_ip'], + ['network_interfaces', 'group'], + ['network_interfaces', 'group_id'], + ['network_interfaces', 'private_ip'], + ['network_interfaces', 'vpc_subnet_id'], ], )