Ansible如何对比主机间变量值,避免重复执行相同操作
实现方案
下面给出两种开箱即用的实现方式,不需要额外提前预读变量的预处理步骤:
方案1:基于主机排序匹配首个dir对应主机(最简洁)
核心逻辑是预计算每个dir值对应的第一个出现的主机,任务仅在当前主机为对应dir的首台主机时执行:
--- - name: 仅对首次出现的dir执行复制操作 hosts: plot gather_facts: false tasks: - name: 预计算每个dir对应的首台主机 ansible.builtin.set_fact: dir_first_host: "{{ dir_first_host | default({}) | combine({ hostvars[item].dir: item }) }}" loop: "{{ groups.plot }}" run_once: true - name: 复制文件到对应目录(仅首台dir主机执行) ansible.builtin.copy: src: /path/to/local/source_file dest: "/target/path/{{ dir }}/destination_file" when: inventory_hostname == dir_first_host[dir]
这个逻辑的运行结果完全符合需求:
- 遍历所有plot组主机生成
dir_first_host字典,key为dir值,value为该dir第一个出现的主机名,最终生成的字典为{'graph': 'server1', 'keller': 'server3'} - 只有当前主机名等于自己dir对应的value时才会执行复制,其余同dir主机自动跳过
方案2:基于已处理标记动态判断(适合变量动态变化的场景)
如果后续有dir值动态变更的需求,可以用play级别的列表存储已处理的dir值,每处理一个就追加到列表,后续判断是否已存在:
--- - name: 动态标记已处理dir实现跳过逻辑 hosts: plot gather_facts: false vars: processed_dirs: [] tasks: - name: 复制文件到对应目录 ansible.builtin.copy: src: /path/to/local/source_file dest: "/target/path/{{ dir }}/destination_file" when: dir not in processed_dirs - name: 追加已处理dir到列表 ansible.builtin.set_fact: processed_dirs: "{{ processed_dirs + [dir] }}" when: dir not in processed_dirs run_once: true
这个方案的优势是不需要预计算全量主机的dir,执行过程中动态标记已处理的dir,run_once保证每轮dir判断后全局的processed_dirs只更新一次,不会重复追加。
内容的提问来源于stack exchange,提问作者alexander moro
相关产品推荐
相关产品推荐

