如何在Ansible Playbooks中定义和使用处理程序

97 阅读3分钟

简而言之,_处理程序_是特殊任务,只有在通过notify 指令触发时才会被执行。处理程序在游戏结束时执行,一旦所有任务都完成。

在Ansible中,处理程序通常用于启动、重新加载、重新启动和停止服务。如果你的playbook涉及到修改配置文件,那么很有可能需要重启服务,以便让修改生效。在这种情况下,你需要为该服务定义一个处理程序,并在需要该服务处理程序的任何任务中包括notify 指令。

本系列的上一节中,你已经看到了如何使用模板将默认的Nginx页面替换成一个自定义的HTML登陆页面。在实践中,在设置Nginx网站服务器时,你很可能会在sites-available 目录中包含新的服务器块文件,创建符号链接,或者改变设置,需要重新加载或重启服务器。

考虑到这种情况,重启Nginx服务的处理程序应该是这样的。

...
  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted     

为了触发这个处理程序,你需要在任何需要重启Nginx服务器的任务中包含一个notify 指令。

以下是使用Ansible内置的替换模块替换Nginx配置文件中的默认文件根。该模块根据regexp 中定义的正则表达式寻找文件中的模式,然后用replace 中定义的内容替换找到的任何匹配内容。然后,该任务向Restart Nginx 处理程序发送通知,以便尽快重启。这意味着,不管你触发多少次重启,只有当所有的任务都已经执行完毕,处理程序开始运行时才会发生。此外,当没有找到匹配的任务时,不会对系统进行任何改变,为此,处理程序不会被触发。

在你的ansible-practice 目录中创建一个名为playbook-12.yml 的新文件。

nano ~/ansible-practice/playbook-12.yml

在新的playbook文件中添加以下几行。

ansible-practice/playbook-12.yml

---
- hosts: all
  become: yes
  vars:
    page_title: My Second Landing Page
    page_description: This is my second landing page description.
    doc_root: /var/www/mypage

  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: latest

    - name: Make sure new doc root exists
      file:
        path: "{{ doc_root }}"
        state: directory
        mode: '0755'

    - name: Apply Page Template
      template:
        src: files/landing-page.html.j2
        dest: "{{ doc_root }}/index.html"

    - name: Replace document root on default Nginx configuration
      replace:
        path: /etc/nginx/sites-available/default
        regexp: '(\s+)root /var/www/html;(\s+.*)?$'
        replace: \g<1>root {{ doc_root }};\g<2>
      notify: Restart Nginx

    - name: Allow all access to tcp port 80
      ufw:
        rule: allow
        port: '80'
        proto: tcp

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

完成后保存并关闭该文件。

在使用处理程序时要记住一件重要的事情,那就是只有当定义notify 触发器的任务导致服务器发生变化时,它们才会被触发。以这个playbook为例,第一次运行replace 任务时,会改变Nginx的配置文件,因此会运行重启。然而,在随后的执行中,由于要替换的字符串不再出现在文件中,该任务将不会引起任何变化,也不会触发处理程序的执行。

如果你运行这个playbook,记得提供-K 选项,因为它需要sudo 权限。

ansible-playbook -i inventory playbook-12.yml -u sammy -K
OutputBECOME password: 

PLAY [all] **********************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [203.0.113.10]

TASK [Install Nginx] ************************************************************************************
ok: [203.0.113.10]

TASK [Make sure new doc root exists] ********************************************************************
changed: [203.0.113.10]

TASK [Apply Page Template] ******************************************************************************
changed: [203.0.113.10]

TASK [Replace document root on default Nginx configuration] *********************************************
changed: [203.0.113.10]

TASK [Allow all access to tcp port 80] ******************************************************************
ok: [203.0.113.10]

RUNNING HANDLER [Restart Nginx] *************************************************************************
changed: [203.0.113.10]

PLAY RECAP **********************************************************************************************
203.0.113.10                : ok=7    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

如果你看一下输出,你会看到 "重启Nginx "处理程序在游戏结束前被执行。如果你现在进入浏览器,访问服务器的IP地址,你会看到以下页面。

Screenshot showing the new landing page after update

在本系列的下一部分,也就是最后一部分,我们将把所有的点连接起来,编写一个自动设置远程Nginx服务器来托管静态HTML网站的游戏手册。