Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to ec2_eip to associate with a secondary ip address #19484

Merged
merged 1 commit into from
Dec 19, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 25 additions & 12 deletions lib/ansible/modules/cloud/amazon/ec2_eip.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@
required: false
default: false
version_added: "2.0"
private_ip_address:
description:
- The primary or secondary private IP address to associate with the Elastic IP address.
required: False
default: None
version_added: "2.3"
extends_documentation_fragment:
- aws
- ec2
Expand All @@ -82,6 +88,8 @@
'''

EXAMPLES = '''
# Note: These examples do not set authentication details, see the AWS Guide for details.

- name: associate an elastic IP with an instance
ec2_eip:
device_id: i-1212f003
Expand Down Expand Up @@ -109,7 +117,8 @@
device_id: i-1212f003

- name: allocate a new elastic IP without associating it to anything
action: ec2_eip
ec2_eip:
state: present
register: eip

- name: output the IP
Expand Down Expand Up @@ -157,19 +166,19 @@ class EIPException(Exception):
pass


def associate_ip_and_device(ec2, address, device_id, check_mode, isinstance=True):
def associate_ip_and_device(ec2, address, private_ip_address, device_id, check_mode, isinstance=True):
if address_is_associated_with_device(ec2, address, device_id, isinstance):
return {'changed': False}

# If we're in check mode, nothing else to do
if not check_mode:
if isinstance:
if address.domain == "vpc":
res = ec2.associate_address(device_id, allocation_id=address.allocation_id)
res = ec2.associate_address(device_id, allocation_id=address.allocation_id, private_ip_address=private_ip_address)
else:
res = ec2.associate_address(device_id, public_ip=address.public_ip)
res = ec2.associate_address(device_id, public_ip=address.public_ip, private_ip_address=private_ip_address)
else:
res = ec2.associate_address(network_interface_id=device_id, allocation_id=address.allocation_id)
res = ec2.associate_address(network_interface_id=device_id, allocation_id=address.allocation_id, private_ip_address=private_ip_address)
if not res:
raise EIPException('association failed')

Expand Down Expand Up @@ -286,7 +295,7 @@ def find_device(ec2, module, device_id, isinstance=True):
raise EIPException("could not find instance" + device_id)


def ensure_present(ec2, module, domain, address, device_id,
def ensure_present(ec2, module, domain, address, private_ip_address, device_id,
reuse_existing_ip_allowed, check_mode, isinstance=True):
changed = False

Expand All @@ -306,12 +315,12 @@ def ensure_present(ec2, module, domain, address, device_id,
if len(instance.vpc_id) > 0 and domain is None:
raise EIPException("You must set 'in_vpc' to true to associate an instance with an existing ip in a vpc")
# Associate address object (provided or allocated) with instance
assoc_result = associate_ip_and_device(ec2, address, device_id,
assoc_result = associate_ip_and_device(ec2, address, private_ip_address, device_id,
check_mode)
else:
instance = find_device(ec2, module, device_id, isinstance=False)
# Associate address object (provided or allocated) with instance
assoc_result = associate_ip_and_device(ec2, address, device_id,
assoc_result = associate_ip_and_device(ec2, address, private_ip_address, device_id,
check_mode, isinstance=False)

if instance.vpc_id:
Expand Down Expand Up @@ -351,11 +360,15 @@ def main():
default=False),
release_on_disassociation=dict(required=False, type='bool', default=False),
wait_timeout=dict(default=300),
private_ip_address=dict(required=False, default=None, type='str')
))

module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True
supports_check_mode=True,
required_together=[
('device_id', 'private_ip_address'),
]
)

if not HAS_BOTO:
Expand All @@ -366,6 +379,7 @@ def main():
device_id = module.params.get('device_id')
instance_id = module.params.get('instance_id')
public_ip = module.params.get('public_ip')
private_ip_address = module.params.get('private_ip_address')
state = module.params.get('state')
in_vpc = module.params.get('in_vpc')
domain = 'vpc' if in_vpc else None
Expand All @@ -392,9 +406,8 @@ def main():

if state == 'present':
if device_id:
result = ensure_present(ec2, module, domain, address, device_id,
reuse_existing_ip_allowed,
module.check_mode, isinstance=is_instance)
result = ensure_present(ec2, module, domain, address, private_ip_address, device_id,
reuse_existing_ip_allowed, module.check_mode, isinstance=is_instance)
else:
address = allocate_address(ec2, domain, reuse_existing_ip_allowed)
result = {'changed': True, 'public_ip': address.public_ip, 'allocation_id': address.allocation_id}
Expand Down