Excluding hosts in a single line ansible command

New at ansible… Have used “pdsh” a lot. In pdsh, assuming it uses the default host list, if I want to run the same command on all hosts. I say something like

‘pdsh ’

If I want to run on only a few hosts, I could run

‘pdsh -w “host[1-5,7,9], doggy23” ’

  • That will run on host1, host2, host3, host4, host5, host7, host9 and doggy23

However, often I want to run on all the hosts EXCEPT a few that, say are dead, or I already ran the command on to test it, or whatever. To do that in pdsh, I could run:

‘pdsh -x “host2, host4, doggy33, kitty[4-6]” ’

That would run on all hosts in the hostlist, EXCEPT host2, host4, doggy33, kitty4, kitty5 and kitty6
How, in ansible, in a command line, one-off, (maybe called “ad-hoc”?) way can I do the above without making a new group or list with just the hosts I do not want to run on, can I do the above?
I believe if I do “ansible ‘dog*’ --list-hosts” it will only run on the hosts that start with “dog” in the list-hosts. But I have had mixed results with stuff like:

‘ansible ‘all:!doggy2:doggy5:host3*’ --list-hosts’

‘ansible ‘all:!doggy2:!doggy5:!host3’ --list-hosts’

'ansible ‘all:!doggy2:!doggy5:!host3*’ --list-hosts’​ {In cshell}

But it seems a little “messy” and, as you can see.

Is there a “Exclude” option like the “-x” in pdsh? Some thing like

‘ansible ‘all:!doggy[2,5]:!host3’ -list-hosts ’

or better:

First off, do not escape the “!” in Ansible if you are also quoting the line.

ansible “all:!doggy2:!doggy5” is fine. If you leave off the quotes, yes, the “!” on the shell is a thing. But double escaping - bad.

Ansible really likes it when you use groups though, I’m not sure arbitrarily why you need to exclude doggy2 and doggy5.

Define your hosts based on groups of where they are, and what they do, and talk to machines in each group.

Ansible does understand host slices of course.

ansible “doggy[2:5]” will select hosts starting at index 2 and ending at index 5 in that group.

Generally subtractive matching is not the norm. Easier to just pick what you want to talk to.

The real magic of course comes in playbooks.

So basically all what you say above works, you’re just escaping too much, and that’s the confusion.

Mike,
Thanks for the reply.
Subtractive Matching, as you called it may seem not quite normal in ansible. We have large clusters of hundreds of compute nodes. It is quite normal for us to run pdsh or ansible against all nodes to do a million things across the board. But. sometimes we just want to do a command against some of the nodes, Sometimes, those nodes are in a structured mode so a “list” of say all compute nodes in rack3 and rack4 would be a good way to talk to just those nodes. However, we find that other than a list of all nodes in the cluster, and maybe some lists of subsets, say all the nodes with one processor type versus another processor. Or a list of all nodes in each chassis or rack is all that we want to manage.

However, there a a lot of times we need to hunt down which nodes are running, say a program that is spread out over a dozen nodes in the cluster, then we want to run a command specifically on those nodes. It is not practical to have lists of every combination of these clusters with 200 or 500 individual compute nodes. Much easier to say run on nodes a, k and r this command.

Likewise, if we want to run a command that could be disruptive to a running job on a set of nodes, we want to run a command on all nodes, but not on those nodes a, k and r. You see.
Actually, even with pdsh, at first I made subgroup hosts lists for each rack or chassis, but found it just as easy to say “pdsh -w node[1-64,81-128,161-192] ” to skip the 5th, 8th and 9th chassis (each with 16 nodes in them) then to use the sublist of hosts groups for the chassis. Of course, could do the same with “pdsh -x node[65-80,129-160} ” and let it run the command on All servers in this cluster, using the default list of all nodes, but exclude those nodes in those three chassis. And yes this could be done with a pdsh with the exclude the three subgroups that represent those three chassis.

But, truth be know, it is rear that a command needs to be run on all blades in certain chassis. More likely it is needed to run on a spattering of nodes all over the entire cluster…Or run on all node EXCEPT a spattering of nodes all over the cluster.
That is why I was wondering if there was an exclude option with ansible. If not, we have the method you wrote about.

Thanks

You might want to look into group_by to be able to make ad-hoc groups based on the conditions you’ve mentioned

Brian Coca