In my ansible host inventory, i got 3 host ip as below
[host-group-1]
123.23.23.21
123.23.23.22
i have a variable as below
host_list:
- { fileName: "master.xml", IP: {{ get_current_Execution_ip }} }
- { fileName: "slave.xml", IP: {{ get_current_Execution_ip }} }
I have a task which will do some logic in the jinja2 template based on value get from IP. My question is how can i use this {{ get_current_Execution_ip }} to get the current IP the file being constructed via jinja2 template based on respective server. For instance, if the file contructing in 123.23.23.21, the IP value should be 123.23.23.21, if contructing in server 123.23.23.22, the IP value should be 123.23.23.22
With your inventory set up like that, you can just access the variable inventory_hostname. If you change your inventory to look something like
[host_group_1]
host1 ansible_host=123.23.23.21
host2 ansible_host=123.23.23.22
then you can instead access the IP with the ansible_host variable (which is also available in the first case).
If you change your inventory to not list IP addresses at all (instead relying on resolving the name through DNS), then you probably want to look at some of the answers to this question.
Related
I would like to fetch IP of a host from another group in inventory file based on variable name.
Example inventory file:
[master]
master-0.example.io
master-1.example.io
master-2.example.io
[replica]
replica-0.example.io master_host=master-0.example.io
replica-1.example.io master_host=master-1.example.io
replica-2.example.io master_host=master-2.example.io
Later in playbook I want to run a command, but for that one I require IP of master (FQDN does not work). I have tried following, but this is not working:
- name: Test run
shell: "echo {{ ansible_default_ipv4.address }}:{{ port }} {{ hostvars['master_host']['ansible_default_ipv4', 'address'] }}:{{ port }}"
Any idea if there is a way to get this covered? Or if there is any other way to do this - basically what I need is to match master-0 with replica-0 etc. and I do not want to put IPs into inventory file.
hostvars is a hash. Each top entry in the hash is the name of your host in the inventory. To address that hash, your are using the string 'master_host' which does not exist. What you want, is to use the value of the variable master_host for the particular host your are executing the command on.
The 2 possible correct syntaxes are:
{{ hostvars[master_host].ansbible_default_ipv4.address }}
{{ hostvars[master_host]['ansbible_default_ipv4']['address'] }}
... or any mix between the dot or bracket syntax.
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 }}
In my inventory I define hosts like this:
[server1]
141.151.176.223
I am looking for a variable which keeps the server1 name, as I am using it to define server hostname.
inventory_hostname is set to 141.151.176.223
ansible_hostname as well as inventory_hostname_short is set to 148.
To workaround this problem I am setting my own variable like this:
[server1]
141.151.176.223 hostname=server1
but I am not satisfied with this approach.
Any ideas?
Explanation
If the inventory file was defined this way:
[server1_group]
server1 ansible_host=141.151.176.223
Then you can access:
server1 with the inventory_hostname fact;
141.151.176.223 with the ansible_host fact;
server1_group with group_names|first (group_names fact contains a list of all groups server belongs to, first selects the first element from that list).
Regardless of the above, ansible_hostname fact contains the host name as defined on the host itself (the value is set during facts gathering).
Solution
You should use a standard ansible_host declaration to point to the target's IP address and set the inventory hostname to however you want to refer to the server in Ansible playbooks.
In particular you can skip groups definition altogether and define just:
server1 ansible_host=141.151.176.223
The [server1] declaration is the name of a group, not a host (even if you only assign a single host to that group).
As ansible allows a host to be placed in multiple groups, you can only get the names as an array: http://docs.ansible.com/ansible/latest/playbooks_variables.html#magic-variables-and-how-to-access-information-about-other-hosts
So I think the workaround that you found is the way to go, unless you can use real host names instead of IP addresses (using DNS or just static hosts file).
I have a host file that looks roughly like this:
[kibanamaster]
efk host_ip host user passwd
[elasticnode]
esnode host_ip user passwd
and I am trying something in the style of
- name: get ip address node1
debug: var=hostvars[inventory_host]['esnode']['ansible_default_ipv4']['address']
register: es_node1
But I get variable not defined. Anyone outthere able to help?
EDIT:
If I do
debug: var=hostvars[LOG1]['esnode']['ansible_default_ipv4']['address']
register: node_1
I get
{"hostvars[LOG1]['ansible_default_ipv4']['address']": "VARIABLE IS NOT DEFINED!"}
hostvars magic variable is a dictionary with keys named after hosts in your inventory.
So you may want to try:
hostvars['esnode']['ansible_default_ipv4']['address']
to get ip address of esnode host.
You can use pre-loaded ansible variable to get values for both ipv4, ipv6 & hostname
IPV4 --> {{ ansible_eth0.ipv4.address }}
IPV6 --> {{ ansible_eth0.ipv6.address }}
Hostname --> {{ ansible_hostname }
I set up group of test VMs (with pure Debian) to play with, all of them are on test network so it is self-contained group of VM. These VMs be destroyed soon so I don't want to add its names to DNS while I need to have them communicate oven hostnames.
Is there any way I can form /etc/hosts files on these VMs based on hosts IPs from Ansible hosts file?
I can set hostnames like that
192.168.0.5 myhostname=host01.local
192.168.0.6 myhostname=host02.local
so I think I can somehow form /etc/hosts like that:
{{ ip }} {{ myhostname }}
but can archive that. I think I can iterate over group['all'] and use lineinfile to add lines to /etc/hosts, but it won't work for me so far.
You can use the inventory_file variable to get the path filename of the hosts file:
Also available, inventory_dir is the pathname of the directory holding Ansible’s inventory host file, inventory_file is the pathname and the filename pointing to the Ansible’s inventory host file.
Reference
You can read its variables with something like:
tasks:
- local_action: shell cat {{ inventory_file }}
register: result
As recommended here. More on local actions here.
You can then use jinja filters and loops to use the variable.