Ansible传递playbook目录名到导入剧本时变量未生效如何解决?
问题原因
Ansible 中 import_playbook 属于静态导入,会在 playbook 整体解析阶段就完成处理,早于任何 task 的执行时间。你在第一个 play 里用 set_fact 定义的 myfolder 是任务运行阶段才生成的变量,解析导入的 playbook 时这个变量还不存在,所以会出现变量未定义的报错。
而你能在导入的 playbook 里 debug 出正确的 bpm_folder 值,是因为 debug 任务执行时,第一个 play 的 set_fact 已经跑完了,变量已经赋值,但被导入 playbook 顶层的 vars_file 加载时机远早于任务执行阶段,所以加载时还是拿不到值。
修复方案
你不需要额外通过 set_fact 定义中间变量,playbook_dir 是 Ansible 预定义的全局变量,在解析阶段就已经可用,直接在导入 playbook 的 vars 中计算即可:
--- # 可直接删除之前的pre deploy play,完全不需要 - name: start deploy import_playbook: '../Common/deploy.yml' vars: bpm_folder: "{{ playbook_dir | basename }}"
这个写法和你写死 appfolder 的效果完全一致,解析阶段就能拿到正确的文件夹名,vars_file 加载时就能正常识别变量。
需先通过任务逻辑计算变量的场景
如果你的文件夹名不是直接取 playbook_dir 的 basename,需要先经过复杂的任务逻辑计算得到,那么可以把静态的 import_playbook 换成动态的 include_playbook,include_playbook 是在运行阶段执行到对应位置时才加载,此时之前的 set_fact 已经执行完毕,变量已经生成:
--- - name: pre deploy hosts: myhosts gather_facts: no tasks: - set_fact: myfolder: "{{ playbook_dir | basename }}" # 把导入动作放到当前play的任务里,用include_playbook动态加载 - name: include deploy play ansible.builtin.include_playbook: '../Common/deploy.yml' vars: bpm_folder: "{{ myfolder }}"
内容的提问来源于stack exchange,提问作者Artyum
相关产品推荐
相关产品推荐

