如何在SaltStack中基于Pillar构建过滤后的主机名列表
当然可以!在SaltStack里实现这个需求其实挺灵活的,我给你几种常用的方案,你可以根据自己的场景来选:
方法1:用Jinja2列表推导式直接过滤(最常用)
首先假设你的Pillar数据结构大概是这样的(比如存在pillar/hosts.sls里):
web_servers: - hostname: web01 include_me: True - hostname: web02 include_me: False - hostname: web03 include_me: True
你可以在状态文件里用Jinja2的列表推导式快速过滤出符合条件的主机名列表,然后把这个变量传给配置模板:
# states/rules_config.sls {% set filtered_hosts = [host['hostname'] for host in pillar.get('web_servers', []) if host.get('include_me', False)] %} # 这里是配置规则的状态 configure_access_rules: file.managed: - name: /etc/access_rules.conf - source: salt://templates/access_rules.conf.j2 - template: jinja - context: target_hosts: {{ filtered_hosts }}
这样target_hosts就是只包含include_me: True的主机名列表,直接可以在模板里使用。
方法2:自定义Pillar模块(适合复用复杂过滤逻辑)
如果你的过滤逻辑比较复杂,或者需要在多个状态/模板里复用这个过滤后的列表,推荐写一个自定义的Pillar模块:
- 在Salt的
_pillar目录下创建一个模块文件,比如filtered_hosts.py:
def filtered_hosts(): # 从Pillar中获取原始主机数据 web_servers = __pillar__.get('web_servers', []) # 过滤出include_me为True的主机名 filtered_list = [host['hostname'] for host in web_servers if host.get('include_me', False)] # 返回过滤后的结果,会自动合并到Pillar数据中 return {'filtered_web_hosts': filtered_list}
- 确保Salt master能加载这个模块,之后你就可以在任何状态或模板里直接引用
pillar.filtered_web_hosts来获取过滤后的列表了,比如:
# 在SLS里直接使用 use_filtered_hosts: cmd.run: - name: echo "{{ pillar.filtered_web_hosts }}" >> /tmp/hosts.txt
方法3:直接在配置模板内过滤
如果你的需求只是在生成配置文件时用到过滤后的列表,也可以直接在Jinja模板里做过滤,省去在SLS里定义变量的步骤:
# templates/access_rules.conf.j2 # 只生成include_me为True的主机规则 {% for host in pillar.get('web_servers', []) if host.get('include_me', False) %} ALLOW_CONNECTION FROM {{ host.hostname }}; {% endfor %}
注意事项
- 记得用
pillar.get()或者host.get()来获取值,避免因为某个主机没有include_me键导致报错; - 如果你的条件不是简单的布尔值,比如要匹配特定字符串/数值,只需要修改列表推导式里的判断条件即可,比如
if host.get('env') == 'production'。
内容的提问来源于stack exchange,提问作者jma
相关产品推荐
相关产品推荐

