Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building lists based on matched attributes (ansible)

Tags:

linux

ansible

Trying to build a list of servers that match an attribute (in this case and ec2_tag) to schedule specific servers for specific tasks.

I'm trying to match against selectattr with:

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

Though I'm getting what looks like a type error from 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"}

What am I missing here?

like image 254
mosh Avatar asked Mar 11 '23 05:03

mosh


1 Answers

When you build a complex filter chain, use debug module to print intermediate results... and add filter one by one to achieve desired result.

In your example, you have mistake on the very first step: hostvars[inventory_hostname] is a dict of facts for your current host only, so there is nothing to select elements from.

You need a list of hostvars' values, because selectattr is applied to a list, not a dict.

But in Ansible hostvars is a special variable and is not actually a dict, so you can't just call .values() on it without jumping through some hoops.

Try the following code:

- 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 }}"
like image 173
Konstantin Suvorov Avatar answered Mar 21 '23 09:03

Konstantin Suvorov