Ansible testing variable type

2019-02-22 08:32发布

问题:

I'm using an existing role, and I wish to modify it to extend its capabilities. Currently, one of its tasks is to create directories. These directories get passed as a variable containing a list of strings to the role, and then iterated over in a with_items statement. However, I would prefer to pass a list of dictionaries of the form e.g. {name: foo, mode: 751}.

So far so good; I can simply edit the role to make it take this sort of input. However, I also want to make it backwards compatible with the old format, i.e. where the items are strings.

Is there a way to test the type of a variable and then return different values (or perform different tasks) based on this? Perhaps using a Jinja2 filter? I was briefly looking at the conditionals listed in the manual, but nothing caught my eye that could be used in this situation.

回答1:

You could use default() for backwards compatibility.

- file:
    path: "{{ item.name | default(item) }}"
    mode: "{{ item.mode | default(omit) }}"
    state: directory
  with_items: your_list

If the item has a name property, use it, else simply use the item itself.

Same goes for all other properties you might have in your dict. The special variable omit would omit the whole option from the task, as if no mode was passed to the file module. Of course you could set any other default.

Documentation references:

  • default
  • omit


回答2:

The quickest solution would be to have two tasks, and have they trigger with opposed conditions. Unfortunately, all items in the list will have to use the same form (you can't mix and match strings and dicts).

- name: create dirs (strings)
  file:
    ...
  with_items: items
  when: string(items[0])

- name: create dirs (dicts)
  file:
    ...
  with_items: items
  when: not string(items[0])