# Feature: User-defined modules as yaml task lists?

**URL:** <https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248>\
**Category:** Ansible Project\
**Created:** [January 13, 2015, 1:58pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248 "2015-01-13T13:58:59Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jang](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@jang](https://forum.ansible.com/u/jang)\
**Post date:** [January 13, 2015, 1:58pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/1 "2015-01-13T13:58:59Z")

</div>

Writing my own modules in, say, Python feels like overkill. I can't find a  
feature at the moment that would let me give a name to a yaml file  
(containing task definitions) and then invoke that name as though it were  
any other module.

Is anything like this already possible? Is it on a roadmap? (Would patches  
to do this be accepted?)

Cheers,  
jan

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [January 13, 2015, 2:05pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/2 "2015-01-13T14:05:56Z")

</div>

I'm not sure I'm reading this right, would you just want?:

- include: tasklist.yml

---

<div class="post-metadata">

**Author:** ![jang](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@jang](https://forum.ansible.com/u/jang)\
**Post date:** [January 13, 2015, 2:12pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/3 "2015-01-13T14:12:59Z")

</div>

The problem's when it's:

- include: ../../common/tasks/tasklist.yml param1=...

which is klunky to read, error-prone to write, and makes refactoring the  
common tasks tricky (particularly if the common tasks and their consumers  
live in separately-gated repositories).

As far as I can tell\* ansible avoids having sprawling search paths for  
task includes (presumably so that it's easy to tell what's going on  
without too much external context); but used judiciously, something like  
this would let me introduce a smidgen of useful abstraction into my  
playbooks.

\* if that's not right, please correct me!

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [January 13, 2015, 2:14pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/4 "2015-01-13T14:14:54Z")

</div>

then use roles, they offer a bit more than simple task lists but you  
can set the search paths.

---

<div class="post-metadata">

**Author:** ![jang](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@jang](https://forum.ansible.com/u/jang)\
**Post date:** [January 13, 2015, 2:18pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/5 "2015-01-13T14:18:59Z")

</div>

Are you saying that if I have a "common" role with a "tasks/do-foo.yml"  
and some other role that has

- include: do-foo.yml

it'll DTRT? I couldn't make that work in testing.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [January 13, 2015, 2:20pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/6 "2015-01-13T14:20:29Z")

</div>

no, you need to use role dependencies for that case

[http://docs.ansible.com/playbooks\_roles.html#role-dependencies](http://docs.ansible.com/playbooks_roles.html#role-dependencies)

---

<div class="post-metadata">

**Author:** ![jang](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@jang](https://forum.ansible.com/u/jang)\
**Post date:** [January 13, 2015, 2:27pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/7 "2015-01-13T14:27:01Z")

</div>

Ah. But tasks for role dependencies are all fired off in advance, right?

I'm talking about having a common "subroutine" task, commonly provided  
through a central point, that can be called like any other module might be  
called, from an arbitrary point within a playbook.

(The point of this is to provide some abstraction, so that client  
playbooks can be written in terms of higher-level operations than the  
concrete modules typically provided. Is that just a misplaced desire to  
"do ansible wrong"? 🙂 )

---

<div class="post-metadata">

**Author:** ![Tom\_Bamford](https://avatars.discourse-cdn.com/v4/letter/t/c2a13f/32.png) [@Tom\_Bamford](https://forum.ansible.com/u/Tom_Bamford)\
**Post date:** [January 13, 2015, 6:25pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/8 "2015-01-13T18:25:53Z")

</div>

If you want greater control of when your common tasks get executed, I would be more inclined to use rules and have verbose playbooks with the execution order explicitly specified.

Perhaps if you could give a better idea of what your common tasks are and the context in which you want to run them?

Regards  
Tom

---

<div class="post-metadata">

**Author:** ![jang](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@jang](https://forum.ansible.com/u/jang)\
**Post date:** [January 14, 2015, 11:37am UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/9 "2015-01-14T11:37:42Z")

</div>

The common tasks involve configuring containers (it doesn't matter what  
kind of container; that's liable to change) then installing software  
elements into it and registering services.

However, to pick a simpler, concrete example, let's say I've a playbook  
that needs to install a package, foo.

I want to use this playbook against both apt and yum-based systems; and  
possibly against systems that use other packaging mechanisms in the  
future.

[[[  
- apt: name=foo  
&nbsp;&nbsp;when: system == 'apt'

- yum: name=foo  
&nbsp;&nbsp;when: system == 'yum'  
]]]

Do I really need to repeat this logic everywhere I might want to install a  
package? What I'm after is the ability to write:

- package: name=foo

and centralise the code that picks a concrete implementation.

Is there already a way to express this simple kind of abstraction in  
ansible? I know I can do something like

- include: ../../common/tasks/install-package.yml name=foo

but writing this is klunky and error-prone; I'm just wondering if there  
are neater ways to achieve this - so that playbooks can separate the  
"what" and the "how".

Cheers,  
jan

---

<div class="post-metadata">

**Author:** ![Tom\_Bamford](https://avatars.discourse-cdn.com/v4/letter/t/c2a13f/32.png) [@Tom\_Bamford](https://forum.ansible.com/u/Tom_Bamford)\
**Post date:** [January 14, 2015, 8:05pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/10 "2015-01-14T20:05:05Z")

</div>

Hi Jan

In terms of unified package management, I believe this is a direction that the Ansible project decided not to go in. I think the cleanest way from a playbook perspective would be to write your own module. But think about how much this might involve, noting that apt, yum, pacman et al don’t have interchangeable functionality - yes there are some commonalities but are really very different. That’s not including other package managers (thinking of npm, pip, rubygems etc). Also, package naming and what you do with a package after installing it varies greatly depending on distro, and by association, package manager.

For the above, citing:  
[https://groups.google.com/d/msg/ansible-project/x2\_9PzAJXNE/ZwcBv02oAhkJ](https://groups.google.com/d/msg/ansible-project/x2_9PzAJXNE/ZwcBv02oAhkJ)

[https://groups.google.com/d/msg/ansible-project/RxoxVVFdLhI/fNUYnH\_sm-cJ](https://groups.google.com/d/msg/ansible-project/RxoxVVFdLhI/fNUYnH_sm-cJ)

[https://github.com/ansible/ansible/issues/4261](https://github.com/ansible/ansible/issues/4261)

I like to keep OS dependant tasks either in separate task files, or separate roles depending on the complexity. I don’t believe in this case that some duplication is a bad thing.

Hope this helps.

Tom

---

<div class="post-metadata">

**Author:** ![Matthew\_Macdonald-Wa](https://avatars.discourse-cdn.com/v4/letter/m/f1d935/32.png) [@Matthew\_Macdonald-Wa](https://forum.ansible.com/u/Matthew_Macdonald-Wa)\
**Post date:** [January 15, 2015, 12:55pm UTC](https://forum.ansible.com/t/feature-user-defined-modules-as-yaml-task-lists/17248/11 "2015-01-15T12:55:29Z")

</div>

Hi Jan 🙂

FWIW, we’re just adding

- include: debian.yml  
when: ansible\_distribution == ‘Debian’ or ansible\_distribution == ‘Ubuntu’

- include: rhel.yml  
when: ansible\_distribution == ‘CentOS’ or ansible\_distribution == ‘Red Hat Enterprise Linux’

To the top of each role. Debian/Ubuntu specific stuff (because config files are in different locations as well as package names being different) goes in the debian.yml file and CentOS/RHEL stuff goes in rhel.yml

Anything that is common to both (tagging for monitoring etc.) is in “main.yml” after the above include statements.

I realise its not exactly what you’re after but it might help?

Cheers,

Matt
