12

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?

onknows
  • 6,151
  • 12
  • 65
  • 109

3 Answers3

34

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.
xenlo
  • 761
  • 1
  • 7
  • 21
dubioushencho
  • 466
  • 4
  • 7
  • Indeed with `register` + `when` `changed`. But it could also be with a `notify` + an handler. – xenlo Aug 20 '19 at 11:00
  • Better use a handler: https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#handlers-running-operations-on-change – dgw Aug 20 '19 at 11:01
  • 5
    @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). – xenlo Aug 20 '19 at 15:52
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.

dgw
  • 13,418
  • 11
  • 56
  • 54
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
tholcomb99
  • 21
  • 2