Arun Suryan
Arun Suryan

Reputation: 1693

Populate a list of dictionary through a loop

I want to generate a list of dictionaries through the loop. I came across that we can use with_sequence to generate the integer sequences in ansible. I am getting the following error:

The offending line appears to be:

- { "dir": "{{ mat_cleaner_input_file_path_flow }}/{{ item }}" }
      with_sequence: start=0 end={{ http_range }}
      ^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

    with_items:
      - {{ foo }}

Should be written as:

    with_items:
      - "{{ foo }}"

My config.j2:

{{ cleaner_config | to_nice_yaml(indent=2) }}

My task.yml:

---
- name: Test dictionaries playbook
  hosts: localhost
  connection: local

  vars:
    mat_cleaner_input_file_path_flow: "/var/opt/miq/sftp/edr-flow"
    mat_cleaner_input_file_path_http: "/var/opt/miq/sftp/edr-http"
    mat_cleaner_input_retention_period: 21600
    http_range: 5
    cleaner_config:
      - { "dir": "{{ mat_cleaner_input_file_path_flow }}/{{ item }}" }
      with_sequence: start=0 end={{ http_range }}

  tasks:
    - name: Set Cleaner Config
      template:
        src: /home/osboxes/CleanerConfig/cleaner.config.j2
        dest: /home/osboxes/CleanerConfig/output
      delegate_to: localhost
      with_items: cleaner_config

I want the final output file to be:

dir: /var/opt/miq/sftp/edr-flow/0
dir: /var/opt/miq/sftp/edr-flow/1
dir: /var/opt/miq/sftp/edr-flow/2

Upvotes: 2

Views: 224

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68189

The format of the output file you want is text. It's not a list. You can create it by Jinja, e.g.

    mat_cleaner_input_file_path_flow: "/var/opt/miq/sftp/edr-flow"
    http_range: 3
    cleaner_config: |
      {% for i in range(http_range) %}
      {{ mat_cleaner_input_file_path_flow }}/{{ i }}
      {% endfor %}

gives

  cleaner_config: |-
    /var/opt/miq/sftp/edr-flow/0
    /var/opt/miq/sftp/edr-flow/1
    /var/opt/miq/sftp/edr-flow/2

Then, because it's not a list, you don't have to use to_nice_yaml in the template. Use indent instead if you want to indent the lines, e.g.

shell> cat cleaner.config.j2
  {{ cleaner_config|indent(2) }}
    - template:
        src: cleaner.config.j2
        dest: output

gives

shell> cat output 
  /var/opt/miq/sftp/edr-flow/0
  /var/opt/miq/sftp/edr-flow/1
  /var/opt/miq/sftp/edr-flow/2

Under normal circumstances, you would simplify the code, omit the cleaner_config variable, and put the Jinja iteration into the template, e.g.

    mat_cleaner_input_file_path_flow: "/var/opt/miq/sftp/edr-flow"
    http_range: 3
shell> cat cleaner.config.j2
{% for i in range(http_range) %}
  {{ mat_cleaner_input_file_path_flow }}/{{ i }}
{% endfor %}

If you want to use a list

    mat_cleaner_input_file_path_flow: "/var/opt/miq/sftp/edr-flow"
    http_range: 3
    cleaner_config_text: |
      {% for i in range(http_range) %}
      - {{ mat_cleaner_input_file_path_flow }}/{{ i }}
      {% endfor %}
    cleaner_config: "{{ cleaner_config_text|from_yaml }}

gives

  cleaner_config:
  - /var/opt/miq/sftp/edr-flow/0
  - /var/opt/miq/sftp/edr-flow/1
  - /var/opt/miq/sftp/edr-flow/2

Now you need to_nice_yaml to format the list, e.g.

shell> cat cleaner.config.j2
  {{ cleaner_config|to_nice_yaml|indent(2) }}

gives

shell> cat output 
  - /var/opt/miq/sftp/edr-flow/0
  - /var/opt/miq/sftp/edr-flow/1
  - /var/opt/miq/sftp/edr-flow/2

Upvotes: 1

Related Questions