prototyp
prototyp

Reputation: 590

Ansible when with variable

I am trying to check if a directory of multiple user is empty. In case it does a command should be executed for each user.

- name: Check if vim plugins has been initialised               
  find: paths="/home/{{ item.name }}/.vim/bundle/"              
  register: "{{ item.name }}_vim_plugin_init_state"             
  with_items: "{{ users }}"                                     
  tags: debug                                                   

- name: Install vim plugins                                     
  command: vim -E -s -c "source ~/.vimrc" -c PluginInstall -c qa
  become_user: "{{ item.name }}"                                
  with_items: "{{ users }}"                                     
  when: "{{ item.name }}"_vim_plugin_init_state.matched|int == 0
  tags: debug                                                   

Is this possible and if what I am doing wrong here?

Upvotes: 0

Views: 52

Answers (1)

larsks
larsks

Reputation: 311248

The arguments to a with statement are implicitly inside a Jinja templating context. In other words, if you write:

when: something

You are actually getting:

when: "{{ something }}"

And since you never nest {{...}} markers inside an existing Jinja expression, that means you will usually never use {{...}} inside your when expressions. However, because you're creating a unique variable for each item in users, you need to compute the variable name in your install task, which complicates things.

Fortunately, you are misusing the register command, which behaves differently in a loop than it does on single tasks. Read "Using register in a loop" for details.

When used appropriately, things get much easier:

- name: Check if vim plugins has been initialised
  find: paths="/home/{{ item.name }}/.vim/bundle/"
  register: "vim_plugin_init_state"
  loop: "{{ users }}"
  tags: debug

- name: Install vim plugins
  command: vim -E -s -c "source ~/.vimrc" -c PluginInstall -c qa
  become_user: "{{ item.item.name }}"
  when: "item.matched|int > 0"
  loop: "{{ vim_plugin_init_state.results }}"
  loop_control:
    label: "{{ item.item.name }}"
  tags: debug

Note that I've made a couple of additional changes here:

  • I'm using loop instead of with_items because that's the recommended syntax these days.

  • I'm using loop_control to set an explicit label, which cuts down on all the output when the task runs.

  • I'm using item.item.name to refer to the user, because in the second task each item is a result from the previous task (this is explained further in that "Using register in a loop" documentation).

Upvotes: 1

Related Questions