Ansible copy file using command syntax - ansible

The assignment is as follows:
Lets create a file touch afile.txt, prior to creating tasks
Create a playbook test.yml to
copy afile.txt from your control machine to host machine at /home/ubuntu/ location as afile_copy.txt and
debug the above task to display the returned value
Execute your playbook (test.yml) and observe the output
I did following
Created the afile_copy.txt using touch
created the playbook as follows:
- name: copy files
hosts: all
tasks:
- name: copy file
command: cp afile.txt /home/ubuntu/afile_copy.txt
register:output
- debug: var=output
When I run the playbook using the command
ansible-playbook -i myhosts test.yml
it fails with the error message
stderr: cp: cannot stat 'afile.txt' : no such file or directory
The afile.txt is present in directory /home/scrapbook/tutorial

You should use copy module instead of command module. command module executes on the remote node.

1)first execute the ad-hoc command for copy:
ansible all -i myhosts -m copy -a "src=afile.txt dest=/home/ubuntu/"
2) After execute the above command,execute this playbpook:
hosts: all
tasks:
stat: path=/home/ubuntu/afile_copy.txt
register: st
name: rename
command: mv afile.txt /home/ubuntu/afile_copy.txt
when: not st.stat.exists
register: output
debug: var=output

Copy module should be used instead of command module
- name: copy files
hosts: all
tasks:
- name: copy file
copy: src=afile.txt dest=/home/ubuntu/afile_copy.txt
register:output
- debug: var=output

---
- name: copy files
hosts: all
tasks:
- name: copy file
copy:
src: afile.txt
dest: /home/ubuntu/afile_copy.txt
register: output
- debug: var=output

Related

Can I modify Ansible 'remote_tmp' on a per task basis?

I am running some tasks with delegate_to. When those tasks run, they use the same remote_tmp directory setup from the ansible.cfg.
However, due to permissions and directory size issues, I need to change the remote_tmp directory for tasks that I am using delegate_to for.
Example:
- name: Create Temp Dir
delegate_to: localhost
file:
path: "{{ my_temp_dir }}"
state: directory
I am using Ansible 2.3.2.
As of 2.5, yes, changing remote_tmp, which is an ansible_* variable is something possible, by adding it to the vars of the said task.
For example:
- tempfile:
state: file
suffix: temp
vars:
ansible_remote_tmp: /tmp/temp_file_1_task
Given a playbook with the two tasks:
- tempfile:
state: file
suffix: temp
vars:
ansible_remote_tmp: /tmp/temp_file_1_task
- tempfile:
state: file
suffix: temp
vars:
ansible_remote_tmp: /tmp/temp_file_2_task
A reduced version of the extra verbose log would yield:
<127.0.0.1> EXEC /bin/sh -c '/usr/local/bin/python /tmp/temp_file_1_task/ansible-tmp-1642453716.1902952-890-119314712082250/AnsiballZ_tempfile.py && sleep 0'
and
<127.0.0.1> EXEC /bin/sh -c '/usr/local/bin/python /tmp/temp_file_2_task/ansible-tmp-1642453716.6039782-905-172576654053914/AnsiballZ_tempfile.py && sleep 0'

ansible copy in different host

I write a simple playbook to copy some configuration files on a certain machine.
I need to copy this file in a different host too for backup. Is possible to declare different host in the same playbook?
I need this cause my "backup host" can be different and I retrieve it from the hostname I use.
I tried both copy and raw module and nothing seems to work
here the example of playbook
- name: find file
find:
file_type: directory
paths: /prd/viv/dat/repository/
patterns: "{{inventory_hostname}}"
recurse: yes
register: find
delegate_to: localhost
- name: Copy MASTER
raw: echo xmonit$(echo {{find.files[0].path}} | cut -d "/" -f7 )
delegate_to: localhost
register: xmonit
- debug:
msg: "{{xmonit.stdout}}"
- name: Copy MASTER raw
raw: sshpass -p "mypass" scp {{find.files[0].path}}/master.cfg myuser#{{xmonit.stdout}}:/prd
delegate_to: localhost
#- name: Copy MASTER
#copy:
#src: "{{find.files[0].path}}/master.cfg"
#dest: /prd/cnf/dat/{{inventory_hostname}}/
edit: if I use the copy module the destination remains that of the main host while the goal is to copy to a third host.
I need to declare a different host for this single task
- name: Copy MASTER
copy:
src: "{{find.files[0].path}}/master.cfg"
dest: /prd/cnf/dat/{{inventory_hostname}}/
Like Zeitounator told me in the comments copy module are the best way to act.
like this it work for me
- name: Copy MASTER
copy:
src: "{{find.files[0].path}}/master.cfg"
dest: /prd/cnf/dat/{{inventory_hostname}}/
delegate_to: xmonit.stdout_lines[0]

