user6005619
user6005619

Reputation: 27

Ansible: Looping Multiline Strings into Single Line Strings

I have a loop that is now producing this error:

Invalid data passed to 'loop', it requires a list, got this instead: 1, 2, 3. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup

Here is my task as of now:

- name: Delete anything that is not excluded
  win_shell: Get-ChildItem -Exclude {{ '"%02x",' | format(item) }} "test_directory", "test_file.txt" | Remove-Item -Recuse -Force
  args:
    chdir: C:\\Temp
  loop: "{{ range(1, 3 + 1) | join(', ') }}"

I would like the loop to fill in the PowerShell command like this:

Get-ChildItem -Exclude "01", "02", "03", "test_directory", "test_file.txt" | Remove-Item -Recuse -Force

I am also open to using other Ansible Windows modules or any other methods to get this working as well.

Upvotes: 1

Views: 1037

Answers (1)

Zeitounator
Zeitounator

Reputation: 44615

Note: I did not play the following win_shell tasks but only used debug on my side to validate my solutions.


You use loop when you want to play a given module n times. You want to format a list and use it to create a single command once.

In this case, the loop should be moved to a previous task where you will construct the list of formatted item iteratively. This could look like:

- name: Create a formatted list of exclusions
  set_fact:
    formatted_exclude_list: >-
      {{ formatted_exclude_list | default([]) + ['"%02x"' | format(item)] }}
  loop: "{{ range(1, 4) | list }}"

- name: Delete anything that is not excluded
  win_shell: Get-ChildItem -Exclude {{ formatted_exclude_list | join(', ') }}, "test_directory", "test_file.txt" | Remove-Item -Recuse -Force
  args:
    chdir: C:\\Temp

Although this is a less "ansiblish" way, you can acheive the same goal in a single task with quite some more templating

- name: Delete anything that is not excluded
  vars:
    exclude_list: "{{ range(1, 4) | list }}"
    formatted_exclude_list: >-
      {%- set my_list = [] -%}
      {%- for item in exclude_list -%}
        {{ my_list.append('"%02x"' | format(item)) }}
      {%- endfor -%}
      {{ my_list }}
  win_shell: Get-ChildItem -Exclude {{ formatted_exclude_list | join(', ') }}, "test_directory", "test_file.txt" | Remove-Item -Recuse -Force
  args:
    chdir: C:\\Temp

Upvotes: 1

Related Questions