尝试构build匹配属性(在本例中为ec2_tag)的服务器列表,以便为特定的任务安排特定的服务器。
我试图匹配与selectattr
:
servers: "{{ hostvars[inventory_hostname]|selectattr('ec2_tag_Role', 'match', 'cassandra_db_seed_node') | map(attribute='inventory_hostname') |list}}"
虽然我从Ansible那里得到了一个types错误:
fatal: [XXXX]: 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"}
我在这里错过了什么?
您可以使用group_by
模块根据hostvar创建临时组:
- group_by: key: 'ec2_tag_role_{{ ec2_tag_Role }}'
这将创建一个名为ec2_tag_role_*
组,这意味着稍后您可以使用以下任何组创建一个游戏:
- hosts: ec2_tag_role_cassandra_db_seed_node tasks: - name: Your tasks...
当你建立一个复杂的过滤器链,使用debug
模块打印中间结果…并逐个添加过滤器,以达到预期的效果。
在你的例子中,第一步你就犯了错误: hostvars[inventory_hostname]
是你当前主机的事实字典,所以没有选择元素。
你需要一个hostvars
的值列表,因为selectattr
被应用到列表中,而不是字典。
但是在Ansible中, hostvars
是一个特殊的变量,实际上并不是一个字典,所以你不能直接调用.values()
而不用跳过一些.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 }}"