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

269 views
Skip to first unread message

Willard Dennis

unread,
Sep 12, 2014, 10:48:57 AM9/12/14
to ansible...@googlegroups.com
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



Serge van Ginderachter

unread,
Sep 12, 2014, 10:54:50 AM9/12/14
to ansible...@googlegroups.com

On 12 September 2014 16:48, Willard Dennis <willard...@gmail.com> wrote:
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)


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

AFAIK, there is no workaround for this.

Michael DeHaan

unread,
Sep 12, 2014, 11:42:30 AM9/12/14
to ansible...@googlegroups.com
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"



--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/CAEhzMJCq7U64k88uUMmFhO_Arwqr%3DhOdFCTzHUgMLg8jxiPD4Q%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Michael DeHaan

unread,
Sep 12, 2014, 11:42:55 AM9/12/14
to ansible...@googlegroups.com
Sorry in the above, the word "distro" should be "pattern".


Willard Dennis

unread,
Sep 12, 2014, 2:15:47 PM9/12/14
to ansible...@googlegroups.com
Thanks, Michael! But can I do the following?

$ cat site.yml
---

- hosts: all
  tasks:

# Set up OS-specific groups
  - group_by: key=os-{{ansible_distribution}}-{{ansible_distribution_version}}


- hosts: "{{ distro | default('all') }}"
  include:
  - dept1-servers.yml
  - dept2-servers.yml
  - base-static-setup.yml


Rather not change the individual playbooks if I can help it.

Thanks,
Will

Willard Dennis

unread,
Sep 12, 2014, 2:29:46 PM9/12/14
to ansible...@googlegroups.com
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 <module>
    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'

Michael DeHaan

unread,
Sep 12, 2014, 3:19:30 PM9/12/14
to ansible...@googlegroups.com
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.





--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

Willard Dennis

unread,
Sep 12, 2014, 4:38:22 PM9/12/14
to ansible...@googlegroups.com
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
---

- include: dept1-servers.yml
- include: dept2-servers.yml
- include: base-static-setup.yml

...which works fine.

The one producing the traceback is this:

$ cat site.yml.bad

---

- hosts: all
  tasks:
# Set up OS-specific groups
  - group_by: key=os-{{ansible_distribution}}-{{ansible_distribution_version}}

- hosts: "{{ distro | default('all') }}"
  include:
  - dept1-servers.yml
  - dept2-servers.yml
  - base-static-setup.yml

I also tested the following:

$ cat site.yml.test1
---
- hosts: all
  tasks:
# Set up OS-specific groups
  - group_by: key=os-{{ansible_distribution}}-{{ansible_distribution_version}}

- include: am-servers.yml
- include: stor-servers.yml
- include: base-static-setup.yml


Which ran fine as well, so it must be the following block that is causing the fault:

- hosts: "{{ distro | default('all') }}"
  include:
  - dept1-servers.yml
  - dept2-servers.yml
  - base-static-setup.yml

All I am trying to do is to make the included playbooks run only for machines with the specified OS, if I specify the target OS on the ansible-playbook command line via the ' -e "distro=os-Fedora-20"' variable construct you gave me. That way I can always target a subset of my specified inventory by OS, if I want to run certain plays (say those with a specific tag) only against member servers with the specified OS. Otherwise, if I don't pass an " -e distro=<whatever>" variable, it will target all members of the inventory. Make sense?

- Will

Reply all
Reply to author
Forward
0 new messages