Run Ansible Task in localhost - ansible

I need to check one file (/tmp/test.html) exist on localhost and if it exist execute the other tasks.
Can you please help to run this first task (name: Check exist and copy) in localhost(workstation).
localhost: workstation
remotehost: servera,serverb
Below is my playbook.yml
---
- name: Check exist and copy
hosts: all
tasks:
- name: check if file is exists #need to execute this task in workstation
stat:
path: /tmp/test.html
register: file_present
- name: copy to taggroup 1
copy:
src: /tmp/test.html
dest: /tmp/dest1.html
when: file_present.stat.exists == 0 and inventory_hostname in groups ['taggroup1']
- name: copy to taggroup 2
copy:
src: /tmp/test.html
dest: /tmp/dest2.html
when: file_present.stat.exists == 0 and inventory_hostname in groups ['taggroup2']

Module stat is not needed when paths are tested at localhost. For example fail the play if the file /tmp/test.html does not exist and continue the play otherwise.
- hosts: all
vars:
my_file: '/tmp/test.html'
tasks:
- fail:
msg: "{{ my_file }} does not exist. End of play."
when: my_file is not exists
delegate_to: localhost
run_once: true
- debug:
msg: "Continue play."
run_once: true

Try the following:
---
- name: Check exist and copy
hosts: all
tasks:
- name: check if file is exists #need to execute this task in workstation
stat:
path: /tmp/test.html
register: file_present
delegate_to: localhost
- name: copy to taggroup 1
copy:
src: /tmp/test.html
dest: /tmp/dest1.html
when: file_present.stat.exists and inventory_hostname in groups ['taggroup1']
- name: copy to taggroup 2
copy:
src: /tmp/test.html
dest: /tmp/dest2.html
when: file_present.stat.exists and inventory_hostname in groups ['taggroup2']
See the docs.
You can use delegate_to: to run a task on a different machine than the current ansible_host.

Try following
---
- name: Check exist and copy
hosts: all
tasks:
- name: check if file is exists #need to execute this task in workstation
stat: path=/tmp/test.html
register: file_present
delegate_to: localhost
- name: copy to taggroup 1
copy:
src: /tmp/test.html
dest: /tmp/dest1.html
when: file_present.stat.exists and inventory_hostname in groups ['taggroup1']
- name: copy to taggroup 2
copy:
src: /tmp/test.html
dest: /tmp/dest2.html
when: file_present.stat.exists and inventory_hostname in groups ['taggroup2']

Thanks all for the great support. This is the fixed answer.
---
- name: Check exist and copy
hosts: all
tasks:
- name: check if file is exists #need to execute this task in workstation
stat:
path: /tmp/test.html
register: file_present
delegate_to: localhost
run_once_ true
- name: copy to taggroup 1
copy:
src: /tmp/test.html
dest: /tmp/dest1.html
when: file_present.stat.exists and inventory_hostname in groups ['taggroup1']
- name: copy to taggroup 2
copy:
src: /tmp/test.html
dest: /tmp/dest2.html
when: file_present.stat.exists and inventory_hostname in groups ['taggroup2']

Related

In Ansible loop, test existence of files from registered results

I have several files that I need to backup in different directories. I have tried the code below and not working for me.
vars:
file_vars:
- {name: /file1}
- {name: /etc/file2}
- {name: /etc/file/file3}
tasks:
- name: "Checking if config files exists"
stat:
path: "{{ item.name }}"
with_items: "{{ file_vars }}"
register: stat_result
- name: Backup Files
copy: src={{ item.name }} dest={{ item.name }}{{ ansible_date_time.date }}.bak
with_items: "{{ file_vars }}"
remote_src: yes
when: stat_result.stat.exists == True
The problem is the condition
when: stat_result.stat.exists == True
There is no attribute stat_result.stat. Instead, the attribute stat_result.results is a list of the results from the loop. It's possible to create a dictionary of files and their statuses. For example
- set_fact:
files_stats: "{{ dict(my_files|zip(my_stats)) }}"
vars:
my_files: "{{ stat_result.results|json_query('[].item.name') }}"
my_stats: "{{ stat_result.results|json_query('[].stat.exists') }}"
Then simply use this dictionary in the condition
when: files_stats[item.name]
Below is a shorter version which creates the dictionary more efficiently
- set_fact:
files_stats: "{{ dict(stat_result.results|
json_query('[].[item.name, stat.exists]')) }}"
Please try using below worked for me:
---
- name: Copy files
hosts: localhost
become: yes
become_user: root
vars_files:
- files.yml
tasks:
- name: "Checking if config files exists"
stat:
path: "{{ item }}"
with_items: "{{ files }}"
register: stat_result
- name: Ansible
debug:
msg: "{{ stat_result }}"
- name: Backup Files
copy:
src: "{{ item }}"
dest: "{{ item.bak }}"
with_items: "{{ files }}"
when: stat_result == "True"
and files.yml will look like:
---
files:
- /tmp/file1
- /tmp/file2
you can check you playbook syntax using below command:
ansible-playbook copy.yml --syntax-check
Also you do dry run your playbook before actual execution.
ansible-playbook -i localhost copy.yml --check

