Restart service when service file changes when using Ansible
Asked Answered
A

3

18

I am creating a systemd service using template module

---
- name: Systemd service
  template:
    src: sonar.unit.j2
    dest: /etc/systemd/system/sonarqube.service
  when: "ansible_service_mgr == 'systemd'" 

The contents of the sonarqube.service can change of course. On change I want to restart the service. How can I do this?

Auctorial answered 20/8, 2019 at 10:36 Comment(0)
D
43

There are two solutions.

Register + When changed

You can register template module output (with its status change),

register: service_conf

and then use when clause.

when: service_conf.changed

For example:

---
- name: Systemd service
  template:
    src: sonar.unit.j2
    dest: /etc/systemd/system/sonarqube.service
  when: "ansible_service_mgr == 'systemd'" 
  register: service_conf

- name: restart service
  service:
    name: sonarqube
    state: restarted
  when: service_conf.changed

Handler + Notify

You define your restart service task as handler. And then in your template task you notify the handler.

tasks:
  - name: Add Sonarqube to Systemd service
    template:
      src: sonar.unit.j2
      dest: /etc/systemd/system/sonarqube.service
    when: "ansible_service_mgr == 'systemd'"
    notify: Restart Sonarqube
  - …

handlers:
  - name: Restart Sonarqube
    service:
      name: sonarqube
      state: restarted

More info can be found in Ansible Doc.

Difference between those 2?

In the first case, the service will restart directly. In the case of the handler the restart will happen at the end of the play.

Another difference will be, if you have several tasks changes that need to restart of your service, you simply add the notify to all of them.

  • The handler will run if any of those task get a changed status. With the first solution, you will have to register several return. And it will generate a longer when clause_1 or clause_2 or
  • The handler will run only once even if notified several times.
Danelle answered 20/8, 2019 at 10:54 Comment(3)
Indeed with register + when changed. But it could also be with a notify + an handler.Scarify
Better use a handler: docs.ansible.com/ansible/latest/user_guide/…Changeup
@dgw, it depends the use-case. Most of the time you right. But sometimes you need that the service restart directly because you need it working as dependency of the following tasks. That's the reason I proposed an update of the answer of lehenric, to have a complete answer covering both use-case (in place of adding another one, and having the 2 valid solutions spitted in 2 answers).Scarify
C
5

This calls for a handler

---
 - name: Testplaybook
   hosts: all
   handlers:
     - name: restart_service
       service:
         name: <servicename>
         state: restarted
   tasks:
     - template:
         src: ...
         dest: ...
       notify:
         - restart_service

The handler will automatically get notified by the module when something changed. See the documentatation for further information on handlers.

Changeup answered 20/8, 2019 at 11:0 Comment(0)
V
2

Since you are using systemd, you will also need to execute daemon-reload because you updated the service file.

The task just templates the service file and notifies a handler:

- name: Systemd service
  template:
    src: sonar.unit.j2
    dest: /etc/systemd/system/sonarqube.service
  when: "ansible_service_mgr == 'systemd'" 
  notify: restart sonarqube systemd

Based on the presence of your specific when clause above, I'm assuming you might want to specify separate handlers in the case that systemd is not in use. The handler for the systemd case would look like the following:

- name: restart sonarqube systemd
  systemd:
    name: sonarqube
    state: restarted
    daemon_reload: yes
Village answered 15/10, 2019 at 20:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.