I trying to wrap my head around a simple problem.
I have a playbook (role) that installs ruby with rbenv.
Actually, it uses ruby.version host/group variable to install the
correct ruby version :
The problem, as explained previously, is that I can hardly use
with_items within a role's task since I use chained actions with
registered variables. It simply wouldn't work.
For instance, before installing ruby, an action checks if the requested
version is already installed (and registers a variable). I don't think
this would survive a "with_items" loop (unless it is possible to
register hash entries, but I don't think so).
I am also looking for a way to loop over a set of tasks.
I used to do it with role.with_items just as you first posted but it has been deprecated.
The deprecation is for good reasons I think because the plays are unrolled before execution and even if role.with_items work in simple cases, I believe there are more complex inventory cases where it does weird things.
One option is to push the with_items down to the task level. This is what I did for my multi-versions installs but I did not need to register variables so it was simpler.
The best would be to make a role loopable with minimum modifications (pushing with_items down to the tasks level is rather painful imho)
Your question made me think about a potential new way to do it. it will look as a hack to many but may work to unroll the loop. The basis of the idea is to consider that the main use case is to loop N times over the role, N being bounded to for example 5.
Let’s say you have you role : “ruby_install_one_version”
in meta.main.yml / dependency, you add something like (I still have a hard time with $ and {{}} in these contexts and I am not sure .length is the way to do it)
The details would have to be refined but I think it could work to have the roles unroll as independent blocks of tasks rather than inside each task ; and if it works, it would look cleaner to me than obscuring the initial role with with_items and with_nested all over the place.
I am also looking for a way to loop over a set of tasks.
[...]
One option is to push the with_items down to the task level. This is
what I did for my multi-versions installs but I did not need to register
variables so it was simpler.
The best would be to make a role loopable with minimum modifications
(pushing with_items down to the tasks level is rather painful imho)
[...]
The details would have to be refined but I think it could work to have
the roles unroll as independent blocks of tasks rather than inside each
task ; and if it works, it would look cleaner to me than obscuring the
initial role with with_items and with_nested all over the place.
Tell me if you try it !
That's hell of a hack, but it works like a charm (with few changes) !
I am glad the looping works it means that you can go from a “single” install script to a “multi” without modification and that is interesting.
Note that in your
ruby_multi/tasks/main.yml
you can add a fail test when the versions array has a length superior to the looping cardinality of your multi. This way you will be informed if your array is not fully looped over.
note also that there might be other issues to look at and solve with notify: restart when doing a multi version of a server install. It might be necessary to restart all versions even if only one version is notified. At least until the notify: can accept parameters.
I do not use ruby that much but thanks for the script it is interesting and made me learn a few tricks.
It's registered variables. I use conditional tasks that depend on
previously registered variables (for instance, I check if the requested
ruby version is already installed and depending on the result, I install
it or not).
I'm not sure I can do that using 'with_items' for the ruby versions :
registered variables would be overriden for each item I suppose, unless
there is some facility that would put the results in a hash instead of a
simple variable.
I just had the same problem. But since your post is a few years old, I wondered if there might be a better solution by now. If there isn’t, I’ll try the “hack” :D.