使用 Ansible 时服务文件更改时重启服务

onk*_*ows 8 ansible ansible-template

我正在使用template模块创建一个 systemd 服务

---
- name: Systemd service
  template:
    src: sonar.unit.j2
    dest: /etc/systemd/system/sonarqube.service
  when: "ansible_service_mgr == 'systemd'" 
Run Code Online (Sandbox Code Playgroud)

sonarqube.service 的内容当然可以改变。更改时我想重新启动服务。我怎样才能做到这一点?

小智 19

有两种解决方案。

注册 + 更改时

您可以注册template模块输出(随着其状态变化),

register: service_conf
Run Code Online (Sandbox Code Playgroud)

然后使用when子句。

when: service_conf.changed
Run Code Online (Sandbox Code Playgroud)

例如:

---
- 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
Run Code Online (Sandbox Code Playgroud)

处理程序 + 通知

您将重新启动服务任务定义为处理程序。然后在你的template任务中你notify是处理程序。

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
Run Code Online (Sandbox Code Playgroud)

更多信息可以在 Ansible Doc 中找到。

那2个的区别?

第一种情况,服务会直接重启。在处理程序的情况下,重新启动将在播放结束时发生。

另一个区别是,如果您有几个需要重新启动服务的任务更改,您只需将notify它们添加到所有任务中。

  • 如果这些任务中的任何一个获得更改的状态,则处理程序将运行。使用第一个解决方案,您将不得不注册多个退货。并且它会生成更长的when子句or_1子句_2 or……
  • 即使多次通知,处理程序也只会运行一次。

  • @dgw,这取决于用例。大多数时候你是对的。但有时您需要直接重新启动服务,因为您需要它作为以下任务的依赖项工作。这就是我提议更新 lehenric 答案的原因,以获得涵盖两个用例的完整答案(而不是添加另一个用例,并将 2 个有效的解决方案分成 2 个答案)。 (2认同)

dgw*_*dgw 5

这需要一个处理程序

---
 - name: Testplaybook
   hosts: all
   handlers:
     - name: restart_service
       service:
         name: <servicename>
         state: restarted
   tasks:
     - template:
         src: ...
         dest: ...
       notify:
         - restart_service
Run Code Online (Sandbox Code Playgroud)

当某些事情发生变化时,处理程序将自动得到模块的通知。有关处理程序的更多信息,请参阅文档。