with_items combined with with_first_file ?

I’ve been looking for a solutions for this, but I can’t seem to figure it out. Here is what I want to do:

I’m writing a playbook to manage a number of DNS servers. I have a list of zones in my vars file, like so:

list_of_zones:

I then have a dir with each zone file in it:

zones/a.com.db
zones/b.com.db
etc…

However, for some of the zones, I just want to use a default zone file. So basically, what I would like to do is something like this:

  • name: Copy zone files
    copy: src=zones/{{ item }} dest=/var/named/zones/{{ item }}
    with_first_file:
  • path/to/zones/{{ item }}.db
  • path/to/zones/default.db
    with_items:
  • list_of_zones

This however does not work.

I tried to split out the copy part and with_first_file to a different file in the playbook and include it, passing the zone as a var, but I then got a warning that using with_items together with include was not recommended and that it was going to be deprecated.

I’m a bit lost how to solve this. One option would of course be to extend my zones var to include the name of the zone file as well, but I would like to make this as dynamic as possible. Any ideas are welcome.

Thanks,
/Martin

Something like this might work:
​​
- name: Copy zone files
  copy: src={{
​lookup('first_found', ['path/to/zones/' + ​
item

+ '.db'

​, 'path/to/zones/default + '.db'])​
}} dest=/var/named/zones/{{ item }}
  with_items:
    - list_of_zones

​Serge​

Hi Serge,

This worked great. I didn’t realize that you could use the with_* functions with lookup(), now things makes more sense. Thank you!

Best regards,
/Martin

Hi Serge,

This worked great, thank you. I didn’t realize that you could use the with_* functions with lookup(), now things makes a lot more sense.

Best regards,
/Martin

It’s not really intended that first_found be used in this way, because it’s a plugin that returns lists to iterate on, as opposed to ‘file’.

However, it is definitely something that will continue to work.

It just wouldn’t make sense using with_items with, say, ‘items’ in the lookup, for that, go to things like ‘with_nested’.

Just out of curiosity, if not with lookup(‘first_found’,…) how would you do


with_items: itemlistvar
with_first_found:

  • file1
  • file2
  • etc…

Are you suggesting:
with_nested:

  • itemlistvar
  • lookup(‘first_found’, … )

I found that the inline lookup "src={{
​lookup(‘first_found’, [‘path/to/zones/’ + ​
item

  • ‘.db’

    ​, 'path/to/zones/default + ‘.db’])​
    }}" did not quite work for me.
    The following example did the trick (for me) tho.

As an example:

When you say something doesn’t work for you, please describe HOW it doesn’t work.

It’s unclear if you hit a traceback that we need to deal with or what.

But no, with_first_found is designed to implement inline loops, not to be used like that.

Some lookup plugins are for simple strings, others provide iterators.

I agree this is somewhat confusing but that’s why we show them seperately in the docs with appropriate-ish examples for each.