16
votes

I am new to Ansible and I am trying to create several virtual environments (one for each project, the list of projects being defined in a variable).

The task works well, I got all the folders, however the handler does not work, it does not init each folder with the virtual environment. The ${item} varialbe in the handler does not work. How can I use an handler when I use with_items ?

  tasks:    
    - name: create virtual env for all projects ${projects}
      file: state=directory path=${virtualenvs_dir}/${item}
      with_items: ${projects}
      notify: deploy virtual env

  handlers:
    - name: deploy virtual env
      command: virtualenv ${virtualenvs_dir}/${item}
2

2 Answers

23
votes

Handlers are just 'flagged' for execution once whatever (itemized sub-)task requests it (had the changed: yes in its result). At that time handlers are just like a next regular tasks, and don't know about the itemized loop.

A possible solution is not with a handler but with an extratask + conditional

Something like

- hosts: all 
  gather_facts: false
  tasks:
  - action: shell echo {{item}}
    with_items:
    - 1 
    - 2 
    - 3 
    - 4 
    - 5 
    register: task
  - debug: msg="{{item.item}}"
    with_items: task.results
    when: item.changed == True
0
votes

To sum up the previous discussion and adjusting for the modern Ansible...

- hosts: localhost,
  gather_facts: false

  tasks:
  - action: shell echo {{item}} && exit {{item}}
    with_items:
    - 1
    - 2
    - 3
    - 4
    - 5
    register: task
    changed_when: task.rc == 3
    failed_when: no
    notify: update service

  handlers:
  - name: update service
    debug: msg="updated {{item}}"
    with_items: >
      {{
      task.results
      | selectattr('changed')
      | map(attribute='item')
      | list
      }}