Ansible如何遵循最佳实践仅对失败主机重跑playbook
符合Ansible最佳实践的失败主机重跑方案
你提出的动态生成failed_hosts组的思路方向正确,但Ansible本身提供了更原生、维护成本更低的实现方式,不需要额外开发脚本维护清单,以下是按优先级排序的落地方案:
方案1:使用内置retry文件+limit参数(官方首推,零额外改造)
Ansible默认在每次playbook执行结束后,会自动在控制端生成一份失败主机列表文件,完全匹配「以最终执行结果判定失败主机」的需求,不需要修改原有playbook或静态inventory:
- 确认你的ansible配置(默认路径
/etc/ansible/ansible.cfg或项目目录下的ansible.cfg)没有关闭retry文件生成:[defaults] retry_files_enabled = True retry_files_save_path = ~/.ansible-retry # 默认路径,可自定义 - 第一次全量执行playbook后,对应目录下会生成和playbook同名的
.retry文件,里面逐行记录了所有执行失败的主机名 - 重跑时直接指定limit参数加载该文件即可,仅会对文件内记录的失败主机执行任务:
ansible-playbook your_original_playbook.yml --limit @~/.ansible-retry/your_original_playbook.retry
该方案的失败判定逻辑默认覆盖所有未跑完整个playbook、或最后一个任务执行失败的主机,和你的需求完全匹配;如果第一次执行时加了--no-retry或--flush-cache参数,不会生成retry文件,可使用下面的方案。
方案2:动态生成内存级failed_hosts组(适配你的初始思路)
如果你需要显式持有失败主机列表,用于后续多步关联操作,可以通过内置模块动态生成主机组,不需要修改静态inventory文件:
- 在原有playbook的最后一个业务任务上注册执行结果:
- name: 原有的最后一个业务任务 ansible.builtin.shell: your_business_command # 替换成你实际的最后一个任务内容 register: final_task_result # 如果需要即使该任务失败也继续执行后续分组逻辑,可添加 ignore_errors: true - 在该任务后追加一个分组任务,将最后一个任务执行失败的主机动态加入内存中的
failed_hosts组:- name: 标记最后一个任务执行失败的主机 ansible.builtin.add_host: name: "{{ inventory_hostname }}" groups: failed_hosts when: final_task_result is failed - 后续重跑时,既可以在同一个playbook内直接写针对
hosts: failed_hosts的重跑任务段,也可以把失败主机列表落地成本地文件供单独的重跑playbook调用,整个过程不会改动你原有的静态inventory清单。
重跑注意事项
- 正式重跑前建议先加
--check参数做dry run,确认目标主机范围符合预期,避免误触发全量执行 - 如果失败原因不涉及前置依赖任务,可搭配
--start-at-task "任务名称"参数从指定位置开始执行,减少重复执行开销 - 如果需要严格以「最后一个任务的执行结果」为唯一判定标准(忽略前面任务的失败影响),请使用方案2的
register+when逻辑做精准判定,不要直接依赖默认retry文件的结果,避免前面任务中途失败导致主机被误计入重跑范围
内容的提问来源于stack exchange,提问作者antwerp
相关产品推荐
相关产品推荐

