From 5f1dd479540f4b5cc86ce0aeefca2dc73da7b142 Mon Sep 17 00:00:00 2001 From: Thomas van Noort Date: Fri, 15 Nov 2013 10:14:13 +0100 Subject: [PATCH] Allow for reuse of allocated but unassociated Elastic IPs. --- library/cloud/ec2_eip | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/library/cloud/ec2_eip b/library/cloud/ec2_eip index 1c5db8cf4c..420f2cc9f9 100644 --- a/library/cloud/ec2_eip +++ b/library/cloud/ec2_eip @@ -53,6 +53,11 @@ options: required: false default: false version_added: "1.4" + reuse: + description: + - Reuse an EIP that is not associated to an instance (when available), instead of allocating a new one. + required: false + default: false requirements: [ "boto" ] author: Lorin Hochstein notes: @@ -198,13 +203,27 @@ def ip_is_associated_with_instance(ec2, public_ip, instance_id, module): return False -def allocate_address(ec2, domain, module): - """ Allocate a new elastic IP address and return it """ +def allocate_address(ec2, domain, module, reuse): + """ Allocate a new elastic IP address (when needed) and return it """ # If we're in check mode, nothing else to do if module.check_mode: module.exit_json(change=True) - address = ec2.allocate_address(domain=domain) + if reuse: + if domain: + domain_filter = { 'domain' : domain } + else: + domain_filter = { 'domain' : 'standard' } + all_addresses = ec2.get_all_addresses(filters=domain_filter) + + unassociated_addresses = filter(lambda a: a.instance_id is None, all_addresses) + if unassociated_addresses: + address = unassociated_addresses[0]; + else: + address = ec2.allocate_address(domain=domain) + else: + address = ec2.allocate_address(domain=domain) + return address @@ -252,6 +271,7 @@ def main(): ec2_access_key = dict(required=False, aliases=['EC2_ACCESS_KEY']), region = dict(required=False, aliases=['ec2_region']), in_vpc = dict(required=False, choices=BOOLEANS, default=False), + reuse = dict(required=False, choices=BOOLEANS, default=False), ), supports_check_mode=True ) @@ -272,18 +292,19 @@ def main(): state = module.params.get('state') in_vpc = module.params.get('in_vpc') domain = "vpc" if in_vpc else None + reuse = module.params.get('reuse'); if state == 'present': if public_ip is None: if instance_id is None: - address = allocate_address(ec2, domain, module) + address = allocate_address(ec2, domain, module, reuse) module.exit_json(changed=True, public_ip=address.public_ip) else: # Determine if the instance is inside a VPC or not instance = find_instance(ec2, instance_id, module) if instance.vpc_id != None: domain = "vpc" - address = allocate_address(ec2, domain, module) + address = allocate_address(ec2, domain, module, reuse) else: address = find_address(ec2, public_ip, module) associate_ip_and_instance(ec2, address, instance_id, module)