# ansible playlets/included plays?

**URL:** <https://forum.ansible.com/t/ansible-playlets-included-plays/12628>\
**Category:** Ansible Project\
**Created:** [April 4, 2013, 9:35pm UTC](https://forum.ansible.com/t/ansible-playlets-included-plays/12628 "2013-04-04T21:35:32Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Seth\_Vidal](https://avatars.discourse-cdn.com/v4/letter/s/7ba0ec/32.png) [@Seth\_Vidal](https://forum.ansible.com/u/Seth_Vidal)\
**Post date:** [April 4, 2013, 9:35pm UTC](https://forum.ansible.com/t/ansible-playlets-included-plays/12628/1 "2013-04-04T21:35:32Z")

</div>

What I want in ansible:

Essentially, it is a simple way to let me port a bunch of puppet  
modules directly to ansible.

right now I can include tasks - which is great  
and I can include handlers - which is great

Ideally, though, I want to just include a single line and 'boom' that  
playbook now does that new stuff. I want to deal with a set of tasks  
and handlers and files/templates and variables, potentially, as a blob  
that is 'finished'. So I can work on the blob, get it right, and not  
have to modify all my other playbooks to fit it in.

In a lot of cases the porting of these modules is easy enough with  
just included tasks - but the moment I need to do any special  
variables or handlers that doesn't work w/o touching ALL of my  
playbooks to include specific vars\_files or to include handlers.

So what I think I want is an included 'thing' that inherits from the  
current play. For the moment I've been calling it a playlet. It has  
tasks, variables, handlers all of its own which are local to that  
playlet in scope. It inherits the variables, handlers, and host-list  
from the play it is included in and the variables/vars\_files that it  
includes are overridden exactly like ones in a playbook - meaning  
group\_vars, host\_vars and extra\_vars override them. (by treating vars  
like that it would mean I could have sensible defaults in vars in a  
task list w/o having to do any weird checks elsehwhere)

basic structure of where a playlet fits:  
playbook  
&nbsp;&nbsp;- play1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- playlet1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- playlet2  
&nbsp;&nbsp;- play2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- playlet3  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- playlet1

Perhaps a playlet would have a directory structure something like  
playlet\_name/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars/vars.yml  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;files/myfile.conf  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myfile2.conf.j2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handlers/handlers.yml  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playlet.yml

so an example play inclusion would be like:

- name: my play with playlets  
&nbsp;&nbsp;hosts: myhosts  
&nbsp;&nbsp;playlets:  
&nbsp;&nbsp;- path/to/playlet\_name  
&nbsp;&nbsp;- path/to/playet\_name\_2

&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;- name: my task  
&nbsp;&nbsp;&nbsp;&nbsp;action: stuff which I do

Questions:

1. do playlets run before or after tasks in any given play?  
2. should there be some other way ordering them?  
3. is a playlet just a short hand for:  
&nbsp;&nbsp;&nbsp;&nbsp;- run this playbook - but override hosts with whatever this play  
has and force these vars/handlers into it? Is it bad to have this kind  
of short hand? Should we just allow a way to include playbooks like  
this and stuff a bunch of vars into them?  
4. can playlets include other playlets? (I'm inclined to say NO  
but....)  
5. what does running a playlet do to cwd for looking up files,  
etc?  
6. what does a playlet do with --tags?  
7. what does a playlet do with --step?

I hope this helps flesh out what I was looking for here and explain how  
I would like to use it. I've been looking at the playbook parsing code  
to see how to fit this in w/the smallest amount of pain and it seems  
like creating a new play and preloading the values from the existing  
play would work - but I'm not sure if this is a good way of going about  
it or if I should be looking at some sort of plugin that this would  
work as.

Thanks,  
-sv

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [April 5, 2013, 4:27pm UTC](https://forum.ansible.com/t/ansible-playlets-included-plays/12628/2 "2013-04-05T16:27:38Z")

</div>

I am currently favoring something like this:

hosts: webservers

tasks:

# optional and as usual

handers:

# optional and as usual

roles:

- common
- wordpress user=alice
- wordpress user=bob

When a role is found (in this case ‘common’), it would do 3 things:

look for ../roles/common or roles/common relative to playbook

if roles/common/vars/main.yml exists, add it to vars\_files

if roles/common/tasks/main.yml exists, add it to tasks as an include

if roles/common/handlers/main.yml exists, add it to tasks as an include

In the case of the wordpress example, the variables ‘user=alice’ would also be set automatically in vars, and passed to the task and handler.

This would be compatible with our ansible-examples repo idea of organizing based on roles and also allow us to improve them.

–Michael

This seems pretty easy to do in the main playbook.py code, I think, without too many modifications elsewhere in the stack.

If tasks and handlers were also specified loose, they would come into play _after_ the roles got applied (just have to pick before or after, so I’m picking after, but maybe before is better?)

–Michael

---

<div class="post-metadata">

**Author:** ![Seth\_Vidal](https://avatars.discourse-cdn.com/v4/letter/s/7ba0ec/32.png) [@Seth\_Vidal](https://forum.ansible.com/u/Seth_Vidal)\
**Post date:** [April 5, 2013, 4:39pm UTC](https://forum.ansible.com/t/ansible-playlets-included-plays/12628/3 "2013-04-05T16:39:39Z")

</div>

Structurally this sounds fine - I want to think for a sec what this  
means for folks looking to exchange these roles.

1. it'd be nice if it let me specify a path so my roles subdir doesn't  
need to be adjacent to my playbooks.

2. the dir structure if I am distributing a role as an example:

rolename/  
├── handlers  
│ └── main.yml  
├── tasks  
│ └── main.yml  
└── vars  
&nbsp;&nbsp;&nbsp;&nbsp;└── main.yml

Since in many cases these roles will need their own templates or config  
files would it make since to toss a files/ dir in there too - for  
relative files that can then be referred to relative to that dir? I  
know that makes the files specification tricky- but I'm thinking of  
the case where I want to take someone else's relatively-complicated  
role and port it into my own repo. If I have to modify every file  
specification to point to wherever my files are that's going to be  
pretty onerous and error-prone.

that's why when I originally brought up the idea of the playlets I  
wanted the files dir to be able to be relative to the rest of the  
playlet.

Do you see what I mean?

For more of an example:

let's say I'm deploying a web app in a role. (like wordpress)  
I need to deploy a wordpress-apache.conf file into /etc/httpd/conf.d/

so I have:

- name: put wordpress config into apache  
&nbsp;&nbsp;action: copy src=where?/wordpress/wordpress-apache.conf  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest=/etc/httpd/conf.d/wordpress-apache.conf

Finally - how do we deal with duplicate handler definitions here? How  
does ansible do that generally - if I two things named 'restart apache'?

thx

-sv

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [April 5, 2013, 4:51pm UTC](https://forum.ansible.com/t/ansible-playlets-included-plays/12628/4 "2013-04-05T16:51:05Z")

</div>

> Structurally this sounds fine - I want to think for a sec what this  
> means for folks looking to exchange these roles.
> 
> 1. it'd be nice if it let me specify a path so my roles subdir doesn't  
> need to be adjacent to my playbooks.
> 
> 2. the dir structure if I am distributing a role as an example:
> 
> rolename/  
> ├── handlers  
> │ └── main.yml  
> ├── tasks  
> │ └── main.yml  
> └── vars  
> &nbsp;&nbsp;&nbsp;&nbsp;└── main.yml

(And also templates & files, but yes, oh I see you say that later too!)

> Since in many cases these roles will need their own templates or config  
> files would it make since to toss a files/ dir in there too - for  
> relative files that can then be referred to relative to that dir? I  
> know that makes the files specification tricky- but I'm thinking of  
> the case where I want to take someone else's relatively-complicated  
> role and port it into my own repo. If I have to modify every file  
> specification to point to wherever my files are that's going to be  
> pretty onerous and error-prone.

I think it should indeed allow this. We have some "path\_dwim" functions  
in Ansible that should be made smart about this.

> Finally - how do we deal with duplicate handler definitions here? How  
> does ansible do that generally - if I two things named 'restart apache'?

Handlers are stored in hashes based on the name IIRC, so I believe they  
overwrite. I can check.

Which actually seems reasonable I think.

---

<div class="post-metadata">

**Author:** ![Seth\_Vidal](https://avatars.discourse-cdn.com/v4/letter/s/7ba0ec/32.png) [@Seth\_Vidal](https://forum.ansible.com/u/Seth_Vidal)\
**Post date:** [April 5, 2013, 8:54pm UTC](https://forum.ansible.com/t/ansible-playlets-included-plays/12628/5 "2013-04-05T20:54:42Z")

</div>

Those path functions would need to be pretty stunning to know how to  
find the files local to that task when the task is just included in the  
normal set of tasks.

If you think about the tree in the bestpractices doc we have it pretty  
similar but we have everything down one level for organization

ansible-repo  
&nbsp;&nbsp;&nbsp;&nbsp;playbooks  
&nbsp;&nbsp;&nbsp;&nbsp;files  
&nbsp;&nbsp;&nbsp;&nbsp;tasks  
&nbsp;&nbsp;&nbsp;&nbsp;roles/ \<--- then the role names under here

so if my playbook is:  
&nbsp;&nbsp;&nbsp;playbooks/hosts/somehost.yml  
&nbsp;&nbsp;&nbsp;and it is including the 'common' role

I have no idea how it will find those files/templates specific to  
'common'

However, if this is part of the bigger plan then that seems like a way  
forward for me.

-sv

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [April 5, 2013, 8:57pm UTC](https://forum.ansible.com/t/ansible-playlets-included-plays/12628/6 "2013-04-05T20:57:15Z")

</div>

I can possibly see roles taking a path versus knowing to look in roles/$name.

I’ll fiddle with it some.
