Need assist with syntax for EC2 assignment of Elastic IP Address

I want to finish off an Ansible playbook by assigning a static IP address to it. I want to do this at the end, because I think it takes a few minutes to take effect. Not sure if doing it at the beginning would cause Ansible to loose the connection or not.

I launch an instance like this

  • name: Launch instance
    local_action: ec2 keypair={{ keypair }} instance_type={{ instance_type }}
    image={{ image }} region={{ region }}
    aws_access_key={{ aws_access_key }}
    aws_secret_key={{ aws_secret_key }}
    group={{ security_group }} wait=true
    register: ec2

I’ve tried a couple of different ways, both fail.

  • name: associate testing.example.com with this instance
    local_action: ec2_eip instance_id={{ item.id }} ip=54.243.243.102 region=us-east-1
    with_items: ec2.instances

TASK: [missing | associate testing.example.com with this instance] ******
fatal: [54.198.204.2] => One or more undefined variables: ‘str object’ has no attribute ‘id’

  • name: associate testing.example.com with this instance
    local_action: ec2_eip instance_id={{ ec2.instance_ids[0] }} ip=54.243.243.102 region=us-east-1

TASK: [missing | associate testing.example.com with this instance] ******
fatal: [54.197.175.124] => One or more undefined variables: ‘ec2’ is undefined

Can somebody show me the correct syntax.

Thanks

mark

First run with the “-v” flag and see what the returns from the ec2 module looks like, which will help with testing how to use the resultant data.

My playbook looks like this

If I reverse the order, like this

  • name: Wait for SSH to come up
    local_action: wait_for host={{ item.public_dns_name }} port=22
    delay=60 timeout=320 state=started
    with_items: ec2.instances

  • name: associate test.example.com with this instance
    local_action: ec2_eip instance_id={{ item.id }} ip=54.123.243.14 region=us-east-1
    with_items: ec2.instances

it gets through those ok, but hangs in the middle of the next stanza.

So assigning an Elastic IP address disturbs the environment.

mark

Hi Mark.

This is the typical outcome of AWS’ flow. When you assign an EIP to an instance, you can forget about the public dns and public ip entries. they are updated according to the EIP.
As a tip, I am registering the output of the ec2_eip module and use that instead of querying the ec2 module’s results. One can also (supposedly) use the ec2_facts module or just output the added EIP to a file with the lineinfile module and read it from there or use the in-memory inventory with add_host.

FYI, here’s what ec2_facts gets:

`
[dvaida@scat ansible-aws]$ ansible -i host all --user=admin --private-key=ansible-ec2.pem -m ec2_facts
The authenticity of host ‘54.76.235.184 (54.76.235.184)’ can’t be established.
ECDSA key fingerprint is ec:11:61:76:a0:28:b5:83:10:a7:3c:b5:d8:02:71:bb.
Are you sure you want to continue connecting (yes/no)? yes
54.76.235.184 | success >> {
“ansible_facts”: {
“ansible_ec2_ami_id”: “ami-630fcb14”,
“ansible_ec2_ami_launch_index”: “0”,
“ansible_ec2_ami_manifest_path”: “(unknown)”,
“ansible_ec2_block_device_mapping_ami”: “/dev/sda”,
“ansible_ec2_block_device_mapping_root”: “/dev/sda”,
“ansible_ec2_hostname”: “ip-10-0-0-8.eu-west-1.compute.internal”,
“ansible_ec2_instance_action”: “none”,
“ansible_ec2_instance_id”: “i-9edd71dd”,
“ansible_ec2_instance_type”: “c3.2xlarge”,
“ansible_ec2_kernel_id”: “aki-52a34525”,
“ansible_ec2_local_hostname”: “ip-10-0-0-8.eu-west-1.compute.internal”,
“ansible_ec2_local_ipv4”: “10.0.0.8”,
“ansible_ec2_mac”: “06:31:2e:4a:82:e2”,
“ansible_ec2_metrics_vhostmd”: “<?xml version=\"1.0\" encoding=\"UTF-8\"?>”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_device_number”: “0”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_interface_id”: “eni-4fb93f38”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_ipv4_associations_54.76.235.184”: “10.0.0.8”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_local_hostname”: “ip-10-0-0-8.eu-west-1.compute.internal”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_local_ipv4s”: “10.0.0.8”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_mac”: “06:31:2e:4a:82:e2”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_owner_id”: “785351690827”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_public_hostname”: “ec2-54-76-235-184.eu-west-1.compute.amazonaws.com”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_public_ipv4s”: “54.76.235.184”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_security_group_ids”: “sg-0b10de6e”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_security_groups”: “allinone”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_subnet_id”: “subnet-ddca27aa”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_subnet_ipv4_cidr_block”: “10.0.0.0/24”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_vpc_id”: “vpc-9037d9f5”,
“ansible_ec2_network_interfaces_macs_06_31_2e_4a_82_e2_vpc_ipv4_cidr_block”: “10.0.0.0/16”,
“ansible_ec2_placement_availability_zone”: “eu-west-1a”,
“ansible_ec2_placement_region”: “eu-west-1”,
“ansible_ec2_profile”: “default-paravirtual”,
“ansible_ec2_public_hostname”: “ec2-54-76-235-184.eu-west-1.compute.amazonaws.com”,
“ansible_ec2_public_ipv4”: “54.76.235.184”,
“ansible_ec2_public_key”: “ssh-rsa XXX ansible-ec2\n”,
“ansible_ec2_reservation_id”: “r-a5fe14e6”,
“ansible_ec2_security_groups”: “allinone”,
“ansible_ec2_services_domain”: “amazonaws.com”,
“ansible_ec2_user_data”: null
},
“changed”: false
}

`
I believe this module should get better documentation.
Hope this helps you!

Dan is absolutely right, here is an example what he is saying. Thanks

  • name: Associate new EIP to the NAT Instance
    local_action:
    module: ec2_eip
    region: “{{ vpc_region }}”
    instance_id: “{{ item.id }}”
    with_items: ec2.results.instances
    register: eip

  • name: Add the newly created EC2 instance(s) to the local host group
    local_action: lineinfile
    dest=“./hosts”
    regexp=“{{ eip.results.public_ip }}”
    insertafter=“[nat]”