-2

I am using Ansible to get a service status on my machines.

Unfortunately I get a fatal error that I am not so sure on how to fix. The code is working but this fatal error is really bothering me.

Code:

- name: Edit application.properties
  hosts: trainingShuttlesBJ
  # gather_facts: true

  tasks:

    - name: Read service name from config.yml
      include_vars:
        file: config.yml
        name: config_vars

    - name: Get service status
      command: systemctl is-active {{ config_vars.service_to_manage }}
      register: service_status_before
      changed_when: false
      ignore_errors: true

    - name: Debug service status
      debug:
        var: service_status_before.stdout
        verbosity: 2

    - name: Start service if not active
      systemd:
        name: "{{ config_vars.service_to_manage }}"
        state: started
      when: service_status_before.stdout != "active"

    - name: Get service status after starting
      command: systemctl is-active {{ config_vars.service_to_manage }}
      register: service_status_after
      changed_when: false
      ignore_errors: true

    - name: Display success message if service started
      ansible.builtin.debug:
        msg: "Table is ready for production. All steps succeeded successfully."
      when: service_status_after.stdout == "active"

Error message:

TASK [Get service status] ****************************************************************************
fatal: [10.6.20.150]: FAILED! => {"changed": false, "cmd": ["systemctl", "is-active", "dealer-tool"], "delta": "0:00:00.011135", "end": "2023-08-31 10:07:33.137622", "msg": "non-zero return code", "rc": 3, "start": "2023-08-31 10:07:33.126487", "stderr": "", "stderr_lines": [], "stdout": "inactive", "stdout_lines": ["inactive"]}
...ignoring
U880D
  • 8,601
  • 6
  • 24
  • 40
  • 2
    What is interpreted as a fatal error is `rc: 3` and absolutely not whatever content in `stdout`. The `command` module (as the `shell` one) treats any return code different from 0 as an error by default. – Zeitounator Aug 31 '23 at 20:30

2 Answers2

1

The code is working but this fatal error is really bothering me.

Besides of the incorrect approach of using the command module with command: systemctl is-active to get a service_fact, the service status, according the documentation of systemctl Exit status it will return an

3   "program is not running"    unit is not active

if the unit is not running or active. Therefore, and in such case, additionally Defining failure would be necessary

      register: status
      changed_when: false
      failed_when: status.rc > 3

Further Reading


However, to simplify and reduce complexity, as well to avoid implementing functionallity which is already there out-of-box, it is recommended to gather service_facts like in Ansible: How to get disabled but running services? or How to pass variable from Ansible service_facts?, or many more referenced below ...

Further Documentation and Q&A

U880D
  • 8,601
  • 6
  • 24
  • 40
1

Provided you always pass in config_vars.service_to_manage the name of a service which is installed on the target server, your entire playbook can be shortened to:

- hosts: trainingShuttlesBJ

  tasks:

    - name: Start service if it's not
      systemd:
        name: "{{ config_vars.service_to_manage }}"
        state: started

This will report "changed" if it was started and "ok" if it was already up.

As reported in @U880D's answer, if you really want to add a status check after start (to get a potential start error), you could gather/refresh service_facts and verify in the returned dict what the actual state is.

Note however that this type of check (as your actual implementation) is not bullet proof since this can report the service is running while the service is starting even if it fails on an startup error a few seconds later.

In that case, it is much more reliable to use (as a non exhaustive example) the wait_for module to check for an open port, a line in a log, a successful connection.... before reporting to your user that the service is correctly running or not and ending the playbook.

Gathering service_facts could also be handy to check that the service name provided in your variable actually exists on the target server before trying to interact with it (and receive errors).

Zeitounator
  • 38,476
  • 7
  • 53
  • 66