Check if service exists with Ansible

I have an Ansible playbook for deploying a Java app as an init.d daemon.

Being a beginner in both Ansible and Linux I'm having trouble to conditionally execute tasks on a host based on the host's status.

Namely I have some hosts having the service already present and running where I want to stop it before doing anything else. And then there might be new hosts, which don't have the service yet. So I can't simply use service: name={{service_name}} state=stopped, because this will fail on new hosts.

How I can I achieve this? Here's what I have so far:

 - name: Check if Service Exists shell: "if chkconfig --list | grep -q my_service; then echo true; else echo false; fi;" register: service_exists
# This should only execute on hosts where the service is present - name: Stop Service service: name={{service_name}} state=stopped when: service_exists register: service_stopped
# This too - name: Remove Old App Folder command: rm -rf {{app_target_folder}} when: service_exists
# This should be executed on all hosts, but only after the service has stopped, if it was present - name: Unpack App Archive unarchive: src=../target/{{app_tar_name}} dest=/opt

8 Answers

See the service_facts module, new in Ansible 2.5.

- name: Populate service facts service_facts:
- debug: msg: Docker installed! when: "'docker' in services"
5

Of course I could also just check if the wrapper script exists in /etc/init.d. So this is what I ended up with:

 - name: Check if Service Exists stat: path=/etc/init.d/{{service_name}} register: service_status - name: Stop Service service: name={{service_name}} state=stopped when: service_status.stat.exists register: service_stopped
9

I modified Florian's answer to only use the return code of the service command (this worked on Mint 18.2)

- name: Check if Logstash service exist shell: service logstash status register: logstash_status failed_when: not(logstash_status.rc == 3 or logstash_status.rc == 0)
- name: Check if Logstash service exist service: name: logstash state: stopped when: logstash_status.rc == 0

It would be nice if the "service" module could handle "unrecognized service" errors.

This is my approach, using the service command instead of checking for an init script:

- name: check for apache shell: "service apache2 status" register: _svc_apache failed_when: > _svc_apache.rc != 0 and ("unrecognized service" not in _svc_apache.stderr)
- name: disable apache service: name=apache2 state=stopped enabled=no when: "_svc_apache.rc == 0"
  • check the exit code of "service status" and accept the exit code 0 when the output contains "unrecognized service"
  • if the exit code was 0, that service is installed (stopped or running)

Another approach for systemd (from Jakuje):

- name: Check if cups-browsed service exists command: systemctl cat cups-browsed check_mode: no register: cups_browsed_exists changed_when: False failed_when: cups_browsed_exists.rc not in [0, 1]
- name: Stop cups-browsed service systemd: name: cups-browsed state: stopped when: cups_browsed_exists.rc == 0

This way using only the service module has worked for us:

- name: Disable *service_name* service: name: *service_name* enabled: no state: stopped register: service_command_output failed_when: > service_command_output|failed and 'unrecognized service' not in service_command_output.msg and 'Could not find the requested service' not in service_command_output.msg

Building on @Maciej's answer for RedHat 8, and combining it with the comments made on it.

This is how I managed to stop Celery only if it has already been installed:

- name: Populate service facts service_facts:
- debug: msg: httpd installed! when: ansible_facts.services['httpd.service'] is defined
- name: Stop celery.service service: name: celery.service state: stopped enabled: true when: ansible_facts.services['celery.service'] is defined

You can drop the debug statement--it's there just to confirm that ansible_facts is working.

My few cents. The same approach as above but for kubernetes

Check if kublete service is running

- name: "Obtain state of kublet service" command: systemctl status kubelet.service register: kubelet_status failed_when: kubelet_status.rc > 3

Display debug message if kublet service is not running

- debug: msg: "{{ kubelet_status.stdout }}" when: "'running' not in kubelet_status.stdout"
2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like