copy and running configfiles programatically in ansible

There is a ansible code i am writing. It does two tasks, first is to copy a configuration file to target instance in groups. Second is running that config file to install the application.
I am creating configuration file and inventory programtically so that same suffix is added to both configfile name & groupname in inventory:
Configfile name example : Equivalent group names:
myappconf1 [myapp1]
hostname
myappconf2 [myapp2]
hostname
This is my code for copying files
hosts: all
tasks:
name: Copy file.role1 to host1
copy: src=/tmp/myconf1 dest=/tmp
when:
- "'myapp1' in group_names"
name: Copy Config File two to to Ldap2
copy: src=/tmp/myconf2 dest=/tmp
when:
- "'myapp2' in group_names"
This is my code for running conf file
hosts: myapp1
tasks:
- command: "/tmp/mainapp/update.sh -f myappconf1"
hosts: myapp2
tasks:
- command: "/tmp/mainapp/update.sh -f myappconf1"
But depending on user input uncertain number of conf files and groups can be created so I would like to do task more programatically. desired code may look like:
[task for copying file]
hosts: ~(myapp)
tasks:
- copy: copy the appropriate file to the host
example: copy myappconf4 to myapp4
- command: run the commmand with appropirate file
example: for myapp3, command: /tmp/mainapp/update.sh -f myappconf3
Can someone please suggest me what i can use to make my code more generic and efficient ?
You can use group variables like this,
#File : "myapp1/group_vars/all/vars_file.yml"
# Application settings
app_name: "myapp1"
copy_file: "myapp1conf1"
.
.
# other variables used for myapp1
Then use 2nd folder for 2nd app
#File : "myapp2/group_vars/all/vars_file.yml"
# Application settings
copy_file: "myapp2conf2"
.
.
# other variables used for myapp2
And In your code modify as below,
hosts: all
-tasks
-name: Copy file.role1 to host1
copy: src=/tmp/{{ copy_file }} dest=/tmp
-name : execute script
command: "/tmp/mainapp/update.sh -f {{ app_name }}"
Now depending upon the environment use the user input during the play time as below,
ansible-play -i myapp1 main.yml
or
ansible-play -i myapp2 main.yml
I populated variables with my python code in below format to resolve the issue:
[myapp]
host1 conf_file="myappconf1"
host2 conf_file="myappconf2"
then in my code i used the variable for both copy and running configfile tasks.

Ansible writing output from multiple task to a single file

In Ansible, I have written an Yaml playbook that takes list of host name and the executes command for each host. I have registered a variable for these task and at the end of executing a task I append output of each command to a single file.
But every time I try to append to my output file, only the last record is getting persisted.
---
- hosts: list_of_hosts
become_user: some user
vars:
output: []
tasks:
- name: some name
command: some command
register: output
failed_when: "'FAILED' in output"
- debug: msg="{{output | to_nice_json}}"
- local_action: copy content='{{output | to_nice_json}}' dest="/path/to/my/local/file"
I even tried to append using lineinfile using insertafter parameter yet was not successful.
Anything that I am missing?
You can try something like this:
- name: dummy
hosts: myhosts
serial: 1
tasks:
- name: create file
file:
dest: /tmp/foo
state: touch
delegate_to: localhost
- name: run cmd
shell: echo "{{ inventory_hostname }}"
register: op
- name: append
lineinfile:
dest: /tmp/foo
line: "{{ op }}"
insertafter: EOF
delegate_to: localhost
I have used serial: 1 as I am not sure if lineinfile tasks running in parallel will garble the output file.
Ansible doc recommend use copy:
- name: get jstack
shell: "/usr/lib/jvm/java/bin/jstack -l {{PID_JAVA_APP}}"
args:
executable: /bin/bash
register: jstackOut
- name: write jstack
copy:
content: "{{jstackOut.stdout}}"
dest: "tmp/jstack.txt"
If you want write local file, add this:
delegate_to: localhost
Why to complicate things ?
I did this like that and it worked:
ansible-playbook your_playbook.yml >> /file/you/want/to/redirect/output.txt
you can also try some parsing with grep or some other stuff with tee -a.

a newbee trying to use ansible and a weird error

