The "ipify_facts" method described in a different answer should work if:
- Your control host has only one interface, or if it has multiple interfaces and the interface used for reaching towards the ipify api_url is the same as for reaching towards your remote host, -and-
- Your control host has a public IP (no NAT used at all), or your control host is inside NAT but the remote host is outside.
If either of the above conditions is not met (that is, if your control host has multiple interfaces and/or your control host as well as your remote host are both behind NAT and using private addresses), then a different (albeit slightly more complex) way is to replicate the following in Ansible:
$ ip route get 203.0.113.4
203.0.113.4 via 172.26.232.1 dev enp0s3 src 172.26.232.125
cache
$
This will show you the interface and the source address (172.26.232.125) to be used for reaching towards a specific destination (203.0.113.4).
One way to implement this in Ansible would be:
---
- name: Obtain local IP address
local_action: shell ip route get {{ inventory_hostname }} | awk '{ for (x=1;x<=NF;x++) if ($x=="src") print $(x+1) }'
register: local_address
changed_when: false
- name: Print my local address
debug: msg="Source address towards {{ inventory_hostname }} is {{ local_address.stdout }}"
Output:
$ ansible-playbook test.yml -i inventory.txt
PLAY [test] ********************************************************************
TASK [Obtain local IP address] *************************************************
ok: [203.0.113.4 -> localhost]
TASK [Print my local address] **************************************************
ok: [203.0.113.4] => {
"msg": "Source address towards 203.0.113.4 is 172.26.232.125"
}
This should also work if you have multiple remote hosts reachable via different interfaces.
An additional step in the "shell" action would be needed if your inventory_hostname was a DNS hostname as opposed to a numerical IP address.