如何让Ansible在主剧本启动后重新评估导入的playbook内容?
首先明确:无法通过在import_playbook之间插入任务的方式让Ansible重新评估playbook_b.yaml。
原因很直接:Ansible在启动阶段会一次性完成所有import_*系列指令的解析与预加载——包括import_playbook。也就是说,当你运行main.yaml时,Ansible会立刻读取playbook_a.yaml和playbook_b.yaml的全部内容并加载到内存,后续哪怕playbook_a修改了磁盘上的playbook_b.yaml文件,内存里预加载的旧版本不会被替换,自然不会生效。
要实现你想要的“在单play内完成修改+执行修改后内容”的需求,可以用以下两种替代方案:
方案1:将Playbook拆分为任务文件,改用include_tasks运行时加载
把playbook_a.yaml和playbook_b.yaml从完整的Playbook结构(包含hosts、tasks等顶层字段)改成纯任务列表,然后在main.yaml的单play中按顺序加载执行:
示例代码
main.yaml
- name: 单play完成全流程 hosts: 你的目标主机组 tasks: # 先执行playbook_a的任务(包含修改playbook_b的操作) - name: 加载并执行playbook_a的任务 import_tasks: playbook_a.yaml # 用include_tasks加载修改后的playbook_b(运行时读取磁盘最新内容) - name: 加载并执行修改后的playbook_b任务 include_tasks: playbook_b.yaml
playbook_a.yaml(纯任务列表)
- name: 调用bash脚本修改playbook_b.yaml ansible.builtin.shell: ./modify_playbook_b.sh
playbook_b.yaml(纯任务列表)
- name: 执行修改后的任务示例 debug: msg: "这是修改后的任务内容"
include_tasks是运行时加载的指令,会在执行到该任务时才去读取磁盘上的文件内容,所以能获取到playbook_a修改后的最新版本。
方案2:在任务中直接调用ansible-playbook执行修改后的文件
如果playbook_b.yaml必须保持完整的Playbook结构(比如需要独立指定hosts、vars等),可以在main.yaml的单play中,先执行playbook_a的修改操作,再通过command或shell模块直接调用ansible-playbook命令运行修改后的文件:
示例代码
main.yaml
- name: 单play完成全流程 hosts: localhost tasks: - name: 执行playbook_a的修改操作 import_tasks: playbook_a.yaml - name: 运行修改后的playbook_b ansible.builtin.command: ansible-playbook playbook_b.yaml -i 你的inventory文件路径 register: playbook_b_result - name: 打印playbook_b的执行输出 debug: var: playbook_b_result.stdout_lines
这种方式相当于在当前Play的任务中触发一次独立的Ansible运行,会重新读取磁盘上的playbook_b.yaml最新内容,自然能生效。需要注意的是,要确保调用ansible-playbook时的环境(比如inventory路径、环境变量)和当前Play的运行环境一致。
内容的提问来源于stack exchange,提问作者0utlawActual

