# executable playbooks

**URL:** <https://forum.ansible.com/t/executable-playbooks/11382>\
**Category:** Ansible Project\
**Created:** [March 30, 2012, 3:14am UTC](https://forum.ansible.com/t/executable-playbooks/11382 "2012-03-30T03:14:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matthew\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a3d4f5/32.png) [@Matthew\_Williams](https://forum.ansible.com/u/Matthew_Williams)\
**Post date:** [March 30, 2012, 3:14am UTC](https://forum.ansible.com/t/executable-playbooks/11382/1 "2012-03-30T03:14:44Z")

</div>

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](https://github.com/mgwilliams/ansible/commit/a70ff5b273051eede44783780cdf5049d4245b8b)

And here’s an example ‘task-master’:  
[https://gist.github.com/d405dc48130fede9b3b7](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?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [March 30, 2012, 3:18am UTC](https://forum.ansible.com/t/executable-playbooks/11382/2 "2012-03-30T03:18:29Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Matthew\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a3d4f5/32.png) [@Matthew\_Williams](https://forum.ansible.com/u/Matthew_Williams)\
**Post date:** [March 30, 2012, 4:01am UTC](https://forum.ansible.com/t/executable-playbooks/11382/3 "2012-03-30T04:01:31Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [March 30, 2012, 11:22am UTC](https://forum.ansible.com/t/executable-playbooks/11382/4 "2012-03-30T11:22:44Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Matthew\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a3d4f5/32.png) [@Matthew\_Williams](https://forum.ansible.com/u/Matthew_Williams)\
**Post date:** [March 30, 2012, 3:16pm UTC](https://forum.ansible.com/t/executable-playbooks/11382/5 "2012-03-30T15:16:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Matthew\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a3d4f5/32.png) [@Matthew\_Williams](https://forum.ansible.com/u/Matthew_Williams)\
**Post date:** [March 30, 2012, 3:18pm UTC](https://forum.ansible.com/t/executable-playbooks/11382/6 "2012-03-30T15:18:54Z")

</div>

Syntax for the last option would be very simple:

tasks:

- include: git.yaml  
only\_if: $run\_git

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [March 30, 2012, 3:27pm UTC](https://forum.ansible.com/t/executable-playbooks/11382/7 "2012-03-30T15:27:26Z")

</div>

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’’

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [March 30, 2012, 3:36pm UTC](https://forum.ansible.com/t/executable-playbooks/11382/8 "2012-03-30T15:36:41Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![Matthew\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a3d4f5/32.png) [@Matthew\_Williams](https://forum.ansible.com/u/Matthew_Williams)\
**Post date:** [March 30, 2012, 3:48pm UTC](https://forum.ansible.com/t/executable-playbooks/11382/9 "2012-03-30T15:48:24Z")

</div>

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?
