Some jinja filters don't work in host pattern

179 views
Skip to first unread message

Raghu Udiyar

unread,
Dec 24, 2014, 8:01:41 AM12/24/14
to ansible...@googlegroups.com
Hello,

I'm trying to work on a requirement to have the host pattern change depending on certain host groups or parameters being passed to the playbook :

This is what I need exactly :
1. When an external var cli_hosts is provided, this playbook runs on the provided host pattern

2. If not, it defaults to a group 'new_instances', I've used this group to indicate new instances that are spawned in a parent playbook, which includes this play via include statement.

I could have used cli_hosts ( by using set_fact ) in the parent playbook, expecting that this one will pick it up, but that doesn't work. Passing it as a parameter in the include statement doesn't work either.

From what I understand, this is because host patterns are not in the set_fact scope. Also, set_fact is host specific fact, so it gets set in the pattern of the original play (localhost in my case). I think it would help if there is a way to access the global scope somehow. I'm not sure why passing it as a parameter not work ( via include )

3. If either of the above two are not present, default to the entire cluster.

This is the play I tried :

---
- name: Test Playbook
  hosts: localhost
  connection: local
  tasks:
    - name: create a custom group
      add_host: name=test groups=new_instances

    - debug: msg="{{cli_hosts|default('new_instances' in groups and 'new_instances' or null)|default('test_cluster')}}"

- name: Deploy to hosts
  hosts: "{{cli_hosts|default('new_instances' in groups and 'new_instances' or null)|default('test_cluster')}}"
  tasks:
    debug:


If you run this, in the first play debug prints the correct, expected output, but fails in the next play when used for the host pattern. I guess this is because of 'new_instances' in groups in default, which works correctly in the first play.

So, question : why does the host pattern fail for the same expression?

Reusing playbooks in other plays gets cumbersome due to the limitations in what can be passed in include. For host patterns, a way to enumerate the hosts would help, as I can reconstruct the group in the included play. Also, using roles to abstract things doesn't fit well in all scenarios. If this fails, the only solution I see is to duplicate the logic in the parent play.

Thanks,
Raghu

Brian Coca

unread,
Dec 24, 2014, 8:40:55 AM12/24/14
to ansible...@googlegroups.com
I'm very confused as to what you are attempting.

First, 'groups' is not available at the host pattern level, as it is
host dependent.
Second, the default filter does work, you can test this easily with:

- hosts: "{{cli_hosts|default('new_instances')}}"

having the ternary condition you want (if no new_instances) is a lot
harder as the group won't get evaluated until after the expression is.

--
Brian Coca

Raghu Udiyar

unread,
Dec 24, 2014, 8:56:20 AM12/24/14
to ansible...@googlegroups.com
On Wednesday, 24 December 2014 19:10:55 UTC+5:30, Brian Coca wrote:
I'm very confused as to what you are attempting.

I'm basically trying to reuse an exiting playbook, by passing a new host pattern to it, from another play. One use case is, I have a "common" play that runs on all hosts. I have another play that spawns new nodes. After spawning new nodes, I include this common play, and need a way to pass the new hosts to the common play. This common play cannot be a role, because there are certain decisions I make based on the pattern, and pass parameters to the role.
 

First, 'groups' is not available at the host pattern level, as it is
host dependent.


I was under the impression that groups was at the "current playbook" scope, as its available for new plays in the same playbook (operating on different hosts pattern).
 
Second, the default filter does work, you can test this easily with:

- hosts: "{{cli_hosts|default('new_instances')}}"

having the ternary condition you want (if no new_instances) is a lot
harder as the group won't get evaluated until after the expression is.


The reason I have the ternary condition is I'm unable to pass the new host pattern to "cli_hosts", if I could do that, than the pattern expression will be simpler. Is there a way I can do that? that is pass the host pattern via include.

Brian Coca

unread,
Dec 24, 2014, 9:02:11 AM12/24/14
to ansible...@googlegroups.com
> I was under the impression that groups was at the "current playbook" scope,
> as its available for new plays in the same playbook (operating on different
> hosts pattern).
>
groups is available to every play but only once hosts/inventory is
loaded, which is not the case with the - hosts: directive.

>
> The reason I have the ternary condition is I'm unable to pass the new host
> pattern to "cli_hosts", if I could do that, than the pattern expression will
> be simpler. Is there a way I can do that? that is pass the host pattern via
> include.
>
I don't understand, if you are passing cli_hosts in the command line
it should be easy enough to pass a pattern -e
'cli_hosts=group1:!group2'.

As for the play needing to target new_hosts, just leave it at that, if
there are no new_hosts ti should be skipped.

--
Brian Coca

Raghu Udiyar

unread,
Dec 24, 2014, 11:05:14 AM12/24/14
to ansible...@googlegroups.com
On Wednesday, 24 December 2014 19:32:11 UTC+5:30, Brian Coca wrote:
> I was under the impression that groups was at the "current playbook" scope,
> as its available for new plays in the same playbook (operating on different
> hosts pattern).
>
groups is available to every play but only once hosts/inventory is
loaded, which is not the case with the - hosts: directive.

Ok, if I could pass the pattern to the included play, I can use it directly in the hosts pattern. But I'm not able to pass that.
 
 

>
> The reason I have the ternary condition is I'm unable to pass the new host
> pattern to "cli_hosts", if I could do that, than the pattern expression will
> be simpler. Is there a way I can do that? that is pass the host pattern via
> include.
>
I don't understand, if you are passing cli_hosts in the command line
it should be easy enough to pass a pattern -e
'cli_hosts=group1:!group2'.

As for the play needing to target new_hosts, just leave it at that, if
there are no new_hosts ti should be skipped.

That is exactly what I was using in fact. But now there is a new requirement of having a default cluster if none of them are defined, that is cli_cluster or new_hosts. and, that is why I started working with the defaults filter to come up with an expression to solve this.

-- Raghu
 

--
Brian Coca
Reply all
Reply to author
Forward
0 new messages