Check if service exists with Ansible

CentosAnsibleAnsible Playbook

Centos Problem Overview


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

Centos Solutions


Solution 1 - Centos

See the service_facts module, new in Ansible 2.5.

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

Solution 2 - Centos

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

Solution 3 - Centos

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

Solution 4 - Centos

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)

Solution 5 - Centos

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

Solution 6 - Centos

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

Solution 7 - Centos

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"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEagleBeakView Question on Stackoverflow
Solution 1 - CentosAidan FeldmanView Answer on Stackoverflow
Solution 2 - CentosEagleBeakView Answer on Stackoverflow
Solution 3 - Centosddrake12View Answer on Stackoverflow
Solution 4 - CentosFlorianView Answer on Stackoverflow
Solution 5 - CentossourcejediView Answer on Stackoverflow
Solution 6 - CentosPaul DubucView Answer on Stackoverflow
Solution 7 - CentosLukasz DynowskiView Answer on Stackoverflow