Search code examples
ansiblejinja2ansible-template

Add new line to template for each item in a list


Given the following example list and Jinja template:

List:

list:
    - foo
    - bar

Jinja template:

{% for key in list %}
results:
      - "{{ key }}"
{% endfor %}

I am able to produce the following output:

results:
    - foo
results:
    - bar

How can I instead append a line, for each item in the list, to the template to produce this result?

results:
    - foo
    - bar

Is this possible with Ansible without using something like lineinfile? I am moreorless trying to replicate the Helm range filter which might look like this:

results:
    {{- range .Values.list }}
    - {{ . }}
    {{- end }}

The join filter appears to get me a little closer. For example:

results:
    - "{{ list | join('\n- ') }}"

Produces the following. But it is not syntactically correct yet:

results:
    - "foo
- bar"

Solution

  • Given the list

    list:
        - foo
        - bar
    

    Q: "Produce this result!"

    results:
        - foo
        - bar
    

    A: There are more options:

    1. You can iterate the list
        - copy:
            dest: /tmp/test.yml
            content: |
              results:
              {% for key in list %}
                  - {{ key }}
              {% endfor %}
    

    gives

    shell> cat /tmp/test.yml 
    results:
        - foo
        - bar
    

    You can put the template into a file

    shell> cat templates/test.yml.j2
    results:
    {% for key in list %}
        - {{ key }}
    {% endfor %}
    

    Then, the template module gives the same result

        - template:
            dest: /tmp/test.yml
            src: test.yml.j2
    

    1. The next option is Ansible formatting filters and Jinja indent filter. The task below gives the same result
        - copy:
            dest: /tmp/test.yml
            content: |
              results:
                  {{ list|to_nice_yaml|indent(4) }}
    
    1. You can use tab if you want to
        - copy:
            dest: /tmp/test.yml
            content: |
              results:
              {% for key in list %}
              {{ '{}- {}'.format(tab, key) }}
              {% endfor %}
          vars:
            tab: "{{ '\t' }}"
    

    The tab spacing will depend on the pager

    shell> cat /tmp/test.yml 
    results:
        - foo
        - bar