executable playbooks

I’ve added a feature to my fork that allows playbook files to be scripts, and thereby dynamically generating a playbook.

Here’s the patch;
https://github.com/mgwilliams/ansible/commit/a70ff5b273051eede44783780cdf5049d4245b8b

And here’s an example ‘task-master’:
https://gist.github.com/d405dc48130fede9b3b7

Another idea I had that could be done with this (although I don’t think I would use it), would be a frequent cron job that would poll the script. The script in turn could be controlled by any sort of data source determining what hosts should get what updates applied.

Any suggestions? Michael, may I open a pull request on this?

I’m wondering if this is making it too complicated.

Offhand, it seems like the playbooks could be generated by an external process instead, so we wouldn’t need to have this
feature.

So if your cron tab polls some data source, it could just output YAML files directly.

(I think most people wouldn’t need even that, I’d hope, but that would be doable now with present software)

–Michael

Complicated… perhaps – but it’s a totally optional feature. The cron part was just an idea that I don’t have too much interest in, but the way my task-master script works (pulling from cobbler) I really like.

Ok, here's my feeling on this.

It adds code paths most people don't have a need for, which means
there are more things to test. Per the original goals of the
project, and the fact you could code-generate playbooks easily from
the wrapper script you are using, I am disinterested in this including
this feature. Where something is achievable by outside scripting to
achieve the niche cases, we're going to stop and allow that to be
achieved that way.

The idea of the playbook file sometimes being a script that generates
a playbook file is extremely difficult to explain, and IMHO, rather
complicated for most users to understand. External inventory is
kind of a neccessary evil (we check executableness to avoid having a
configuration file) -- but it's something that *is* reasonably easy to
explain and already exists in other apps, but I think that's where we
should stop in terms of interpreting files as scripts and running
them.

Small core is major design focus, as is cutting back on
options/syntax/corner-cases that make it difficult to keep all of
Ansible in your head.

It also becomes very hard to audit what your playbooks produce,
meaning you can't track change of your configuration in source control
because it's dynamic.
This is also against one of the goals of the project.

OK, definitely see your point, but I’m wondering whether this could be made possible by a more general solution.

I’m thinking of a hooks directory, where scripts would be placed. There could be pre-run, post-run, etc scripts, that generate playbooks, perhaps return the name of a playbook to run, etc. Also too complicated?

Another idea that I think would allow me to accomplish what I’m trying, would be for task includes to support only_if. Then I could have a playbook that lists all my tasks, but only includes them if a certain var is set.

Syntax for the last option would be very simple:

tasks:

  • include: git.yaml
    only_if: $run_git

So your --extra-args patch (with no further patches) would presumably allow:

ansible-playbook foo.yml --extra-args “run-git=1”

possibly with some casting:

only_if: ‘$run_get eq ‘1’’

OK, definitely see your point, but I’m wondering whether this could be made possible by a more general solution.

I’m thinking of a hooks directory, where scripts would be placed. There could be pre-run, post-run, etc scripts, that generate playbooks, perhaps return the name of a playbook to run, etc. Also too complicated?

Yes, I don’t want any generated play books, this is confusing and something I would strongly like to avoid.

Another idea that I think would allow me to accomplish what I’m trying, would be for task includes to support only_if. Then I could have a playbook that lists all my tasks, but only includes them if a certain var is set.

While this initially seems reasonable, only_if is a per-host facility. Hosts see all tasks, they just know when to skip them.

The way to do this is actually groups, where your hosts are in the group if they need to have the tasks run on them or not, and then include multiple plays in the playbook.

  1. run common play on all
  2. run git stuff on subset of systems
  3. run other stuff on other group of systems
  4. etc

OK, always have to look at things from a few angles. So I think this
could be done with the existing inventory scripts and the extra-vars
patch. Right?