include + with_items

Michael,

What exactly is the (technical?) problem doing include + with_items?

I know you do not recommend it, and are very vocal on that, but I never really understood exactly why.

Is it a syntax problem, difficult to grasp all the possible consequences?
Is there a particular technical reason not to do that?
Is this something that coincidently happens to work now, but might break in the future?
Maybe something else?

Also: is it specific to the items lookup_plugin, or does this recommendation also apply to other lookup plugins?

Thanks for sorting that out,

Serge

yeah, with_items on an include was something Daniel added a while back.

What “include with a with_items” clause does is create a list of tasks.

While this sounds great (and was technically pretty slick), tasks must be uniform for all hosts in the play (but variables get subbed in later)

95% of everyone seems to want to use this with an inventory scoped data, like having a list of packages or users defined in the group.

This doesn’t work, because the same tasks can’t be created for each item.

So, yes, it’s technically NOT possible to do include + with_items if with an inventory scoped variable.
It’s fine otherwise, but I feel it’s much better to include the looping inside the task file, using a simple task + with_items.

It’s the same kind of thing that comes up with “why aren’t variables in my task name being interpolated” when using inventory variables, except it’s functional instead of cosmetic.

Excerpts from Michael DeHaan's message of 2013-07-09 21:09:21 -0400:

While this sounds great (and was technically pretty slick), tasks must be
uniform for all hosts in the play (but variables get subbed in later)

95% of everyone seems to want to use this with an inventory scoped data,
like having a list of packages or users defined in the group.

This doesn't work, because the same tasks can't be created for each item.

Just to clarify, this means looping on task includes *would* work if the
list were set in, say, 'group_vars/all'? And might *happen to* work if
the list were defined in, say, 'group_vars/foo', and the playbook in
question had 'hosts' set to 'foo'?

In other words, ansible parses the yaml, encounters an include statement
(either literally or via role magic), and then evaluates the loop. If
any variables referenced in the loop cannot be resolved, they are (like
all unresolved variables in ansible), passed literally.

I can see that coming back to bite you if you forget those specifics.

I assume the exact same conditions imply to looping roles?

Is there any chance of inserting a deprecation warning (or just a 'there
be dragons' warning) when someone uses a loop with an include statement
or a role statement?

If not, perhaps we could add a note in the documentation regarding
variable precedence? Or add a short section near there about scoping
rules (of which there are very few, this being by far the most
complicated)? I'd be happy to submit a pull request if that's desired.
I can also see wanting to let sleeping dogs lie...

Also, re: lookup plugins other than 'with_items', as Serge asked, I'm
going to guess is again matters whether the lookup plugin can be
evaluated.

So, for example, I tested the following:

    --- # test.yaml
    hosts: localhost
    connection: local
    tasks:
      - include: mytasks.yaml
        with_env:
          - HOME
          - USER
          - PWD
          - EDITOR

    --- # mytasks.yaml
    - debug: msg={{item}}

Running `ansible-playbook test.yaml` gives:

    PLAY [localhost] **********************************************************
    
    GATHERING FACTS ***********************************************************
    ok: [localhost]

    TASK: [debug msg=/home/chamill] *******************************************
    ok: [localhost] => (item=/home/chamill)
    
    TASK: [debug msg=chamill] *************************************************
    ok: [localhost] => (item=chamill)
    
    TASK: [debug msg=/home/chamill] *******************************************
    ok: [localhost] => (item=/home/chamill)
    
    TASK: [debug msg=vim] * ***************************************************
    ok: [localhost] => (item=vim)
    
    PLAY RECAP ****************************************************************
    localhost : ok=4 changed=0 unreachable=0 failed=0

Anwyay, sorry about the wall of text, but I got curious. Basically
with_items works fine on includes, but only if the variables in the loop
have an effectively global scope (so, variables set for the 'all' group,
or directly in the playbook, or resolved at runtime via a lookup plugin;
I might be missing one or two other types of variables).

“Just to clarify, this means looping on task includes would work if the
list were set in, say, ‘group_vars/all’?”

No, it would not.

Excerpts from Michael DeHaan's message of 2013-07-10 09:46:11 -0400:

"Just to clarify, this means looping on task includes *would* work if the
list were set in, say, 'group_vars/all'?"

No, it would not.

Ah, so it is of *really* limited utility. Only works with playbook vars
and lookup plugins.

I can see why you don't encourage its use.

Excerpts from Michael DeHaan’s message of 2013-07-09 21:09:21 -0400:

Is there any chance of inserting a deprecation warning (or just a ‘there
be dragons’ warning) when someone uses a loop with an include statement

or a role statement?

+1 for deprecation warnings
Also, Ansible with 1.2 has changed and regularized a lot to the better.
The ability to flag old style/new style would be useful.

Parenthetically, error_on_undefined_vars is useful too.

If not, perhaps we could add a note in the documentation regarding
variable precedence? Or add a short section near there about scoping
rules (of which there are very few, this being by far the most
complicated)? I’d be happy to submit a pull request if that’s desired.
I can also see wanting to let sleeping dogs lie…

+1 for very good documentation about precedence/scoping.
It seems to generate a lot of questions.

Right, I haven’t really deprecated it, meaning there is no plan to remove it.