Ansible creates string instead of list

Viewed 281

In a vars/main.yml file I have the following:

var_list: "{% if somevar == 'someval' %}
    - host1
    - host2
    - host3
    - host4
  {% elif somevar == 'differentval' %}
    - host5
    - host6
  {% endif %}"

Then I have a tasks/main.yml with this:

- name: Do these things on specific hosts
command:
  cmd: "echo hello"
delegate_to: "{{ item }}"
with_items: "{{ var_list }}"

The output I get when I run the playbook fails with
ansible_loop_var: item item: ' - host5 - host6 ' msg: 'Failed to connect to the host....

So Ansible is treating "var_list" as a string with all values stringed together (including the hyphens), rather than as a list as desired. I have tried adding and removing hyphens to the opening and closing {%- -%}, and I tried the alternate method of using [host1,host2] on a single line, but again it was not turned into a list. What am I missing here?

1 Answers

You've asked Jinja to create a string " ... - host1 ... ". The statement you use

- hosts: localhost
  vars:
    somevar: someval
    var_list: "{% if somevar == 'someval' %}
        - host1
        - host2
        - host3
        - host4
      {% elif somevar == 'differentval' %}
        - host5
        - host6
      {% endif %}"
    - debug:
        var: var_list
    - debug:
        msg: "{{ var_list|type_debug }}"

gives

  var_list: ' - host1 - host2 - host3 - host4 '

  msg: str

There are many options on how to get a list. For example, use literal to create the YAML list structure

- hosts: localhost
  vars:
    somevar: someval
    var_list: |
      {% if somevar == 'someval' %}
      - host1
      - host2
      - host3
      - host4
      {% elif somevar == 'differentval' %}
      - host5
      - host6
      {% endif %}
  tasks:
    - debug:
        var: var_list
    - debug:
        msg: "{{ var_list|type_debug }}"

gives

  var_list: |-
    - host1
    - host2
    - host3
    - host4

  msg: str

and convert the string to a list, e.g.

    - debug:
        var: var_list|from_yaml
    - debug:
        msg: "{{ var_list|from_yaml|type_debug }}"

gives

  var_list|from_yaml:
  - host1
  - host2
  - host3
  - host4

  msg: list

A simpler option, to get a list, is using the {{ ... }} expression, e.g.

- hosts: localhost
  vars:
    somevar: someval
    var_list: "{{ (somevar == 'someval')|ternary(l1, l2) }}"
    l1:
      - host1
      - host2
      - host3
      - host4
    l2:
      - host5
      - host6
  tasks:
    - debug:
        var: var_list
    - debug:
        msg: "{{ var_list|type_debug }}"

gives

  var_list:
  - host1
  - host2
  - host3
  - host4

  msg: list
Related