Multiple items and a long list of conditional tasks

I’m writing a playbook to create a number of solr cores, but I’m running into some issues.

I started with a task file that would be included, but appearantly include and with_items isn’t supported.

The idea was, that for every core I would check that the base folder of the core existed. This result (stat) would be saved to a variable.

  • name: check for core existence

stat: path=/usr/share/solr/live/solr/cores/{{ item.name }}
register: st_cores
with_items: solr_cores

Then, to enumerate over it in later tasks, I could use the with_indexed_items and use a conditional when to exclude the cores that were already present
eg:

  • name: Copy example core
    shell: cp -R /usr/share/solr/example/solr/collection1/conf/* /usr/share/solr/live/solr/cores/{{ item.0.name }}/conf/
    with_items: solr_cores

when: not st_cores.results[{{ item.0 }}].stat.exists

This works fine for most of the tasks, but I also have a number of tasks that use with_items themselves. I managed to combine them using with_nested, but I can’t figure out how to include the conditional, as I don’t have the index as with with_indexed_items

eg.

  • name: Copy some files
    shell: cp /some/folder/{{ item[1] }} /usr/share/solr/cores/{{ item[0].name }}/
    with_nested:
  • solr_cores
  • [ ‘somefile.xml’, ‘anotherfile.xml’, ‘evenmorefiles.xml’ ]
    when: not st_cores.results[{{ item[0].0 }}].stat.exists

Basically, I can’t check stat results, as I don’t know the index of the current item in that array. Any ideas on how I can solve this? Either I need a way to be able to check for the file existance on some other way that does work with with_nested, or I need some sort of creative workaround for the include with_items problem.

Might it be easier to write a simple fact module that returns what cores you have, rather than doing the register?

This way you could return a hash table indexed by core name, as well as a list of cores, which might make the playbooks more intuitive and less relying on some rather “programmy” concepts that Ansible usually tries to avoid.

Of course! I keep forgetting that the “programmy” stuff should go in Python :slight_smile:
When you talk about a ‘fact’ module, though, what do you mean? Writing a module that takes in a bunch of data formatted in some way and then exit_json( [changed=False,] yourStuff=yourStuff ), where “yourStuff” is a dictionary/object/etc that you can then register and iterate over the results? Or, is there some sort of API method where modules can set facts themselves? I ask because I have a similar task, in that I need to read in a file and then perform a set of tasks based on the results.

For example, if my file “foo.xml” looks like:

<foos> <foo bar="a"> <baz Name="a1"> <baz Name="a2"> </foo> <foo bar="b"> <baz Name="b1"> <baz Name="b2"> <baz Name="b3"> </foo> </foos>

Then, for each foo, I will have to do one set of tasks to handle the bar value and then another set of tasks to handle each bar’s baz. I am wondering how I can accomplish this while operating within the Ansible paradigm. Can you elaborate a little more on how this could/should be accomplished? Thanks!

Is this what “block” tasks are meant to handle?