How do you copy multiple files using remote_src in Ansible?

When I run the command remote_src: true I get the error
ERROR! 'remote_src' is not a valid attribute for a Task
I was wondering if there is a better way to write the code or if this is a bug
Tried to remove the offending line of code, however, the files exist on the remote host so I'm unable to copy the files into the correct location
- hosts: openvpn_server
vars:
file_vars:
- { name: ca }
- { name: server }
tasks:
- name: check if ca.crt and server.crt exists
stat:
path: /tmp/{{ item.name }}.crt
with_items: "{{ file_vars }}"
register: ensure_ca_crt_exists
- name: copying server.crt and ca.crt
become: true
copy: src={{ item.src }} dest={{ item.dest }}
with_items:
- { src: '/tmp/server.crt' , dest: '/etc/openvpn/server.crt' }
- { src: '/tmp/ca.crt' , dest: '/etc/openvpn/ca.crt' }
remote_src: true
when: ensure_ca_crt_exists.results
- name: creating Diffie-Hellman key to use during key exchange
shell: ./easyrsa gen-dh
args:
chdir: ~/EasyRSA-v3.0.6/
- name: Generating HMAC signature to strengthen servers TLS integrity
shell: openvpn --genkey --secret ta.key
- name: copying ta.key and dh.pem to /etc/openvpn
become: true
copy: src={{ item.src }} dest={{ item.dest }}
with_items:
- { src: '/home/dc/EasyRSA-v3.0.6/ta.key' , dest: '/etc/openvpn/ta.key' }
- { src: '/home/dc/EasyRSA-v3.0.6/dh.pem' , dest: '/etc/openvpn/dh.pem' }
I should be able to copy the file from the tmp folder to /etc/openvpn folder
via the remote_src command, apologizes for the badly configured register I'm fairly new to ansible
ERROR! 'remote_src' is not a valid attribute for a Task
Indentation is wrong
- name: copying server.crt and ca.crt
become: true
copy: src={{ item.src }} dest={{ item.dest }}
with_items:
- { src: '/tmp/server.crt' , dest: '/etc/openvpn/server.crt' }
- { src: '/tmp/ca.crt' , dest: '/etc/openvpn/ca.crt' }
remote_src: true
Correct
- name: copying server.crt and ca.crt
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
remote_src: true
loop:
- {src: '/tmp/server.crt', dest: '/etc/openvpn/server.crt'}
- {src: '/tmp/ca.crt', dest: '/etc/openvpn/ca.crt'}
become: true

Problem with creating consul cluster using ansible

