Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible with_subelements default value

i have a vars definition like this:

sites:
 - site: mysite1.com
   exec_init:
    - "command1 to exec"
    - "command2 to exec"
 - site: mysite2.com

then i have play with the following task

- name: Execute init scripts for all sites
  shell: "{{item.1}}"
  with_subelements: 
    - sites
    - exec_init
  when: item.0.exec_init is defined

The idea here is that i will have multiple "Site" definitions with dozens of other properties in my vars, then i would like to execute multiple Shell script commands for those sites having "exec_init" defined

Doing it this way it just always skip executing the task, i've tried this in all combinations i can imagine but i just can't get it to work...

Is this the proper way of doing it? maybe i'm trying to achieve something that doesn't make sense?

Thanks for your help

like image 415
jmserra Avatar asked Jul 07 '14 17:07

jmserra


People also ask

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 .

Does Ansible do until loops?

This loop is used for retrying task until certain condition is met. To use this loop in task you essentially need to add 3 arguments to your task arguments: until - condition that must be met for loop to stop. That is Ansible will continue executing the task until expression used here evaluates to true.

What is Loop_var in Ansible?

Defining inner and outer variable names with loop_var 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 .


3 Answers

The valid solution here (considering ansible 2.7+) is to use loop instead of with_subelements. As with loop you can apply subelements filter, that has skip_missing option (ie what @hkariti suggested in option 3 but in proper way).

So, code should look like:

- name: Execute init scripts for all sites
  shell: "{{ item.1 }}"
  loop: "{{ sites | subelements('exec_init', skip_missing=True) }}"
like image 185
Дмитрий Работягов Avatar answered Sep 20 '22 16:09

Дмитрий Работягов


This works for me. I am using version 2.1.1 Just add the third element in the subelements list as shown

- name: Iterate over something
  with_subelements:
     - "{{ unit }}"
     - config
     - skip_missing: True
like image 37
Vidya Avatar answered Sep 19 '22 16:09

Vidya


There's another way, try:

- debug: "var=item"
  with_subelements:
    - "{{ sites | selectattr('exec_init', 'defined') | list }}"
    - exec_init

Thanks to: https://github.com/PublicaMundi/ansible-plugins/blob/master/lookup_plugins/subelements_if_exist.py

like image 24
user5066686 Avatar answered Sep 17 '22 16:09

user5066686