Search code examples
ansibleansible-2.xansible-awx

ansible lookup plugin does not work on AWX


I tried lookup on machine installed on it ansible and it works, but when uploading playbook to awx it does not work.

  - name: get file
    set_fact:
      policer: "{{ lookup('file', 'file.txt') }}"

it gives An unhandled exception occurred while running the lookup plugin 'file'. Error was a <class 'ansible.errors.AnsibleError'>, original message: could not locate file in lookup"

although the file in the same repo of playbook, and have worked on machine but not awx. And if there is something specific to remote hosts how to know the path


Solution

  • Ansible Lookup plugins "execute and are evaluated on the Ansible control machine."

    1. The play works fine when you run it at the localhost (control machine) where the file is located
    shell> hostname
    test_11
    shell> cat /tmp/file.txt 
    content of file /tmp/file.txt
    
    shell> cat pb1.yml
    - hosts: localhost
      vars:
        policer: "{{ lookup('file', '/tmp/file.txt') }}"
      tasks:
        - debug:
            var: policer
    
    shell> ansible-playbook pb1.yml
    
    PLAY [localhost] *****************************************************************************
    
    TASK [debug] *********************************************************************************
    ok: [localhost] => 
      policer: content of file /tmp/file.txt
    
    PLAY RECAP ***********************************************************************************
    localhost: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    1. When you move to another controller (might be AWX) the file remains at the remote host (test_11 in the example) and is not available at the localhost controller. You can test it. See the block below
    shell> hostname
    awx
    shell> cat /tmp/file.txt
    cat: /tmp/file.txt: No such file or directory
    shell> ssh admin@test_11 cat /tmp/file.txt
    content of file /tmp/file.txt
    
    shell> cat pb2.yml
    - hosts: test_11
      vars:
        policer: "{{ lookup('file', '/tmp/file.txt') }}"
      tasks:
        - block:
            - stat:
                path: /tmp/file.txt
              register: st
            - debug:
                var: st.stat.exists
          delegate_to: localhost
        - debug:
            var: policer
    
    shell> ansible-playbook pb2.yml
    
    PLAY [test_11] *******************************************************************************
    
    TASK [stat] **********************************************************************************
    ok: [test_11 -> localhost]
    
    TASK [debug] *********************************************************************************
    ok: [test_11 -> localhost] => 
      st.stat.exists: false
    
    TASK [debug] *********************************************************************************
    [WARNING]: Unable to find '/tmp/file.txt' in expected paths (use -vvvvv to see paths)
    

    fatal: [test_11]: FAILED! => msg: 'An unhandled exception occurred while templating ''{{ lookup(''file'', ''/tmp/file.txt'') }}''. Error was a <class ''ansible.errors.AnsibleError''>, original message: An unhandled exception occurred while running the lookup plugin ''file''. Error was a <class ''ansible.errors.AnsibleError''>, original message: could not locate file in lookup: /tmp/file.txt. could not locate file in lookup: /tmp/file.txt'

    PLAY RECAP ***********************************************************************************
    test_11: ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
    

    There are many options for how to fix it. The trivial one is moving also the file to the localhost controller. If the file remains at the remote host you can either read it by command or slurp, or fetch it. The module command always reports changed. The modules slurp and fetch are idempotent.

    1. Read the file by command
    shell> cat pb3.yml
    - hosts: test_11
      vars:
        policer: "{{ out.stdout }}"
      tasks:
        - command: cat /tmp/file.txt
          register: out
        - debug:
            var: policer
    
    shell> ansible-playbook pb3.yml
    
    PLAY [test_11] *******************************************************************************
    
    TASK [command] *******************************************************************************
    changed: [test_11]
    
    TASK [debug] *********************************************************************************
    ok: [test_11] => 
      policer: content of file /tmp/file.txt
    
    PLAY RECAP ***********************************************************************************
    test_11: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    1. Read the file by slurp. This should be used for smaller files only because (quoting from slurp): "This module returns an ‘in memory’ base64 encoded version of the file, take into account that this will require at least twice the RAM as the original file size."
    shell> cat pb4.yml
    - hosts: test_11
      vars:
        policer: "{{ out.content|b64decode }}"
      tasks:
        - slurp:
            path: /tmp/file.txt
          register: out
        - debug:
            var: policer
    
    shell> ansible-playbook pb4.yml
    
    PLAY [test_11] *******************************************************************************
    
    TASK [slurp] *********************************************************************************
    ok: [test_11]
    
    TASK [debug] *********************************************************************************
    ok: [test_11] => 
      policer: |-
        content of file /tmp/file.txt
    
    PLAY RECAP ***********************************************************************************
    test_11: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    1. The next option is to fetch the file to the local directory dest (will be created). By default, the file(s) is stored in the directory named by the remote host
    shell> cat pb5.yml
    - hosts: test_11
      vars:
        file_path: "/tmp/fetched_files/{{ inventory_hostname }}/tmp/file.txt"
        policer: "{{ lookup('file', file_path)  }}"
      tasks:
        - fetch:
            src: /tmp/file.txt
            dest: /tmp/fetched_files
        - debug:
            var: policer
    
    shell> ansible-playbook pb5.yml
    
    PLAY [test_11] *******************************************************************************
    
    TASK [fetch] *********************************************************************************
    changed: [test_11]
    
    TASK [debug] *********************************************************************************
    ok: [test_11] => 
      policer: content of file /tmp/file.txt
    
    PLAY RECAP ***********************************************************************************
    test_11: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    shell> cat /tmp/fetched_files/test_11/tmp/file.txt 
    content of file /tmp/file.txt
    

    Notes