Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible loop through group vars in template

Tags:

I'm struggling with a pattern pulling inventory vars in Ansible templates, please help. :)

I'm setting up a monitoring server, and I want to be able to automatically provision the servers using Ansible. I'm struggling with loops in the template to allow me to this.

My semi-working soluition so far is in the playbook that calls the template task I have:

monitoringserver.yml

 vars:        servers_to_monitor:          - {cname: web1, ip_address: 192.168.33.111}          - {cname: web2, ip_address: 192.168.33.112}          - {cname: db1, ip_address: 192.168.33.211}          - {cname: db2, ip_address: 192.168.33.212} 

template.yml

all_hosts += [            {% for host in servers_to_monitor %}                    "{{ host.cname }}{{ host.ip }}|cmk-agent|prod|lan|tcp|wato|/" + FOLDER_PATH + "/",            {% endfor %} ]  

But this isn't ideal as I can't define different IP address for different servers to be monitoring. How have other people done this? I'm sure it must be trivial but my brain's struggling with the syntax.

Thanks

Alan

edit: To clarify the resulting template looks something like this:

all_hosts += [                         "web1|cmk-agent|prod|lan|tcp|wato|/" + FOLDER_PATH + "/",                         "web2|cmk-agent|prod|lan|tcp|wato|/" + FOLDER_PATH + "/",                         "db1|cmk-agent|prod|lan|tcp|wato|/" + FOLDER_PATH + "/",                         "db2|cmk-agent|prod|lan|tcp|wato|/" + FOLDER_PATH + "/", ] 

What I would like is the values web1/web2/db1/db2 to be different depending on whether I'm using a production inventory file or a development inventory file.

like image 297
Alan Hollis Avatar asked Nov 18 '14 08:11

Alan Hollis


People also ask

How do you use nested loops in Ansible?

You can nest two looping tasks using include_tasks . However, by default Ansible sets the loop variable item for each loop. This means the inner, nested loop will overwrite the value of item from the outer loop. You can specify the name of the variable for each loop using loop_var with loop_control .

What is {{ item }} Ansible?

item is not a command, but a variable automatically created and populated by Ansible in tasks which use loops. In the following example: - debug: msg: "{{ item }}" with_items: - first - second. the task will be run twice: first time with the variable item set to first , the second time with second .

Which loop can be used to iterate over files in a directory Ansible?

Looping over Filetrees. with_filetree recursively matches all files in a directory tree, enabling you to template a complete tree of files on a target system while retaining permissions and ownership.

How do you write a for loop in Jinja2?

Jinja2 being a templating language has no need for wide choice of loop types so we only get for loop. For loops start with {% for my_item in my_collection %} and end with {% endfor %} . This is very similar to how you'd loop over an iterable in Python.


1 Answers

Ideally you would be using different inventory files for production and staging, which would allow you to keep the same {{ inventory_hostname }} value, but target different machines.

You can also loop through different groups...

hosts:

[web] web1 web2  [db] db1 db2 

playbook:

- name: play that sets a group to loop over   vars:     servers_to_monitor: "{{ groups['db'] }}"    tasks:     - template:       src: set-vars.j2       dest: set-vars.js 

template:

all_hosts += [ {% for host in servers_to_monitor %}   "{{ hostvars[host].inventory_hostname }}{{ hostvars[host].ansible_default_ipv4.address }}|cmk-agent|prod|lan|tcp|wato|/" + FOLDER_PATH + "/", {% endfor %} ]  
like image 149
Conrado Avatar answered Oct 12 '22 05:10

Conrado