遍历两个JSON并按条件执行任务的Ansible问题及需求实现
解决Ansible 'dict object'无'inventory_hostname'属性错误及节点脚本执行方案
错误原因
该错误是因为你直接迭代字典对象(比如machine.json的条目)时,错误尝试访问仅主机变量才有的inventory_hostname属性——迭代的是字典条目而非主机列表,自然不存在这个属性。
解决方案步骤
1. 加载JSON数据
先用include_vars模块加载machine.json到变量中:
- name: 加载machine.json数据 include_vars: file: machine.json name: machine_data
2. 提取目标节点列表
从加载的数据中提取所有nodename,处理成一维主机列表(适配单个节点或节点数组的情况):
- name: 收集所有需要执行脚本的节点 set_fact: target_nodes: "{{ machine_data | json_query('[*].nodename') | flatten }}"
3. 在目标节点执行脚本
方式一:循环+委托执行
直接迭代节点列表,通过delegate_to指定执行目标,同时校验节点是否在inventory中:
- name: 在目标节点运行cleanup.sh script: cleanup.sh delegate_to: "{{ item }}" loop: "{{ target_nodes }}" when: item in groups['all']
方式二:创建动态主机组
先将目标节点加入动态组,再针对组执行任务,更符合Ansible最佳实践:
- name: 将目标节点添加到动态组 add_host: name: "{{ item }}" groups: target_cleanup_nodes loop: "{{ target_nodes }}" when: item in groups['all'] - name: 对动态组执行清理脚本 hosts: target_cleanup_nodes tasks: - name: 执行cleanup.sh script: cleanup.sh
注意事项
- 确认
machine.json的结构:确保每个条目包含nodename字段,字段值可以是单个字符串或节点数组,flatten会自动处理嵌套列表。 - 校验inventory:确保目标节点(如oda708c1n1、oda708c1n2、oda8m032)已存在于你的inventory文件中,否则
when条件会过滤掉不存在的节点,避免执行错误。
内容的提问来源于stack exchange,提问作者Akash-BLR
相关产品推荐
相关产品推荐

