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.
Related
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.
I am a bit at loss at how to achieve an ansible playbook that generates nagios config files for a series of hosts, each hosts should have it's own variables set.
I think the issue is that I don't understand how to assign variables value to hosts that are already defined as variables.
here's the very simple ansible playbook main task file I am using
- name: Generate the nagios monitoring templates
template: src={{ item + ".j2" }}
dest=nagiosdir/{{ item }}
force=yes
owner=nagios
group=nagios
mode=660
with_items:
- linuxservers.cfg
become: true
here's a very simple working ansible vars file I made
hosts: [host1_fqdn, host2_fqdn]
here's my linuxserver.cfg.j2 template file
{% for hosts in hosts %}
define host{
use linux-server ; Name of host template to use
; This host definition will inherit all variables that are defined
; in (or inherited by) the linux-server host template definition.
host_name {{ hosts }}
alias {{ hosts }}
address {{ hosts }}
action_url /grafici/index.php/graph?host={{ hosts }}
}
define service{
use generic-service ; Name of service template to use
host_name {{ hosts }}
service_description Current Load
check_command check_by_ssh_remote_load!5.0,4.0,3.0!10.0,6.0,4.0
notifications_enabled 1
}
{% endfor %}
and this extremely simple for loop works.
on the linuxserver.cfg file I want to be able to add variables to be defined for each host, like so
check_command check_by_ssh_remote_load!{host1_var1}!{host1_var1}
and so forth for each host, as to be able to have a var file in ansible where i define each and every host and for each and every host I should be able to define different values to use withing my nagios check_commands definitions.
what tools available in ansible/jinja2 should I use to achieve that?
I have very little experience so I am quite lost as where to even begin achieving that.
I am running a shell command, this command runs for all hosts listed in my inventory file. I am then using register to define the variable, when i retrieve these values for debug messages i see register variable for all hosts printed for all IP in my inventory but i want to store them in a list so that i can use them in templates. How can we achieve it?
- name: Command
shell: hostname -f
register: fqdn_name
For your specific question, you are doing more work than you need to. Each time Ansible runs against a host, it collects a series of 'facts' about the host and stores them in a dictionary available during your plays. Therefore, replace your existing Command task with the following, to see what I mean:
- name: Display the Ansible FQDN fact
debug:
var: ansible_fqdn
Running ansible -m setup <hostname taken from inventory file> will show you all the variables that get collected.
The variables for all your hosts are made available through a special dictionary called 'hostvars', therefore in your template you can do something like this:
{% for host in groups.all %}
{{ hostvars[host]['ansible_fqdn'] }}
{% endfor %}
You could replace groups.all with groups.<some inventory groupname> to limit the matched hosts to a particular group.
One possible gotcha here, is that these facts will only have been collected if Ansible has already targeted a host, therefore one strategy for more complex playbooks is:
# This play simply connects to all your hosts and gathers facts
- hosts: all
gather_facts: yes
# Now all subsequent plays have access to facts for all hosts
- hosts: <all or some group>
tasks: ...
I recently discovered how use "when inventory_hostname" to set_fact for the first host in an host group. I was wondering how to pass a variable as the host group. In my testing I use the following:
Inventory file:
---
[test]
test-001.example.com
test-002.example.com
vars file:
---
declared_hostgroup: test
playbook:
- name: set first host in group as master
set_fact:
test_order: MASTER
when: inventory_hostname == group.test[0]
That works great. But I would like to replace "test" in "group.test" with the variable "declared_hostgroup". I've tried {{ }} syntax with no success. Any suggestions would be really appreciated.
This is the correct syntax:
when: inventory_hostname == group[declared_hostgroup][0]
But keep in mind that although Ansible tries to keep order of host consistent, it can break sometime in the future (e.g. different sort order or some other quirks), so you may want to mark your host inside inventory for clarity.
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.