Search code examples
ansibleprompt

Ansible playbook file selection task


It's probably against best practice but using an Ansible playbook, is it possible to get a list of files from one task and then offer a user prompt to select one of the files to pass into a variable?

For example:

Choose file to select:
1. file1.txt
2. file2.txt
3. file3.txt
> 1

The playbook would theoretically pause for the user input and then pass the resulting file selection into a variable to use in a future task.

Many thanks in advance.


Solution

  • Use pause. For example, given the files

    shell> tree files
    files
    ├── file1.txt
    ├── file2.txt
    └── file3.txt
    
    0 directories, 3 files
    

    Update

    the playbook

    shell> cat playbook.yml 
    - hosts: localhost
    
      vars:
    
        dir: files
        my_files: "{{ q('fileglob', dir ~ '/*')|map('basename') }}"
        selected_file: "{{ dir }}/{{ my_files[result.user_input|int - 1] }}"
    
      tasks:
    
        - pause:
            prompt: |-
              Choose file to select:
              {% for file in my_files %}
              {{ loop.index }} {{ dir }}/{{ file }}
              {% endfor %}
          register: result
    
        - debug:
            var: selected_file
    

    gives (when selecting the 2nd file and typing '2<ENTER')

    shell> ansible-playbook playbook.yml 
    
    PLAY [localhost] ****
    
    TASK [pause] ****
    [pause]
    Choose file to select:
    1 files/file3.txt
    2 files/file2.txt
    3 files/file1.txt
    :
    2^Mok: [localhost]
    
    TASK [debug] ****
    ok: [localhost] => 
      selected_file: files/file2.txt
    
    PLAY RECAP ****
    localhost: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
    

    Origin

    the playbook below

    shell> cat playbook.yml
    - hosts: localhost
      tasks:
        - find:
            path: files
          register: result
        - set_fact:
            my_files: "{{ result.files|map(attribute='path')|list|sort }}"
        - pause:
            prompt: |
              Choose file to select:
              {% for file in my_files %}
              {{ loop.index }} {{ file }}
              {% endfor %}
          register: result
        - debug:
            msg: "selected file: {{ my_files[result.user_input|int - 1] }}"
    

    gives (when selecting the 2nd file and typing '2<ENTER')

    shell> ansible-playbook playbook.yml 
    
    PLAY [localhost] ****
    
    TASK [find] ****
    ok: [localhost]
    
    TASK [set_fact] ****
    ok: [localhost]
    
    TASK [pause] ****
    [pause]
    Choose file to select:
    1 files/file1.txt
    2 files/file2.txt
    3 files/file3.txt
    :
    ok: [localhost]
    
    TASK [debug] ****
    ok: [localhost] => {
        "msg": "selected file: files/file2.txt"
    }
    
    PLAY RECAP ****
    localhost: ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0