ansible looping through the result and finding files

219 views Asked by At

I am using ansible to configire 10-20 linux systems. I have a set of tools that I define in my invetory files with versions, as:

tools:
  - tool: ABC
    version: 7.8
  - tool: XYZ
    version: 8.32.1

Now, in my playback yml file, I would like to loop through them and have the necessay installation logic. Such as:

DEBUG tools loop

  - name: Find installer files
    copy:
      src=
    with_items:
    - "{{ tools }}"
    when:
      tools.tool == "ABC"

In my case, {{tools.tool}}/{{tools.version}} has a tgz file which I need to unarchive at a remote location. Do you know how to do this? I have tried these:

- name: Find installer files
    vars:
      files: {{ lookup("fileglob",'tools/{{item.tool}}/linux/{{item.version}}/*') }}
    unarchive:
      src: "{{ files }}"
      dest: "tools/{{item.tool}}/{{item.version}}/"
    with_items:
    - "{{ tools }}"
    when:
      item.tool == "ABC"

- name: Find installer files
   debug:
     msg: "{{ item}}"
   with_items:
   - "{{ tools }}"
   with_fileglob:
   - "tools/{{item.tool}}/linux/{{item.version}}/*"
   when:
     item.toolchain == "ABC"

But none worked. Thanks for the help.

2

There are 2 answers

2
EOhm On BEST ANSWER

It's not that simple as Your own solution breaks if there are multiple files in the directory, I assume.
So if You only have one file in the directory I wouldn't use fileglob at all but define a fixed name for it that You can generate knowing tool and version.

I also see the need for such sort of things often but did not found any nice solution for that. Only such ugly thing as:

- name: example book
  hosts: localhost
  become: false
  gather_facts: false
  vars:
    tools:
      - tool: ABC
        version: 7.8
      - tool: XYZ
        version: 8.32.1
    tools_files: []
  tasks:
    - name: prepare facts
      set_fact:
        tools_files: "{{ tools_files + [{'tool': item.tool | string, 'version': item.version | string, 'files': lookup('fileglob', 'tools/' ~ item.tool ~ '/linux/' ~ item.version ~ '/*', wantlist=True)}] }}"
      with_items:
        - "{{ tools }}"
    - name: action loop
      debug:
        msg: "{{ {'src': item[1], 'dest': 'tools/' ~ item[0].tool ~ '/' ~ item[0].version ~ '/'} }}"
      with_subelements:
        - "{{ tools_files }}"
        - files
      when:
        item[0].tool == "ABC"

or

- name: example book
  hosts: localhost
  become: false
  gather_facts: false
  vars:
    tools:
      - tool: ABC
        version: 7.8
      - tool: XYZ
        version: 8.32.1
    tools_files: []
  tasks:
    - name: prepare facts
      set_fact:
        tools_files: "{{ tools_files + [{'tool': item.tool | string, 'version': item.version | string, 'files': lookup('fileglob', 'tools/' ~ item.tool ~ '/linux/' ~ item.version ~ '/*', wantlist=True)}] }}"
      with_items:
        - "{{ tools }}"
    - name: action loop
      debug:
        msg: "{{ {'src': item[1], 'dest': 'tools/' ~ item[0].tool ~ '/' ~ item[0].version ~ '/'} }}"
      with_items:
        - "{{ tools_files | subelements('files') }}"
      when:
        item[0].tool == "ABC"

Maybe I miss somthing because such things are a very basic feature (looping throug an array generating a result array beeing able to use all functions available and not just map using filters where some important things are just not available or cannot be used because map gives the inport as first argument to filter always).

0
wantro On

That was actually simple. This worked for me:

- name: Find installer files
  unarchive:
    src: 
    "lookup('fileglob','tools/item.tool/linux/item.version/*') }}"
    dest: "tools/{{item.tool}}/{{item.version}}/"
    with_items:
    - "{{ tools }}"
    when:
      item.tool == "ABC"