根据匹配的属性构建列表(ansible)

mos*_*osh 4 linux ansible

尝试构建与属性匹配的服务器列表(在本例中为ec2_tag),以便为特定任务调度特定服务器.

我正在尝试selectattr与之匹配:

servers: "{{ hostvars[inventory_hostname]|selectattr('ec2_tag_Role', 'match', 'cassandra_db_seed_node') | map(attribute='inventory_hostname') |list}}"
Run Code Online (Sandbox Code Playgroud)

虽然我从Ansible得到了类似错误:

fatal: [X.X.X.X]: FAILED! => {"failed": true, "msg": "Unexpected templating type error occurred on ({{ hostvars[inventory_hostname]|selectattr('ec2_tag_Role', 'match', 'cassandra_db_seed_node') | map(attribute='inventory_hostname') |list}}): expected string or buffer"}
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

Kon*_*rov 5

构建复杂的过滤器链时,使用debug模块打印中间结果...并逐个添加过滤器以获得所需的结果.

在你的例子中,你在第一步有错误:hostvars[inventory_hostname]只是当前主机的事实字典,所以没有什么可以从中选择元素.

您需要一个hostvars'值列表,因为selectattr它应用于列表,而不是dict.

但是在Ansible中hostvars是一个特殊的变量,实际上并不是一个字典,所以你不能只是.values()在不跳过一些箍的情况下调用它.

请尝试以下代码:

- hosts: all
  tasks:
    - name: a kind of typecast for hostvars
      set_fact:
        hostvars_dict: "{{ hostvars }}"
    - debug:
        msg: "{{ hostvars_dict.values() | selectattr('ec2_tag_Role','match','cassandra_db_seed_node') | map(attribute='inventory_hostname') | list }}"
Run Code Online (Sandbox Code Playgroud)