Ansible getting public ip of host from inventory file - ansible

I would like to get public ip of a host defined in inventory file
[test-sites:children]
test-site-1
[test-site-1]
test-site-1-2 ipv4=192.168.0.1 ipv6=....
How do I get the ipv4 and ipv6 address of "test-site-1-2" defined in the inventory file? I have checked this answer but it gives all of the addresses (public & private). I am interested in ips defined in the inventory file only.

[test-site-1]
test-site-1-2 ipv4=192.168.0.1 ipv6=....
Q: "How do I get the ipv4 and ipv6 address of "test-site-1-2" defined in the inventory file?"
A: If the playbook is running at "test-site-1-2" simply reference the variables directly. For example
- hosts: test-site-1-2
tasks:
- debug:
var: ipv4
- debug:
var: ipv6
If these variables are needed by other hosts reference to "hostvars" is needed. For example
- hosts: test-site-1
tasks:
- debug:
var: hostvars['test-site-1-2'].ipv4
- debug:
var: hostvars['test-site-1-2'].ipv6
See Basic inventory.

Related

Ansible using dynamic variable on hosts returns Error

I'm trying to create a playbook which basically consists 2 hosts init; (don't ask why)
---
- hosts: all
tasks:
- name: get the hostname of machine and save it as a variable
shell: hostname
register: host_name
when: ansible_host == "x.x.x.x" *(will be filled by my application)*
- hosts: "{{ host_name.stdout }}"
tasks:
- name: use the variable as hostname
shell: whoami
I don't have any hostname information in my application so I need to trigger my playbook with an IP address, then i should get the hostname of that machine and save it to a variable to use in my other tasks to avoid "when" command for each task.
The problem is that I'm able to use "host_name" variable in all other fields except "hosts", it gives me an Error like this when i try to run;
ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'host_name' is undefined
Screenshot of the error
By default, Ansible itself gathers some information about a host. This happens at the beginning of a playbook's execution right after PLAY in TASK [Gathering Facts].
This automatic gathering of information about a system can be turned off via gather_facts: no, by default this is active.
This collected information is called Ansible Facts. An example of the collected facts is shown in the Ansible Docs, for your host you can print out all Ansible Facts:
either in the playbook as a task:
- name: Print all available facts
debug:
var: ansible_facts
or via CLI as an adhoc command:
ansible <hostname> -m setup
The Ansible Facts contain values like: ansible_hostname, ansible_fqdn, ansible_domain or even ansible_all_ipv4_addresses. This is the simplest way to act with the hostname of the client.
If you want to output the hostname and IP addresses that Ansible has collected, you can do it with the following tasks for example:
- name: Print hostname
debug:
var: ansible_hostname
- name: Print IP addresses
debug:
var: ansible_all_ipv4_addresses
If you start your playbook for all hosts, you can check the IP address and also stop it directly for the "wrong" clients.
---
- hosts: all
tasks:
- name: terminate execution for wrong hosts
assert:
that: '"x.x.x.x" is in ansible_all_ipv4_addresses'
fail_msg: Terminating because IP did not match
success_msg: "Host matched. Hostname: {{ ansible_hostname }}"
# your task for desired host

Ansible - hostvars from single host

i have in the inventory host with own variables:
children:
webserver:
vars:
hosts:
web01.local:
function: live
location: lca
web02.local:
function: test
location: lcb
now i would like to create a playbook, which installs the snmpd service on each of the hosts (all) and stores the value "location" from the inventory.
How can I access this variable "location" in the playbook?
If your playbook is targeting the remote hosts, you can just refer to the location variable:
- hosts: webserver
tasks:
- debug:
msg: "value of location: {{ location }}"

get Ansible MASTER Machine (where ansible is installed and running) hostname

Is there a special variable where ansible master machine hostname is stored (not hosts where action are running : ansible_host inventory_hostname ) ?
I want to get my local hostname while running a playbook against hosts.
for example i have installed my ansible on : machine1 and i'm running it against machine_dev , how to get machine1 in a special variable without a localhost hostname shell command ?
The hostname is stored in the fact ansible_hostname. You need to gather facts for this.
All gathered hosts facts are available through the hostvars hashmap
If you gather facts for localhost in your very first play, the local hostname will be available anywhere else in hostvars.localhost.ansible_hostname
Here is a quick demo of how you can use this.
---
- hosts: localhost
- hosts: all
tasks:
- name: show localhost hostname for each current host in the play loop
debug:
msg: "{{ hostvars.localhost.ansible_hostname }}"

How do I correctly use the ansible hostname module?

I am trying to use ansible to modify the hostnames of a dozen newly created Virtual Machines, and I am failing to understand how to loop correctly.
Here is the playbook I've written:
---
- hosts: k8s_kvm_vms
tasks:
- name: "update hostnames"
hostname:
name: "{{ item }}"
with_items:
- centos01
- centos02
...
The result is that it updates each host with each hostname. So if I have 12 machines, each hostname would be "centos12" at the end of the playbook.
I expect this behavior to essentially produce the same result as:
num=0
for ip in ${list_of_ips[*]}; do
ssh $ip hostnamectl set-hostname centos${num}
num=$((num+1))
done
If I were to write it myself in bash
The answer on this page leads me to believe I would have to include all of the IP addresses in my playbook. In my opinion, the advantage of scripting would be that I could have the same hostnames even if their IP changes (I just have to copy the ip addresses into /etc/ansible/hosts) which I could reuse with other playbooks. I have read the ansible page on the hostname module, but their example leads me to believe I would, instead of using a loop, have to define a task for each individual IP address. If this is the case, why use ansible over a bash script?
ansible hostname module
You can create a new variable for each of the servers in the inventory like
[k8s_kvm_vms]
server1 new_hostname=centos1
server2 new_hostname=centos2
Playbook:
---
- hosts: k8s_kvm_vms
tasks:
- name: "update hostnames"
hostname:
name: "{{ new_hostname }}"
I think you need to sudo to change the hostname thus you should add "become: yes"
---
- hosts: k8s_kvm_vms
become: yes
tasks:
- name: "update hostnames"
hostname:
name: "{{ new_hostname }}"

how to extract the IP from ansible getent wrapper module

I would like to use getent wrapper module in order to parse the contents of /etc/hosts and save the ip address in a variable for later use. I do not manage to isolate the IP if found on /etc/hosts
we are doing this in order to check that the /etc/hosts on the server farm are up to dated we will use this variable to verify against the dns and if the two address do not match then correct /etc/hosts. I also tried slurp but without much success
---
- hosts: all
tasks:
- name: getent hosts
getent:
database: hosts
key: "{{ansible_hostname}}"
register: results
- name: print result
debug:
msg="{{results}}"
- set_fact:
a_host_ip={{ getent_hosts[ansible_default_ipv4.address] }}
- debug: var=a_host_ip
I would like to have the ip address in the varilable a_host_ip but the actual contents are the hostnames corresponding to the ip address. How can I save the IP address in a variable.
To get a list of IPs:
{{ getent_hosts.keys() }}
To get a single element:
{{ getent_hosts.keys() | first }}

Resources