Ansible Playbook 根据任务状态执行特定任务

Ansible Playbook 根据任务状态执行特定任务

使用 handlers

先举个例子,用 Ansible 去修改 ssh 服务的配置文件并重启服务,下边这个 Playbook 可以实现这个功能:

- name: set sshd conf
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    backrefs: true
    regexp: "^#?\\s*PermitRootLogin"
    line: PermitRootLogin yes
- name: restart ssh
  ansible.builtin.systemd:
    name: sshd
    state: restarted
    enabled: true

在这个 Playbook 中,每次执行都会重启 ssh 服务,虽然能够实现结果,但是不满足 Ansible 的幂等性规则。

为了解决这个问题,Ansible 可以做到在某些任务处于 changed 状态时执行特定任务,Ansible 通过一下三个字段实现这个功能:

  • notify:设置哪些任务处于 changed 时触发特定任务
  • handlers:设置可由 notify 触发的任务
  • listen:用于监听 notify

下边是一个优化后的 Playbook:

- name: set sshd conf
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    backrefs: true
    regexp: "^#?\\s*PermitRootLogin"
    line: PermitRootLogin yes
  notify: restart sshd
handlers:
- name: restart ssh
  ansible.builtin.systemd:
    name: sshd
    state: restarted
    enabled: true
  listen: restart sshd

这里可以看到:

  • 设置 ssh 配置文件的 Play 有一个 notify 内容为 restart sshd,表示有一个 restart sshd 的通知
  • handlers 下有一个重启 sshd 服务的 Play
  • 有一个 listen 内容为 restart sshd,这个和前边 notify 对应

这三个字段实现的功能就是当发生 ssh 配置文件修改时,重启 sshd 服务,如果没有发生配置文件修改,则重启 sshd 服务的 Play 不会执行。

[root@study ansible]# ansible-playbook /tmp/test.yml

PLAY [test handlers] **********************************************************************************************************************************************

TASK [set sshd conf] **********************************************************************************************************************************************
ok: [servera]

TASK [restart ssh] ************************************************************************************************************************************************
changed: [servera]

PLAY RECAP ********************************************************************************************************************************************************
servera                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@study ansible]# ansible-playbook test.yml

PLAY [test handlers] **********************************************************************************************************************************************

TASK [set sshd conf] **********************************************************************************************************************************************
ok: [servera]

PLAY RECAP ********************************************************************************************************************************************************
servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

如果 notify 要触发的 Play 只有一个,那么 listen 可以省略,只需要 notify 的内容和 handlers 的 Play 的 name 对应上。

如果 notifyloop 结合使用,发生 changed 时,会将所有可触发的 handlers Play 执行一遍。

https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-and-loops

多个任务触发同一个 handlers Play 时,Play 只会执行一次。

handlers 中含有静态导入或动态导入时,静态导入支持单独通知被导入的 Play,动态导入被通知时导入的任务会被全部执行。

https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#includes-and-imports-in-handlers

设置 handlers 任务触发时间

默认情况下,handlers 的 Play 会在所有 tasks 都执行完后才去执行,通过 meta: flush_handlers 可以让 handlers 的 Play 提前执行:

- name: set sshd conf
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    backrefs: true
    regexp: "^#?\\s*PermitRootLogin"
    line: PermitRootLogin yes
  notify: restart sshd
- name: Flush handlers
  meta: flush_handlers
- name: debug
  ansible.builtin.debug:
    msg: "Hello World!"
handlers:
- name: restart ssh
  ansible.builtin.systemd:
    name: sshd
    state: restarted
    enabled: true
  listen: restart sshd

在这个 Playbook 中,重启服务的 Play 会在 debug 任务之前执行。

[root@study ansible]# ansible-playbook test.yml

PLAY [test handlers] **********************************************************************************************************************************************

TASK [set sshd conf] **********************************************************************************************************************************************
changed: [servera]

TASK [Flush handlers] *********************************************************************************************************************************************

RUNNING HANDLER [restart ssh] *************************************************************************************************************************************
changed: [servera]

TASK [debug] ******************************************************************************************************************************************************
ok: [servera] => {
    "msg": "Hello World!"
}

PLAY RECAP ********************************************************************************************************************************************************
servera                    : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Ansible Playbook 根据任务状态执行特定任务
https://www.linuxstudynotes.com/2025/07/13/ansible/ansible-playbook-%e6%a0%b9%e6%8d%ae%e4%bb%bb%e5%8a%a1%e7%8a%b6%e6%80%81%e6%89%a7%e8%a1%8c%e7%89%b9%e5%ae%9a%e4%bb%bb%e5%8a%a1/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