如何让Ansible Playbook终端输出解析inventory的ansible_host Jinja变量
解决Ansible Playbook输出中ansible_host Jinja表达式未解析的问题
核心解决方案:修改Inventory变量定义
不需要为每个主机单独定义ansible_host,只需调整inventory中变量的写法即可解决问题:
修改后的Inventory片段
[all:vars] ansible_connection=network_cli host_domain=wfm.pvt ansible_host={{ inventory_hostname }}.{{ host_domain }} [CEASF] CEASF-RTR
原理说明
当你用单引号包裹{{ inventory_hostname }}.{{ host_domain }}时,Ansible会将其视为字面字符串,不会触发Jinja表达式解析。去掉单引号后,Ansible在加载inventory阶段就会自动解析该表达式,将ansible_host替换为实际的主机地址(如CEASF-RTR.wfm.pvt),此时playbook的输出就会显示解析后的结果:
changed: [CEASF-RTR -> CEASF-RTR.wfm.pvt] => (item=cowfm-tower-core) => {
替代方案:自定义回调插件(无法修改Inventory时使用)
如果因依赖问题不能修改inventory,可以通过自定义回调插件拦截并修改输出内容,主动解析其中的Jinja表达式。
步骤1:创建回调插件文件
在playbook目录下新建callback_plugins/parse_ansible_host_output.py,内容如下:
from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'stdout' CALLBACK_NAME = 'parse_ansible_host' def v2_runner_on_ok(self, result): # 获取主机已解析的变量值 host_vars = result._host.get_vars() parsed_ansible_host = host_vars.get('ansible_host') # 构建解析后的输出前缀 status = 'changed' if result._result.get('changed') else 'ok' host_name = result._host.get_name() item_info = f" => (item={result._result['item']})" if result._task_loop else "" parsed_msg = f"{status}: [{host_name} -> {parsed_ansible_host}]{item_info} => " self._display.display(parsed_msg) # 输出任务结果的详细内容 self._display.display(self._dump_results(result._result)) def v2_runner_on_failed(self, result, ignore_errors=False): # 对失败任务做同样的解析处理 host_vars = result._host.get_vars() parsed_ansible_host = host_vars.get('ansible_host') status = 'failed' host_name = result._host.get_name() item_info = f" => (item={result._result['item']})" if result._task_loop else "" parsed_msg = f"{status}: [{host_name} -> {parsed_ansible_host}]{item_info} => " self._display.display(parsed_msg) super().v2_runner_on_failed(result, ignore_errors)
步骤2:配置使用回调插件
在ansible.cfg中添加以下配置:
[defaults] callback_plugins = ./callback_plugins stdout_callback = parse_ansible_host
或者运行playbook时临时指定:
ansible-playbook -i ce_campus_rtr_inventory_singular your_playbook.yml -e "ansible_callback_plugins=./callback_plugins stdout_callback=parse_ansible_host"
常见疑问解答
为什么verbose模式和debug模块能看到正确值?
- Verbose模式的输出来自连接阶段,此时Ansible已经解析了
ansible_host变量用于建立连接。 - Debug模块直接读取的是Ansible内部已解析的主机变量,而非inventory中的原始字符串。
- Verbose模式的输出来自连接阶段,此时Ansible已经解析了
有没有命令行参数直接实现解析?
- 没有直接的命令行参数可以强制解析inventory中的Jinja表达式并修改输出,最简便的方式还是修改inventory变量定义。
内容的提问来源于stack exchange,提问作者humbleStrength
相关产品推荐
相关产品推荐

