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

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 }}"

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

How to manually pass host name to ansible tower template at runtime

I am have a requirement like passing a server hostname at runtime to ansible tower template. the issue i faced is we dont know the hostname before running the template so we cant configure hostname in the ansible tower inventory. I tired googling but haven't found a solution yet.
my main.yaml file starting will be looking like this
- name: Execution server
hosts: <hostname>
gather_facts: false
serial: 1
the erroer i am getting is
1 plays in main.yml
[WARNING]: Could not match supplied host pattern, ignoring: <hostname>
You can use the target_host variable. I like setting a default with this
- name: Execution server
hosts: "{{ target_host | default('all') }} "
gather_facts: false
serial: 1
Define target_host in a job template's limit:

how to set hostname using inventory file

I have my hosts in an inventory file as below:
cnamgw01b ansible_ssh_host=172.17.0.26
cnamgw01a ansible_ssh_host=172.17.1.26
cnamgw02b ansible_ssh_host=172.17.0.23
cnamgw02a ansible_ssh_host=172.17.1.23
cnamgw03a ansible_ssh_host=172.17.1.13
cnamgw03b ansible_ssh_host=172.17.0.13
These are new builds and I would like to set the hostname based on the inventory file. I already have a script in place that updated the inventory file as new VM's are turned up and assigns a random hostname. I would like to take this hostname assigned and set it as the hosts hostname. How can I accomplish this? Also note that I also use folders to subdivide the hosts by region
You can use the ansible module hostname to set hostname.
https://docs.ansible.com/ansible/latest/modules/hostname_module.html
- hosts: all
tasks:
- name: Set hostname
hostname:
name: {{ inventory_hostname }}
You could run something like this to set the system hostname to the inventory hostname:
- hosts: all
tasks:
- name: set system hostname
command: hostnamectl set-hostname {{ inventory_hostname }}
That is, the variable inventory_hostname holds the name of the current host as it was named in your inventory.
This task assumes you have the hostnamectl command available. You could instead write the value of inventory_hostname to /etc/hostname and call the hostname command separately.

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 can I get hostname and put it on cfg

how can I edit a remote cfg file or in my case
I must modify the "hostname" by the name of the remote machine,
knowing that it is for automated because aprre I will deploy it on +300 server
I must be able to get the remote hostname and put it in the cfg file with ansible
thanks
############# file for config host ############
---
- hosts: computer_user
remote_user: toto
tasks:
- name: "config zabbix agent"
lineinfile:
path: /etc/zabbix.cfg
regexp: '(.*)hostname_local(.*)'
line: '%hostname%'
########### file_cfg_on_computer_user #########
hostname_local: here_i_want_put_the_hostname_of_my_computer_user_with_a_like_%hostname%
I'm not really sure about what you really want, but if you want to get the hostname of the system where your playbook is running, then you have two possibility :
You can get the value of inventory_hostname : It is the name of the hostname as configured in Ansible’s inventory host file
Or you can get the value of the ansible fact ansible_hostname : this one is discovered during the gathering fact phase
You can find more info about hosts variables and facts here
Ansible defines many special variables at runtime.
You can use {{ inventory_hostname }} to returns the inventory name for the ‘current’ host being iterated over in the play.
Or you can execute a remote command and use result in next task :
---
- hosts: computer_user
remote_user: toto
tasks:
- name: "get hostname from remote host"
shell: hostname
register: result_hostname
- name: "config zabbix agent"
lineinfile:
path: /etc/zabbix.cfg
regexp: '(.*)hostname_local(.*)'
line: '{{ result_hostname.stdout }}'

Resources