Thank you everyone who chimed in on this discussion, it's really helped me 
understand how run_once works.

As for workarounds - Alex I think you were on the right track with the 
include, but it needs to be dynamic. I think this does what you want:

inventory:

machine-a
machine-b

playbook.yml:

- hosts: all
  gather_facts: no
  tasks:
    - name: first task
      ping:

    - name: include for second task
      include_tasks: task.yml
      when: inventory_hostname == 'machine-b'

task.yml:

- name: second task
  ping:
  run_once: true

Because this include is dynamic instead of static, the first host - 
"machine-a" - doesn't encounter the "run_once" task at all, so it runs when 
the second host reaches it. (The reason this doesn't happen with your 
example in the first message on this thread is because the import is 
static: the include task runs for all machines, and the condition applies 
to the tasks it includes, so it's equivalent to having the "when" written 
on the run_once task.)

This example is trivial, but in a larger setup this could be used to run a 
task only once, on a host matching certain conditions, in a way that is far 
less fragile than depending on inventory order. Hopefully this is helpful 
to anyone trying to combine run_once and conditions.


On Tuesday, 20 March 2018 17:46:38 UTC, Alex Hunt wrote:
>
> Thanks everyone, I think the root of the issue is finally clear.
>
> I'd love to have a 'run_first_host_that_matches_when' keyword, though I 
> understand there might be technical issues getting in the way. I think the 
> most intuitive way to set the status would be to set it for all hosts that 
> match the when, but that's a bit of an arbitrary thing.
>
> The current set of keywords makes it very difficult to make reusable code. 
> If we want to include roles or tasks conditionally, we simply can't use 
> run_once safely. Even the "ugly-ass workarounds" mentioned above are not 
> possible in some instances, since the conditions might be completely 
> different depending on where it gets included.
>
> Another alternative would be to expose the list of hosts skipped by outer 
> when clauses in another variable that can be used in inner when clauses. 
> Something like "ansible_not_already_skipped_hosts". I know the logic is to 
> skip the task, not the host, but when using includes, it's effectively the 
> same. If we haven't done any includes with when clauses, it'd be 
> effectively the same as ansible_play_hosts.
>
> If we had a variable like that, I could put something like this in the 
> inner-task.yml:
> - name: Inner task
>   command: hostname
>   when: inventory_hostname == ansible_not_already_skipped_hosts[0]
> If I needed to save the result to all hosts, I could register the result 
> and then follow up with a set_fact using the var from that one host.
>
> This isn't as clean as having a 'run_first_host_that_matches_when' 
> keyword, but still prevents the "ugly-ass workarounds" from being needed on 
> EVERY included task.
>
> On Tuesday, March 20, 2018 at 7:07:27 AM UTC-7, Brian Coca wrote:
>>
>> A couple of  clarifications, these are important when you hit the 
>> corner case in which it matters: 
>>
>> - its not 'run on the first host in play/inventory' its 'run on the 
>> first host that reaches the task' which means that hosts that fail 
>> and/or are removed in previous tasks are not considered. Normally (in 
>> the absence of failure) this does mean the first host in 
>> play/inventory, changing to other strategies can affect this. 
>>
>> - it is 'mostly' equivalent to `when: inventory_hostname == 
>> ansible_play_batch.0` but there is one major difference, other hosts 
>> are not 'skipped', they are all given the same status/return from the 
>> single execution. 
>>
>>
>> The feature should really be named 
>> 'only_first_host_tries_to_run_and_applies_status_to_rest'.  To make it 
>> work as 'run_first_host_that_matches_when' would make the part of 
>> applying the status to all hosts a lot more difficult to do sanely ... 
>> do we set 'skipped' for the ones we skipped? do we set same status for 
>> all hosts? 
>>
>> At this point I don't see us modifying the feature (maybe clarifying 
>> docs?), but I'm open to create a new set of keywords that allows for 
>> the difference in range of behaviors not already available via 
>> conditional construction. 
>>
>> -- 
>> ---------- 
>> Brian Coca 
>>
>

-- 
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-project+unsubscr...@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/4b365dd9-8307-49f2-9240-2cc02ff1bf3e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to