I'm trying to create a Consul cluster using Ansible and i'm using this example https://github.com/brianshumate/ansible-consul .i'm using the vagrant file to up 3 Ubuntu machines
the problem is that the task Install unzip package seem to always fail,and it gives this error message:
fatal: [consul1.consul -> localhost]: FAILED! => {"changed": false, "msg": "Could not detect which package manager to use. Try gathering facts or setting the \"use\" option."}
Ansible seem unable to recognize the package manager,even though ansible localhost -m setup | grep mgr shows that the variable ansible_pkg_mgr has the value apt
i'm not sure what could be the source of the problem.i tried upping 3 debian machines and i still have the same problem.
UPDATE:
here's the task file for consul
---
# File: install.yml - package installation tasks for Consul
- name: Install OS packages
package:
name: "{{ item }}"
state: present
with_items: "{{ consul_os_packages }}"
tags: installation
- name: Read package checksum file
local_action:
module: stat
path: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
register: consul_checksum
tags: installation
- name: Download package checksum file
local_action:
module: get_url
url: "{{ consul_checksum_file_url }}"
dest: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
tags: installation
when: not consul_checksum.stat.exists | bool
- name: Read package checksum
local_action:
module: shell
grep "{{ consul_pkg }}" "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS" | awk '{print $1}'
become: no
run_once: true
register: consul_sha256
tags: installation
- name: Check Consul package file
local_action:
module: stat
path: "{{ role_path }}/files/{{ consul_pkg }}"
become: no
run_once: true
register: consul_package
tags: installation
- name: Download Consul package
local_action:
module: get_url
url: "{{ consul_zip_url }}"
dest: "{{ role_path }}/files/{{ consul_pkg }}"
checksum: "sha256:{{ consul_sha256.stdout }}"
timeout: "42"
become: no
run_once: true
tags: installation
when: not consul_package.stat.exists | bool
- name: Update alpine package manager (apk)
local_action:
module: apk
update_cache: yes
run_once: true
when: lookup('file','/etc/alpine-release')
- name: Install unzip package
local_action:
module: package
name: unzip
state: present
run_once: true
when:
- consul_install_dependencies | bool
- name: Unarchive Consul package
local_action:
module: unarchive
src: "{{ role_path }}/files/{{ consul_pkg }}"
dest: "{{ role_path }}/files/"
creates: "{{ role_path }}/files/consul"
become: no
run_once: true
tags: installation
- name: Install Consul
copy:
src: "{{ role_path }}/files/consul"
dest: "{{ consul_bin_path }}/consul"
owner: "{{ consul_user }}"
group: "{{ consul_group }}"
mode: 0755
tags: installation
- name: Daemon reload systemd in case the binaries upgraded
command: systemctl daemon-reload
become: yes
notify: restart consul
when:
- ansible_service_mgr == "systemd"
- consul_install_upgrade
- name: Cleanup
local_action: file path="{{ item }}" state="absent"
become: no
with_fileglob: "{{ role_path }}/files/consul"
run_once: true
tags: installation
The problem is with the Alpine package Manager,somehow it seem to cause an error with Ubuntu,so all what i did is use Apt instead of Apk.
here's the new version of the task file
---
# File: install.yml - package installation tasks for Consul
- name: Install OS packages
package:
name: "{{ item }}"
state: present
with_items: "{{ consul_os_packages }}"
tags: installation
- name: Read package checksum file
local_action:
module: stat
path: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
register: consul_checksum
tags: installation
- name: Download package checksum file
local_action:
module: get_url
url: "{{ consul_checksum_file_url }}"
dest: "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS"
become: no
run_once: true
tags: installation
when: not consul_checksum.stat.exists | bool
- name: Read package checksum
local_action:
module: shell
grep "{{ consul_pkg }}" "{{ role_path }}/files/consul_{{ consul_version }}_SHA256SUMS" | awk '{print $1}'
become: no
run_once: true
register: consul_sha256
tags: installation
- name: Check Consul package file
local_action:
module: stat
path: "{{ role_path }}/files/{{ consul_pkg }}"
become: no
run_once: true
register: consul_package
tags: installation
- name: Download Consul package
local_action:
module: get_url
url: "{{ consul_zip_url }}"
dest: "{{ role_path }}/files/{{ consul_pkg }}"
checksum: "sha256:{{ consul_sha256.stdout }}"
timeout: "42"
become: no
run_once: true
tags: installation
when: not consul_package.stat.exists | bool
- name: Install unzip package
apt:
name: unzip
state: present
run_once: true
when:
- consul_install_dependencies | bool
- name: Unarchive Consul package
local_action:
module: unarchive
src: "{{ role_path }}/files/{{ consul_pkg }}"
dest: "{{ role_path }}/files/"
creates: "{{ role_path }}/files/consul"
become: no
run_once: true
tags: installation
- name: Install Consul
copy:
src: "{{ role_path }}/files/consul"
dest: "{{ consul_bin_path }}/consul"
owner: "{{ consul_user }}"
group: "{{ consul_group }}"
mode: 0755
tags: installation
- name: Daemon reload systemd in case the binaries upgraded
command: systemctl daemon-reload
become: yes
notify: restart consul
when:
- ansible_service_mgr == "systemd"
- consul_install_upgrade
- name: Cleanup
local_action: file path="{{ item }}" state="absent"
become: no
with_fileglob: "{{ role_path }}/files/consul"
run_once: true
tags: installation

Ansible: when condition with_items

