Is there a way to dynamically target subsets of an inventory group based on facts?

Hi all,

I have an inventory file with hosts in different groups within. I would like to run a playbook on a certain group, but only where the host members of that group that have a certain OS (say, " ansible_distribution=‘Fedora’ ".) I was told to look at the “group_by” module, and so in my top-level site.yml file I put in the following:

Set up OS-specific groups

  • group_by: key=os-{{ansible_distribution}}

So then I tried to do the following:

$ ansible-playbook -i inventory-file -u root -k site.yml --tags=mailserver --limit=os-Fedora

but when I do so, I get:

ERROR: provided hosts list is empty

So am I doing this incorrectly, or for some reason, is the “os-Fedora” group empty? (i.e. the logic is not matching any hosts)

Also, is there a way to print the members of the group_by variable out so I can see what’s being included?

Thanks,
Will

​The --limit happens early, at initialization​, and at that time the group
is indeed empty.

AFAIK, there is no workaround for this.

You can’t use group_by stuff at that point because it hasn’t run yet, true, but there is a solution to what you would like to do, using two plays in the same playbook

  • hosts: all
    tasks:

  • group_by: key=os-{{ ansible_distribution }}

  • hosts: “{{ distro | default(‘all’) }}”
    tasks:

  • action: ping

ansible-playbook foo.yml -e “pattern=os-Fedora”

Sorry in the above, the word “distro” should be “pattern”.

Thanks, Michael! But can I do the following?

$ cat site.yml

Hmmm, I guess not…

$ ansible-playbook -i temp-stor-inv -u root -k site.yml --tags=mailserver -e “distro=os-Fedora-20”
SSH password:
Traceback (most recent call last):
File “/usr/bin/ansible-playbook”, line 309, in
sys.exit(main(sys.argv[1:]))
File “/usr/bin/ansible-playbook”, line 191, in main
force_handlers=options.force_handlers
File “/usr/lib/pymodules/python2.7/ansible/playbook/init.py”, line 180, in init
(self.playbook, self.play_basedirs) = self._load_playbook_from_file(playbook, vars)
File “/usr/lib/pymodules/python2.7/ansible/playbook/init.py”, line 271, in _load_playbook_from_file
inc_vars, inc_path = self._get_include_info(play, basedir, play_vars)
File “/usr/lib/pymodules/python2.7/ansible/playbook/init.py”, line 208, in _get_include_info
tokens = shlex.split(play_ds.get(‘include’, ‘’))
File “/usr/lib/python2.7/shlex.py”, line 279, in split
return list(lex)
File “/usr/lib/python2.7/shlex.py”, line 269, in next
token = self.get_token()
File “/usr/lib/python2.7/shlex.py”, line 96, in get_token
raw = self.read_token()
File “/usr/lib/python2.7/shlex.py”, line 124, in read_token
nextchar = self.instream.read(1)
AttributeError: ‘list’ object has no attribute ‘read’

I’m unclear what you meant by “can I do X” specifically, what that meant you could or couldn’t do.

A traceback in ansible is a bug though, so please figure out what the minimum way to reproduce that is and file a ticket (provided you are using at least 1.7.1 already and it can be reproduced there).

If you can, checking the devel branch would also be useful.

Sorry Michael, I will try to be more clear.

I am running Ansible 1.7.1 currently.

So my original site.yml is this:

$ cat site.yml.orig