Friday, May 25, 2018

Interesting Ansible ipify problem

I had this interesting problem recently and was able to work around that problem (once I discovered it)

I was using the ansible functionality of 'ipify' to determine the public ip address of the host I was provisioning. It worked great and I used that fact to find the ethernet interface that was attached to that public ip address.

I ran it on a new host and it just didn't work.

After far too long of troubleshooting I discovered my problem. The ip address provided by 'ipify` was not the public ip address of the host I ran the playbook on. It was the public ip address of the http proxy that the system was using (...doh!!!). Don't get me wrong, this is the correct behavior of an application that uses http by respecting the proxy settings. However, ipify has no way to override the proxy setting.

I was able to solve it:

- name: delete public ip address file
  file:
    state: absent
    path: /tmp/public_ip_address

- name: set_facts | get my public IP
  get_url:
    url: http://ifconfig.co/ip
    use_proxy: no
    dest: /tmp/public_ip_address

- name: Slurp file with public ip address
  slurp:
    src: /tmp/public_ip_address
  register: slurpfile
 
- name: set_facts | set fact from ip address in slurped file
  set_fact:
    _public_ip_address: "{{ slurpfile['content'] | b64decode | ipaddr }}"

- name: set_facts | interface for public ip
  set_fact:
    public_interface: "{{ item }}"
  when: >
    (hostvars[inventory_hostname]['ansible_%s' % item]|default({}))
    .get('ipv4', {}).get('address') == _public_ip_address
    or
    _public_ip_address in ((hostvars[inventory_hostname]['ansible_%s' % item]|default({}))
    .get('ipv4_secondaries'))|map(attribute='address')|list
  with_items:
    - "{{ ansible_interfaces }}"




Many thanks to user larsks that published a good way to iterate through the interfaces.

StackOverFlow discussion about Ansible iterating interface details

And shoutout to Flowroute ( https://www.flowroute.com/ )