I have such a part of a playbook, which works fine:
- name: "Copy solrconfig.xml"
copy:
src: "{{role_path}}/files/{{item.path}}"
dest: "{{solr_jmx_config}}/solrconfig.xml"
with_items:
- path: solrconfig_master.xml
when: inventory_hostname == "{{ solr_master }}"
become: yes
become_user: solr
- name: "Copy solrconfig.xml"
copy:
src: "{{role_path}}/files/{{item.path}}"
dest: "{{solr_jmx_config}}/solrconfig.xml"
with_items:
- path: solrconfig_slave.xml
when: inventory_hostname != "{{ solr_master }}"
become: yes
become_user: solr
However, I would like it to look nicer and do something like that:
- name: "Copy solrconfig.xml"
copy:
src: "{{role_path}}/files/{{item.path}}"
dest: "{{solr_jmx_config}}/solrconfig.xml"
with_items:
- path: solrconfig_master.xml -> when: inventory_hostname == "{{ solr_master }}"
- path: solrconfig_slave.xml -> when: inventory_hostname != "{{ solr_master }}"
become: yes
become_user: solr
How to apply "when" condition for each particular item?
Best regards,
Marek
Why do you need with_items and role_path here? Try this:
- name: "Copy solrconfig.xml"
copy:
src: "{{ 'solrconfig_master.xml' if inventory_hostname == solr_master else 'solrconfig_slave.xml' }}"
dest: "{{solr_jmx_config}}/solrconfig.xml"
become: yes
become_user: solr
with_ is generally used for loops, you don't need it for single element.
When you call tasks inside roles, search path for file modules include <role_path>/files/....

Ansible - How to use register name from with_items

In my current playbook, I have something like the following:
- name: Copy cov-analysis-linux64-8.0.0.tgz
copy: src=/home/devops/chroot/cov-analysis-linux64-8.0.0.tgz dest=/var/tmp/cov-analysis.tgz owner=devops
register: coverity
- name: Copy fortidev-2.02.chroot.tar.bz2
copy: src=/home/devops/chroot/fortidev-2.02.chroot.tar.bz2
dest=/var/tmp/fortidev2.chroot.tar.bz2 owner=devops
register: fortidev2
The list is getting longer and longer and for code readability, I want to use with_items to do it. I've updated it to something like:
- name: copy chroot tarball to the servers
copy: src={{ item.src }} dest={{ item.dest }} owner=devops
register: "{{ item.register }}"
with_items:
- { src: /home/devops/chroot/cov-analysis-linux64-8.0.0.tgz,
dest: /var/tmp/cov-analysis.tgz,
register: coverity
}
- { src: /home/devops/chroot/fortidev-2.02.chroot.tar.bz2,
dest: /var/tmp/fortidev2.chroot.tar.bz2,
register: fortidev2
}
- { src: /home/devops/chroot/fmdev-6.0.tar.xz,
dest: /var/tmp/fmdev6.tar.xz,
register: fmdev6
}
The problem is now when I want to refer to one of the registers in subsequent tasks, it couldn't find the variable. The code to refer it is:
- name: umount fortidev2 /proc|/dev|/tmp|/cov-analysis
command: umount {{ item }}
become: yes
when: fortidev2.changed
with_items:
- /home/devops/fortidev2/proc
- /home/devops/fortidev2/dev
- /home/devops/fortidev2/tmp
ignore_errors: yes
The error is
{"failed": true, "msg": "The conditional check 'fortidev2.changed' failed. The error was: error while evaluating conditional (fortidev2.changed): 'fortidev2' is undefined\n\nThe error appears to have been in '/var/lib/jenkins/jobs/Devops/jobs/update_chroot/workspace/roles/chroot/tasks/main.yml': line 70, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n# unmount /proc and /dev first before deleting the folder\n- name: umount fortidev2 /proc|/dev|/tmp|/cov-analysis\n ^ here\n"}
Try this:
- name: copy chroot tarball to the servers
copy: src={{ item.src }} dest={{ item.dest }} owner=devops
register: tarballs
with_items:
- { src: /home/devops/chroot/cov-analysis-linux64-8.0.0.tgz,
dest: /var/tmp/cov-analysis.tgz,
name: coverity
}
- { src: /home/devops/chroot/fortidev-2.02.chroot.tar.bz2,
dest: /var/tmp/fortidev2.chroot.tar.bz2,
name: fortidev2
}
- { src: /home/devops/chroot/fmdev-6.0.tar.xz,
dest: /var/tmp/fmdev6.tar.xz,
name: fmdev6
}
- name: umount fortidev2 /proc|/dev|/tmp|/cov-analysis
command: umount {{ item }}
become: yes
when: tarballs.results | selectattr('item.name','equalto','fortidev2') | join('',attribute='changed') | bool
with_items:
- /home/devops/fortidev2/proc
- /home/devops/fortidev2/dev
- /home/devops/fortidev2/tmp

Resources