I have this playbook:
- name: main playbook
hosts: 127.0.0.1
connection: local
sudo: Yes
gather_facts: True
vars_files:
- /home/core/REPO/alonso/core2door-integration/workflows/core2door.ansible/vars-feed.yml
tasks:
- include: tasks/feed-adapter.yml
tasks/feed-adapter.yml
# This playbook deploys feed-adapter application in this host. This app needs a jar that basically writes to HDFS and write a log in a system,
# actually Impala. Variables are described within vars-feed.yml file.
- name: feed-adapter playbook
hosts: "{{host_feed}}"
remote_user: "{{remote-user}}"
sudo: Yes
- name: Creates feed_adapter_outputpath directory
file: path=/var/app/feed-adapter/ state=directory
- name: Creates check-feed-adapter-folders_outputpath directory
file: path=/var/app/check-feed-adapter-folders/ state=directory
- name: Copy supervisor conf files to /etc/supervisor.d folder
copy: src=/home/core/REPO/alonso/core2door-integration/feed-adapter/feed_adapter_Sip_Pub.conf dest=/etc/supervisor.d/feed_adapter_Sip_Pub.conf owner=root group=root mode=0644
- name: Copy generated jar to destination folder
copy: src=/home/core/REPO/alonso/core2door-integration/feed-adapter/target/feed-adapter-0.0.1-SNAPSHOT.jar dest=/var/app/check-feed-adapter-folders/feed-adapter.jar mode=0644
- name: Copy necessary .properties files to destination folder
copy: src=/home/core/REPO/alonso/core2door-integration/feed-adapter/feed-adapter-SIP-Pub.properties dest=/var/app/check-feed-adapter-folders/feed-adapter-SIP-Pub.properties mode=0644
- name: Copy check-feed-adapter-folders jar to destination folder
copy: src=/home/core/REPO/alonso/core2door-integration/CheckFeedAdapterFolders/target/CheckFeedAdapterFolders-0.0.1-SNAPSHOT.jar dest=/var/app/check-feed-adapter-folders/CheckFeedAdapterFolders.jar mode=0644
- name: Copy check.sh script to destination folder
copy: src=/home/core/REPO/alonso/core2door-integration/CheckFeedAdapterFolders/check.sh dest=/var/app/check-feed-adapter-folders/check.sh mode=0644
and when I try to run the playbook, it returns me this output:
$ ansible-playbook playbook.yml --syntax-check --i hosts.txt
/usr/lib/python2.6/site-packages/setuptools-12.0.5-py2.6.egg/pkg_resources/__init__.py:1222: UserWarning:
/home/core/.python-eggs is writable by group/others and vulnerable to
attack when used with get_resource_filename. Consider a more secure
location (set with .set_extraction_path or the PYTHON_EGG_CACHE
environment variable).
playbook: playbook.yml
ERROR: copy is not a legal parameter at this level in an Ansible Playbook
Please help, i am newbee with ansible.
UPDATE
after Daniel's advice, I have indented carefully the playbook and I am getting this error:
$ vi tasks/feed-adapter.yml
$ ansible-playbook playbook.yml --syntax-check --i hosts.txt
/usr/lib/python2.6/site-packages/setuptools-12.0.5-py2.6.egg/pkg_resources/__init__.py:1222: UserWarning:
/home/core/.python-eggs is writable by group/others and vulnerable to
attack when used with get_resource_filename. Consider a more secure
location (set with .set_extraction_path or the PYTHON_EGG_CACHE
environment variable).
playbook: playbook.yml
ERROR: file is not a legal parameter at this level in an Ansible Playbook
UPDATE 2:
The execution of ansible-playbook with -vvvv shows the same output:
ERROR: file is not a legal parameter at this level in an Ansible Playbook
[core#dub-vcd-vms171 core2door.ansible]$ ansible-playbook --i hosts.txt -vvvv playbook.yml
/usr/lib/python2.6/site-packages/setuptools-12.0.5-py2.6.egg/pkg_resources/__init__.py:1222: UserWarning: /home/core/.python-eggs is writable by group/others and vulnerable to attack when used with get_resource_filename. Consider a more secure location (set with .set_extraction_path or the PYTHON_EGG_CACHE environment variable).
ERROR: file is not a legal parameter at this level in an Ansible Playbook
I guess that the error comes with this line:
- name: Creates feed_adapter_outputpath directory
file: path=/var/app/feed-adapter/ state=directory
You have to be very careful with line indention when working with yaml files. The error here is probably caused by the copy element in line 28:
- name: ...
copy: ...
Add two whitespaces in front of the copy, so it looks like this:
- name: ...
copy: ...

Resources