# action\_plugin/ vs library/ module

**URL:** <https://forum.ansible.com/t/action-plugin-vs-library-module/20307>\
**Category:** Ansible Project\
**Created:** [January 21, 2016, 11:00pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307 "2016-01-21T23:00:35Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 21, 2016, 11:00pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/1 "2016-01-21T23:00:35Z")

</div>

So, what’s the deal with action\_plugins? There is very little documentation on their purpose.

Observations:

1. If action\_plugin/foo.py and library/foo.py both exist, then only action\_plugin/foo.py gets called (the plugin _may_ call the module if it wants, but that is not by default).
2. If library/foo.py exists, but there is no corresponding action\_plugin, the library is called.
3. If action\_plugin/foo.py exists, but there is no corresponding module, then Ansible throws a syntax error.
4. If action\_plugin/foo.py exists, and the library is empty (literally created with ‘touch library/foo.py’), then the action\_plugin is called and everything works.
5. _some_times, but no always, the action\_plugin does some preliminary work with data that is not available to the library or the option plugin modifies the results.

For #5, I can understand a solid use case. If a vendor supplies a module and you want to use it, but would prefer to have the data returned differently (or strip out data or whatever) but don’t want to modify the vendor’s module, then this makes a lot of sense as a module wrapper.

I need to write a module and can’t decide if I should write a standard library module or if I should write an action\_plugin with a blank library module (I suppose just to use for documentation, though that seems odd).

any clarification would help.

---

<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 22, 2016, 4:08am UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/2 "2016-01-22T04:08:49Z")

</div>

99% of the time you want a module, action plugins normally are created  
when you need to do work on the 'master' machine.

---

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [January 22, 2016, 8:40am UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/3 "2016-01-22T08:40:11Z")

</div>

Taking a step back, what problem are you trying to solve?

Depending on what you are trying to do, you might be able to solve the problem using the existing modules working together in a (re-usable) role.

Jon

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 22, 2016, 2:28pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/4 "2016-01-22T14:28:37Z")

</div>

I’m trying to get Ansible to open a ticket in our internal config management system.

I’m not new to modules, just thought that the action plugin looked more 2.0-ish.

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 22, 2016, 2:35pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/5 "2016-01-22T14:35:23Z")

</div>

I also notice that there seem to be a lot of action\_plugins for core modules.

It doesn’t look like modules have access to ansible **main** data (e.g. if --diff was passed on the cmdline). If I need that data, might I need an action\_plugin?

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 22, 2016, 6:13pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/6 "2016-01-22T18:13:23Z")

</div>

So, it looks like, in my case, I’ll want an action plugin since I don’t really need anything run on a remote machine and I’ll need access to the results of the playbook.

---

<div class="post-metadata">

**Author:** ![psprygada](https://avatars.discourse-cdn.com/v4/letter/p/898d66/32.png) [@psprygada](https://forum.ansible.com/u/psprygada)\
**Post date:** [January 22, 2016, 9:35pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/7 "2016-01-22T21:35:20Z")

</div>

From the sounds of it, developing a callback might be more appropriate.

[http://docs.ansible.com/ansible/developing\_plugins.html#callbacks](http://docs.ansible.com/ansible/developing_plugins.html#callbacks)

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 22, 2016, 11:44pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/8 "2016-01-22T23:44:01Z")

</div>

I actually started out to create a callback that triggered on change, but after some internal discussion, decided that I didn’t want it to fire after each task, but rather, wanted to run it one time in the beginning and once at the end, so I figured that calling it as a task would be more appropriate.

That said, one future enhancement will be to open the ticket at the beginning, then update it after each changed task, in which case, I plan to use module tasks to create and close the ticket and then use a callback\_plugin to update the ticket with results as they come in. Of course, if I’ve already written a module, I could set the updates to run as a handler task on change.

---

<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 23, 2016, 2:28am UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/9 "2016-01-23T02:28:29Z")

</div>

It still sounds like you want a callback, you can just implement the  
on\_start and on\_stat methods and ignore all the intermediate actions

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 23, 2016, 3:47am UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/10 "2016-01-23T03:47:53Z")

</div>

Perhaps. I’ll probably build both and see which feels better. I need to be able to set vars for the plugin/module to use that might be different for each playbook. The callback\_plugins have access to vars through the ‘invocation’ in res, right? I’ll also need access to all of the diffs, so I’ll need to capture and then reference them in on\_stat.

All other things being equal, this may come down to style and which playbook is easiest for people to understand and work with. Of course, most likely, in either case, my playbook would probably look something like this, no matter which option I choose:

`

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 26, 2016, 6:22pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/11 "2016-01-26T18:22:01Z")

</div>

Ok, so the problem I’m having in making this a callback is that I want to open a ticket on playbook start and close it on stats.

In order to open the ticket, I need certain information that will be specific to the playbook being run. The only way I can find to pass vars is through play\_vars, which are only available in v2\_playbook\_on\_play\_start through play.get\_vars().  
These vars are only those that are set in the play itself, which excludes vars defined in vars\_files (play.get\_vars\_files() returns a list of files which I would then need to read).

I feel like I’m missing something. Is there a better way that I can pass variables to a callback\_plugin?

The best I can find so far is to grab them from TaskResult[‘invocation’] **after** the first task is run (then keep track of the fact that I’ve already opened a ticket and not open a new one for every task).

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [January 27, 2016, 10:43pm UTC](https://forum.ansible.com/t/action-plugin-vs-library-module/20307/12 "2016-01-27T22:43:02Z")

</div>

IYI, my eventual solution involves creating a blank change-mgmt ticket with a callback\_plugin in init(). I then store the ticket number that is created in **main**.cli.ticket\_number.  
Then, the first pre-task of my playbook calls my action\_plugin to read the ticket\_number from **main**.cli and update the ticket with the actual data specific to the playbook that is being run.

I’m not sure I’m completely satisfied with this solution, but it does seem to work.
