1

I'm trying to have list of paths. The variables folder (web_folder, app_folder or db_folder ) may be undefined and is expected to be undefined.
In this case I just don't want the undefined value in the the list.

- set_fact: root_paths="{{ root_paths | default([]) + [ item ] }}"
  loop:
    - "{{ web_folder }}"
    - "{{ app_folder }}"
    - "{{ db_folder }}"
  when: item is defined

When I do this I get an error message 'The task includes an option with an undefined variable.'

I can make this work if I define default values e.g. '-' and replace the when condition with

when: item != '-'

I don't like this solution.

I tried a few things like

  • 'when: vars[item] is undefined' from this post, but it didn't work for me.
  • I also replaces 'loop' with 'with_items' didn't work either

Any suggestions?

fan
  • 2,234
  • 1
  • 23
  • 24
  • cant tell which variable is undefined in your task and causes this error. is it one of the _folder vars? – ilias-sp Aug 30 '19 at 20:40

2 Answers2

1

The variables folder (web_folder, app_folder or db_folder ) may be undefined and is expected to be undefined.

you could use the default filter to initialize them to an empty array, in case they are not defined:

- set_fact: root_paths="{{ root_paths | default([]) + [ item ] }}"
  loop:
    - "{{ web_folder | default([]) }}"
    - "{{ app_folder | default([]) }}"
    - "{{ db_folder | default([]) }}"
  when: item is defined

hope it helps.

ilias-sp
  • 6,135
  • 4
  • 28
  • 41
1

Q: I get an error message 'The task includes an option with an undefined variable.' I can make this work if I define default values e.g. '-' and replace the when condition with when: item != '-'. I don't like this solution.

A: The expansion of an undefined variable causes the error. Either the variables are tested explicitly or default filter is used.

Testing each variable is cumbersome

  tasks:
    - set_fact:
        folders_defined: []
    - set_fact:
        folders_defined: "{{ folders_defined + [web_folder] }}"
      when: web_folder is defined
    - set_fact:
        folders_defined: "{{ folders_defined + [app_folder] }}"
      when: app_folder is defined
    - set_fact:
        folders_defined: "{{ folders_defined + [db_folder] }}"
      when: db_folder is defined
    - debug:
        var: folders_defined

The next option (which is very similar to the one you don't like) is to test a default value assigned to undefined variables. For example, the playbook below tests default empty string. If necessary fit this condition to your needs.

- hosts: localhost
  vars:
    web_folder: /my/web/folder
    app_folder: /my/app/folder
    folders: [web_folder, app_folder, db_folder]
  tasks:
    - set_fact:
        folders_defined: "{{ folders_defined|default([]) +
                             [lookup('vars', item)] }}"
      loop: "{{ folders }}"
      when: lookup('vars', item, default='')|length > 0
    - debug:
        var: folders_defined

gives

ok: [localhost] => {
    "folders_defined": [
        "/my/web/folder", 
        "/my/app/folder"
    ]
}
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63