2

i.e. I have a playbook, there some actions could be applied for some of hosts within ansible_play_hosts_all list, and I need to execute one task in the only case if none of hosts within ansible_play_hosts_all list have certain variable defined. I have tried to use such approach:

    - name: look-up if there are no junos changes in such deploy
      set_fact:
        no_junos_changes: >-
          {%- set ns = namespace(junos_changes_counter=0) -%}
          {%- for router in ansible_play_hosts_all -%}
          {%- if hostvars[router]['correct_sections'] is defined -%}
          {%- set ns.junos_changes_counter = ns.junos_changes_counter + 1 -%}
          {%- endif -%}
          {%- endfor -%}
          {{ ns.junos_changes_counter }}
      delegate_to: localhost
      run_once: true

    - name: sent final summary to ms teams in case when junos commit skipped
      import_tasks: ./tasks/post_commit_summary.yml
      when: no_junos_changes|int == 0
      delegate_to: localhost
      run_once: true

So, first task will provide me a number, how much hosts within ansible_play_hosts_all list have they hostvars[router]correct_sections variable defined. Then at the second task I'll just comparing that number with 0.

It is working as expected, but I am not sure if it's the most simple and elegant way for such purpose. I mean, ideally I would like to get rid of first task and use some one-liner in "when" statement at the second task, I just not sure if it's possible ...

2 Answers2

1

Q: "How much hosts within ansible_play_hosts_all list have they hostvars[router]correct_sections variable defined?"

A: Try this

- set_fact:
    no_junos_changes: "{{ ansible_play_hosts_all|
                          map('extract', hostvars)|
                          selectattr('correct_sections', 'defined')|
                          list|length }}"
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • thanks a lot! I was suspecting, is could be done with selectattr, I just didn't know that map('extract') could been used for slicing the needed parts of nested dict to the list. – Aleksandr Smirnov Feb 12 '20 at 12:25
0
- name: sent final summary to ms teams in case when junos commit skipped
  import_tasks: ./tasks/post_commit_summary.yml
  when: ansible_play_hosts_all
    |map('extract', hostvars)
    |selectattr('correct_sections', 'defined')
    |list|length|int == 0
  delegate_to: localhost
  run_once: true

Just in case if someone interested about single-task solution with one-liner condition