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

如何用Ansible过滤器按指定条件与默认值生成目标主机列表?

解决方案:用Jinja过滤器优雅筛选符合条件的Ansible主机列表

可以通过组合Jinja过滤器链实现需求,完全替代冗长的循环写法,直接生成符合以下两个条件的主机列表:

  1. 属于cdsre组
  2. 要么未定义foo属性,要么foo属性值为baz

核心过滤器写法

some_servers: "{{ groups['cdsre'] | map('extract', hostvars) | selectattr('foo', 'default', 'baz') | selectattr('foo', '==', 'baz') | map(attribute='inventory_hostname') | list }}"

过滤器逻辑说明

  • groups['cdsre']: 获取cdsre组下的所有主机名
  • map('extract', hostvars): 将主机名转换为对应的主机变量对象
  • selectattr('foo', 'default', 'baz'): 对每个主机变量,如果foo未定义,就默认赋值为baz;已定义的则保留原值
  • selectattr('foo', '==', 'baz'): 筛选出foo值为baz的主机(包含刚才被默认赋值的未定义foo的主机)
  • map(attribute='inventory_hostname'): 提取符合条件主机的inventory_hostname字段
  • list: 将结果转换为列表

完整Playbook示例

---
- hosts: localhost
  gather_facts: false

  tasks:
    - set_fact:
        # 用过滤器链实现的优雅写法
        some_servers: "{{ groups['cdsre'] | map('extract', hostvars) | selectattr('foo', 'default', 'baz') | selectattr('foo', '==', 'baz') | map(attribute='inventory_hostname') | list }}"
        # 原有的仅匹配已定义foo=baz的写法
        foo_matched_servers: "{{ groups['cdsre'] | map('extract', hostvars) | selectattr('foo', 'defined') | selectattr('foo', '==', 'baz') | map(attribute='inventory_hostname') | list}}"
    - debug:
        var: some_servers
    - debug:
        var: foo_matched_servers

验证输出

执行后,some_servers的输出会和你原来循环写法的结果完全一致:

"some_servers": [
    "ovh-vm1",
    "ovh-vm2",
    "ovh-vm3",
    "ovh-vm6",
    "ovh-vm7",
    "oracle-vm4",
    "oracle-vm5"
]

备选写法(用自定义筛选条件)

如果需要更直观表达“或”逻辑,也可以用select结合lambda表达式:

some_servers: "{{ groups['cdsre'] | map('extract', hostvars) | select(item => item.foo is not defined or item.foo == 'baz') | map(attribute='inventory_hostname') | list }}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:40:47