使用ansible_host调用hostvars值时循环列表失败问题求助
Ansible循环中'ansible_host'未定义错误的解决方法
问题场景
基于inventory中主机的environment变量生成NFS挂载路径时,前两个debug任务能正确显示变量值,但遍历nfs_mounts的循环任务报错'ansible_host' is undefined,导致挂载任务无法执行。
相关文件
Inventory文件
[Hosts] host1 environment=dev hots2 environment=test
原Playbook代码(deploy.yml)
--- - name: Mount issue hosts: all gather_facts: false vars: nfs_hostname: server1 nfs_mounts: - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1", dest: /mnt/drive1 } - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2", dest: /mnt/drive2 } tasks: - name: display environments debug: var: hostvars[ansible_host].environment - name: display mounts debug: var: nfs_mounts - name: display each mount debug: var: item with_items: - "{{ nfs_mounts }}" - name: mount mount: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - "{{ nfs_mounts }}"
执行错误信息
TASK [display each mount] ************************************************************************************************** fatal: [host1]: FAILED! => {"msg": "[{'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1', 'dest': '/mnt/drive1'}, {'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2', 'dest': '/mnt/drive2'}]: 'ansible_host' is undefined"} fatal: [hots2]: FAILED! => {"msg": "[{'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1', 'dest': '/mnt/drive1'}, {'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2', 'dest': '/mnt/drive2'}]: 'ansible_host' is undefined"}
问题原因
在Play的vars块中定义nfs_mounts时,变量内的模板语法{{ hostvars[ansible_host].environment }}虽在单个debug任务中能被正确渲染,但通过with_items引用变量时,Ansible会重新解析变量的原始定义,此时循环上下文无法获取ansible_host变量,导致模板渲染失败。
本质是Play级别的vars在加载阶段解析,任务级别的循环引用触发二次解析时,主机相关变量的作用域丢失。
解决方案
将nfs_mounts的定义从Play的vars块移到set_fact任务中,让每个主机在执行任务时动态生成符合自身环境的挂载配置,确保变量被正确渲染且在后续任务中保持正确状态。
修改后的Playbook代码:
--- - name: Mount issue hosts: all gather_facts: false vars: nfs_hostname: server1 tasks: - name: display environments debug: var: hostvars[ansible_host].environment - name: Define NFS mounts for current host set_fact: nfs_mounts: - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1", dest: /mnt/drive1 } - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2", dest: /mnt/drive2 } - name: display mounts debug: var: nfs_mounts - name: display each mount debug: var: item with_items: "{{ nfs_mounts }}" - name: mount mount: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: "{{ nfs_mounts }}"
补充优化
可以简化变量引用逻辑,直接使用当前主机上下文的environment变量(无需通过hostvars索引):
- name: Define NFS mounts for current host set_fact: nfs_mounts: - { src: "/mnt/nas/{{ environment }}/drive1", dest: /mnt/drive1 } - { src: "/mnt/nas/{{ environment }}/drive2", dest: /mnt/drive2 }
修改后,循环任务就能正确获取已渲染的挂载配置,顺利执行挂载操作。
内容的提问来源于stack exchange,提问作者highbury
相关产品推荐
相关产品推荐

