Ansible sshd 配置

知识点:notify、handlers

---
- name: modify sshd_config
  hosts: new
  gather_facts: false
  tasks:
    # 1. 备份/etc/ssh/sshd_config文件
    - name: backup sshd config
      shell: 
        /usr/bin/cp -f {{path}} {{path}}.bak
      vars: 
        - path: /etc/ssh/sshd_config

    # 2. 设置PermitRootLogin no
    - name: disable root login
      lineinfile: 
        path: "/etc/ssh/sshd_config"
        line: "PermitRootLogin no"
        insertafter: "^#PermitRootLogin"
        regexp: "^PermitRootLogin"
      notify: "restart sshd"

    # 3. 设置PasswordAuthentication no
    - name: disable password auth
      lineinfile: 
        path: "/etc/ssh/sshd_config"
        line: "PasswordAuthentication no"
        regexp: "^PasswordAuthentication yes"
      notify: "restart sshd"

  handlers: 
    - name: "restart sshd"
      service: 
        name: sshd
        state: restarted

这里使用了shell模块中的creates参数,它表示如果其指定的文件/tmp/only_once.txt存在,则不执行shell命令,只有该文件不存在时才执行。这就是保证幂等性的一种体现:既然不能保证多次执行shell命令的结果不变,那就保证只执行一次。

Ansible提供了notify指令和handlers功能。如果在某个task中定义了notify指令,当Ansible在监控到该任务changed=1时,会触发该notify指令所定义的handler,然后去执行handler(不是触发后立即执行,稍后会解释)。所谓handler,其实就是task,无论在写法上还是作用上它和task都没有区别,唯一的区别在于handler是被触发而被动执行的,不像普通task一样会按流程正常执行。

唯一需要注意的是,notify和handlers中任务的名称必须一致。比如notify: "restart nginx",那么handlers中必须得有一个任务设置了name: restart nginx

此外,在上面的示例中,两个lineinfile任务都设置了相同的notify,但Ansible不会多次去重启sshd,而是在最后重启一次。实际上,Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。