Search code examples
ansibleftpeoflftp

Ansible play to upload ftp file using lftp


I setup ftp server using ansible and verified it's working by manually doing lftp from my localhost

I uploaded a file using put and was able to find the file in ftp server, when i do ls.

I wrote a play to upload file to ftp server and it returned success always. However, i can't find the file that I uploaded using my play. Then i edited my play to display result register and found a warning. See below

---
- name: test ftp upload
  hosts: localhost
  tasks:
    - name: install lftp
      yum:
        name: lftp
    - name: upload file
      shell: >
        lftp ansible1.example.com<<EOF
        cd pub
        put /etc/hosts
        bye
        EOF
      register: result

    - name: display result
      debug:
        var: result

Below is the output I got after running the play

PLAY [test ftp upload] ****************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************
ok: [localhost]

TASK [install lftp] *******************************************************************************************************************************************************************
ok: [localhost]

TASK [upload file] ********************************************************************************************************************************************************************
changed: [localhost]

TASK [display result] *****************************************************************************************************************************************************************
ok: [localhost] => {
    "result": {
        "changed": true,
        "cmd": "lftp ansible1.example.com<<EOF cd pub put /etc/hosts bye EOF\n",
        "delta": "0:00:00.010150",
        "end": "2020-04-04 09:15:26.305530",
        "failed": false,
        "rc": 0,
        "start": "2020-04-04 09:15:26.295380",
        "stderr": "/bin/sh: warning: here-document at line 0 delimited by end-of-file (wanted `EOF')",
        "stderr_lines": [
            "/bin/sh: warning: here-document at line 0 delimited by end-of-file (wanted `EOF')"
        ],
        "stdout": "",
        "stdout_lines": []
    }
}

PLAY RECAP ****************************************************************************************************************************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

I am not able to understand the warning w.r.t EOF part and if it's the reason for the file upload not happening. Because, I use the below shell script (which is basically the same steps from the play) to upload file and it works perfect.

lftp ansible1.example.com<<EOF
cd pub
put /etc/hosts
bye
EOF

Solution

  • You have used the wrong scalar block style indicator (see documentation) for your shell command.

    You need to keep the new lines in your piece of shell code. In this case, you have to use the literal scalar block indicator: |

    You have used the folded scalar block indicator (>) which will basically convert new lines to spaces (although it is a little more complicated as explained in this other source). So your current piece of shell code expands to a single line in your shell (you can debug the value to see for yourself):

    lftp ansible1.example.com<<EOF cd pub put /etc/hosts bye EOF
    

    The following should fix your current problem:

        - name: upload file
          shell: |
            lftp ansible1.example.com<<EOF
            cd pub
            put /etc/hosts
            bye
            EOF
          register: result