LabHub
学习 学习路径 课程

Ansible 基础

做一个跑两次也安静的 playbook

在 LabHub 中继续学习

目标

将同一个 playbook 运行任意多次,并确保从第二次开始不再发生任何变更;同时用日志和报告证明这一点。

为什么重要

幂等性不是“代码好不好看”的问题,而是自动化能否真正投入使用的前提。只有确信第二次执行是安全的,才能通过 cron 定期运行来纠正漂移,也才能在流水线中途失败后放心重跑。反过来,如果 playbook 每次都会重启服务,人们自然会回避它;没人愿意使用的自动化,等于没有自动化。关键手段包括能识别当前状态的模块、shell 命令的保护条件(creates/changed_when),以及仅在发生变更时运行的 handler。尤其要记住,handler 会集中到 play 结束时才执行——如果 play 在中途失败,handler 可能完全不会运行,从而出现“配置已经改变,但服务仍在使用旧配置”的状态。

步骤

  1. 创建并运行 /root/ans/idem/site.yml,将输出保存到 /root/ans/idem/out/run1.txt。首次运行的 changed 必须不小于 2。
  2. 再次运行同一个 playbook,将输出保存到 /root/ans/idem/out/run2.txt。这次必须是 changed=0
  3. 定义名为 reload app 的 handler,并在处理配置的 task 中通过 notify 调用它。handler 运行时必须创建 /root/ans/idem/artifacts/reload.marker
  4. 第二次运行日志(run2.txt)中不得出现 RUNNING HANDLER,首次运行日志中则必须出现。
  5. 添加一个 command/shell task,并设置 creates 保护条件。该 task 要向 /root/ans/idem/artifacts/stamp.txt 写入一行;即使运行两次,文件中也只能有一行。
  6. 对只做查询的 task 至少使用一次 changed_when,对需要自行判定失败的 task 至少使用一次 failed_when
  7. 使用 --check 运行 playbook,并把输出保存到 /root/ans/idem/out/check.txt。结果必须为 changed=0failed=0
  8. 创建 /root/ans/idem/out/idempotency.json,其中包含四个键:run1_changed(不小于 2)、run2_changed(0)、handler_fired(1 或 true)以及 verdict("idempotent")。

参考

在首次运行中产生变更

创建并运行 /root/ans/idem/site.yml,将输出保存到 /root/ans/idem/out/run1.txt。首次运行的 changed 必须不小于 2。

用几个用于创建目录、文件和配置的 task 就足够了。请把完整执行结果保存到文件。

让第二次运行达到 changed=0

再次运行同一个 playbook,将输出保存到 /root/ans/idem/out/run2.txt。这次必须是 changed=0

再次运行同一个 playbook。如果 changed 不是 0,请从日志中找出是哪一个 task 造成了变更。

定义 handler 并通过 notify 调用

定义名为 reload app 的 handler,并在处理配置的 task 中通过 notify 调用它。handler 运行时必须创建 /root/ans/idem/artifacts/reload.marker

handler 名称必须与 notify 中的字符串完全一致。让 handler 运行后留下标记文件。

让第二次运行不触发 handler

第二次运行日志(run2.txt)中不得出现 RUNNING HANDLER,首次运行日志中则必须出现。

只有 task 状态为 changed 时才会触发 notify。第二次运行日志中不应出现 RUNNING HANDLER。

为 shell 命令添加 creates 保护条件

添加一个 command/shell task,并设置 creates 保护条件。该 task 要向 /root/ans/idem/artifacts/stamp.txt 写入一行;即使运行两次,文件中也只能有一行。

通过 creates 指明命令会创建的文件路径,后续运行就会跳过该命令。日志文件只能保留一行。

自行定义变更与失败判定

对只做查询的 task 至少使用一次 changed_when,对需要自行判定失败的 task 至少使用一次 failed_when

只做查询的命令可设置 changed_when: false;需要自行判断失败的地方则使用 failed_when。

确认检查模式下也无变更

使用 --check 运行 playbook,并把输出保存到 /root/ans/idem/out/check.txt。结果必须为 changed=0failed=0

如果状态已经收敛,--check 运行也应得到 changed=0。不支持检查模式的模块可能会导致失败。

生成幂等性判定报告

创建 /root/ans/idem/out/idempotency.json,其中包含四个键:run1_changed(不小于 2)、run2_changed(0)、handler_fired(1 或 true)以及 verdict("idempotent")。

将两次运行的 changed 数量和 handler 触发次数整理为 JSON,并写入判定字符串。