You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在任意主机存在openvz事实时让所有主机执行Ansible任务

你原有代码的问题是循环执行set_fact时没有做列表追加,每次执行都会直接覆盖virt_list的值,且没有加run_once限制导致每个受管主机都单独执行了一次收集,最终每个主机只能拿到自己对应的条目,无法完成全量列表的汇总。

最简实现方案(无需额外收集列表)

直接在目标任务的when条件中用Jinja2表达式做判断,无需单独设置fact,一行即可实现需求:

- name: 存在OpenVZ主机时所有节点执行的指定任务
  # 此处替换为你实际要执行的任务动作
  yum:
    name: fuse
    state: present
  when: groups['all'] | map('extract', hostvars, 'ansible_virtualization_type') | select('equalto', 'openvz') | list | length > 0

表达式逻辑说明:

  • 先提取全量主机组中所有节点的ansible_virtualization_type属性
  • 筛选出值为openvz的结果
  • 转换为列表后判断长度,大于0则说明存在符合条件的主机

如果你确实需要保留OpenVZ主机列表供后续多任务复用

可以用以下修正后的写法收集列表:

- name: 收集所有OpenVZ虚拟化的主机列表
  set_fact:
    virt_list: "{{ virt_list | default([]) + [{'host': item, 'type': 'openvz'}] }}"
  when: hostvars[item].ansible_virtualization_type == "openvz"
  with_items: "{{ groups['all'] }}"
  run_once: true
  delegate_to: localhost
  delegate_facts: true

新增的两个关键配置作用:

  • run_once: true:让收集任务仅在第一个主机上执行一次,避免所有受管节点重复执行
  • virt_list | default([]) + [xxx]:初始化空列表并做元素追加,不会每次循环覆盖原有值

后续其他任务可以直接用以下条件判断:

when: hostvars['localhost'].virt_list | default([]) | length > 0

内容的提问来源于stack exchange,提问作者Aleritty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 05:00:03