I've been doing some experimenting to figure out the exact nature of
the include syntax. Here's something that surprised me (because I was
wrong about what I assumed it was going to do):
- include: tasks/java-app.yaml
tags:
- update
- rollbounce
I assumed that syntax would associate the update and rollbounce tags
with the include statement, the same way it does with action type
tasks. I guess the syntax is slightly different for include
statements. The correct syntax is include: tasks/java-app.yaml
tags=update,rollbounce
When I saw the "include: $file $tags" syntax initially my hopes were
that something like the following would work:
- include: tasks/java-app.yaml tags=stop
tags: [update,rollbounce]
- include: tasks/puppet.yaml tags=run
tags: update
- include: tasks/java-app.yaml tags=start
tags: [update,rollbounce]
$ ansible-playbook services/production/java-app.yaml --tags=rollbounce
Expected (wishful) behavior:
The include's tagged with rollbounce are selected for evaluation.
Those are the first and last in this case. When the include is
evaluated "tasks/java-app.yaml tags=stop" would include the
java-app.yaml file and select all tasks tagged 'stop' for evaluation.
Likewise, "tasks/java-app.yaml tags=run" would run the necessary
start-up commands.
$ ansible-playbook services/production/java-app.yaml --tags=update
Expected (wishful) behavior:
All three includes are selected for evaluation. When each is evaluated
the only the tags they specify (or set globally) will be selected.
$ ansible-playbook services/production/java-app.yaml
Expected (wishful) behavior:
Same as --tags=update. Because no tags are selected in the 'top level'
all three include statements are selected for evaluation.
Why would I want this behavior? It lets let me group my tasks in a way
that lets me very succinctly express my goals in a play. I have a lot
of clusters with very similar release processes, so this would mean
much greater code reuse potential. And it would work without having to
break the tasks files into dozens of more little files. All the tasks
related to similar actions can be stored together and subsets from
each yaml file are selected to be ran when the file is imported.
I've assembled a playbook collection that has the *theoretical*
required functionality to handle releases on my primary JBoss web
application clusters. It was designed with supporting releases in
multiple data centers (not at the same time) in mind. The playbooks in
the java directory have two run modes: tags=update and
tags=rollbounce. No tags means an update run is executed.
With a little tweaking and maybe a wrapper script for setting the
hosts parameter, I could consolidate the three into one single
playbook to and manage my qa servers in the phx1 datacenter, and the
stage/prod servers in my phx2 DS from the same playbook.
The only problem right now is how I originally misinterpreted the
behavior of the include statement (and hopefully nothing else!).
I'll probably try to write a patch which provides the described
functionality in some way (if there are no objections). I'm really
keen on how it works out for organizing files and the expressive power
it gives me in playbooks. It's like a much simpler version of the
nasty hack that I'd be required to write if I was trying to implement
all of this with 'only_if'. Though I'm not sure include statements
currently support only_if anyway.
Here's the playbook collection if anybody would like to take a look at it: