module (copy) is missing interpreter line

Hello everyone,

It seems quite difficult to perform a very simple task: save the content of a variable to a file.
This variable content is not just a string, but several lines as shown by the debug module:

“out.stdout_lines”: [
[
“Using 2011 out of 262144 bytes, uncompressed size = 3870 bytes”,
“!”,
“! Last configuration change at 18:34:42 UTC Thu Jun 30 2016 by admin”,
“!”,
“version 15.2”,

“hostname IOSv_L2_1”,

“end”,
“”
]
]

Trying to use the “copy” module leads to the previously mentioned issue:

  • name: Copying config into local file
    copy:
    content: “{{ out.stdout_lines }}”
    dest: host_vars/{{ inventory_hostname }}/{{ inventory_hostname }}_{{ config }}.txt

=>

TASK [ios_pull_config : Copying config into local file] ************************
task path: /home/actionmystique/Program-Files/Ubuntu/Ansible/git-Ansible/roles/ios_pull_config/tasks/main.yml:59
<192.168.137.242> ESTABLISH LOCAL CONNECTION FOR USER: root
<192.168.137.242> EXEC /bin/sh -c ‘( umask 77 && mkdir -p “echo $HOME/.ansible/tmp/ansible-tmp-1467812828.82-260068933148720” && echo ansible-tmp-1467812828.82-260068933148720=“echo $HOME/.ansible/tmp/ansible-tmp-1467812828.82-260068933148720” ) && sleep 0’
<192.168.137.242> PUT /tmp/tmpotKrzg TO /root/.ansible/tmp/ansible-tmp-1467812828.82-260068933148720/stat
<192.168.137.242> EXEC /bin/sh -c ‘LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1467812828.82-260068933148720/stat; rm -rf “/root/.ansible/tmp/ansible-tmp-1467812828.82-260068933148720/” > /dev/null 2>&1 && sleep 0’
<192.168.137.242> EXEC /bin/sh -c ‘( umask 77 && mkdir -p “echo $HOME/.ansible/tmp/ansible-tmp-1467812828.91-263479362702141” && echo ansible-tmp-1467812828.91-263479362702141=“echo $HOME/.ansible/tmp/ansible-tmp-1467812828.91-263479362702141” ) && sleep 0’
<192.168.137.242> PUT /tmp/tmp5gr0LH TO /root/.ansible/tmp/ansible-tmp-1467812828.91-263479362702141/source
fatal: [192.168.137.242]: FAILED! => {“failed”: true, “msg”: “module (copy) is missing interpreter line”}

In /etc/ansible/ansible.cfg with ansible 2.1.1.0, the default library path is defined:
library = /usr/lib/python2.7/dist-packages/ansible

Also, there are 2 default “copy.py” in the downstream tree:

  • ./modules/core/files/copy.py
  • ./plugins/action/copy.py
    Isn’t this confusing for Ansible?

How do we know that Ansible uses its module and not python’s own “copy.py” available in:

/usr/lib/python3.5/copy.py
/usr/lib/python2.7/copy.py

Exactly same issue if I slightly modify the call in the role with:

  • name: Saving config into local file
    local_action:
    copy content=“{{ out.stdout_lines }}” dest=host_vars/“{{ inventory_hostname }}”/“{{ inventory_hostname }}”_“{{ config }}”.txt

Also, I haven’t mentioned the fact that I do not experience that issue with other modules.

Also, downgrading from 2.1.1.0 (which is a RC) to stable 2.1.0 does not change anything as far as this issue is concerned.

The copy module is not design for this, use the template module instead.

No: the template module only deals with files, not with a variable.

If you are referring to “ios_template”, the module is designed to push a running-config, not to pull it from the remote device.

Yes, the template module, in your first post you write "save the content of a variable to a file" that is exactly what the template module is highly capable of doing
https://docs.ansible.com/ansible/template_module.html

The template will be Jinja2 code looping the variable and write the content to a file.

I combined my posts #2 & #3, and it worked!
That is to say, downgrading to 2.1.0 & using “local_action: copy…” enables me to save the content of the variable into a local file.

However, the file is barely readable because all line feeds have been removed and each line is enclosed by “”, but at least that’s a start.
That means some formatting is necessary, unless another way exists.

I’ve just tried with 2.1.1.0 RC2 and it works. As a conclusion, and since there is a typo in my first post, here is one solution:

  • name: Saving config into local file
    local_action:
    copy content=“{{ out.stdout }}” dest=files/configs/{{ inventory_hostname }}/{{ inventory_hostname }}{{ config }}{{ ansible_date_time.date }}{{ ansible_date_time.time }}{{ ansible_date_time.tz }}.txt

  • name: Reformatting config file
    local_action:
    script {{ role_path }}/…/…/files/scripts/format-config.sh files/configs/{{ inventory_hostname }}/{{ inventory_hostname }}{{ config }}{{ ansible_date_time.date }}{{ ansible_date_time.time }}{{ ansible_date_time.tz }}.txt