this module requires key=value arguments (['<<INCLUDE_ANSIBLE_MODULE_ARGS>>'])

Dear *,

trying to create a new plugin. It’s gonna be a variation of the lineinfile module, so I copied the code from there and placed it into my local action plugins folder, as configured in my ansible.cfg

I didn’t change anything yet, it is the original lineinfile.py so I’d expect the same behavior. Though instead I get an error I don’t understand:

TASK: [calling testmodule] ****************************************************************** {"msg": "this module requires key=value arguments (['<<INCLUDE_ANSIBLE_MODULE_ARGS>>'])", "failed": true}

This error happens when the AnsibleModule class is initiated. Obviously the replacement is not happening.

This is my task, which triggers my test module.

`

  • name: calling testmodule
    testmodule: dest=“some-file” line=“some-line”
    `

The module gets called. A debug message at the beginning of the main() method gets shown on the command line when executed.

There is nothing wrong with the params definition. When I replace my “testmodule” with the original “lineinfile” it instantly works.

This is Ansible 1.8.2 but I tested it with other version too, down to 1.6.5 and I get the same error.

Why is Ansible failing to replace the INCLUDE_ANSIBLE_MODULE_ARGS? What am I missing, how to fix it?

Thanks,
Daniel

I tried to reproduce this issue but it worked just fine for me:

1. Copy modules/files/lineinfile.py to modules/files/testmodule.py
2. Replace all occurrences of "lineinfile" with "testmodule" in
testmodule.py
3. Run playbook

$ ansible-playbook testmodule.yml
PLAY [test line in file]

Thanks for looking into it Giovanni.

My py file really is just a copy of the original with the replaced name in the DOCUMENTATION / EXAMPLES sections but I think that wouldn’t matter. I created a gist here, which includes all other things involved too: https://gist.github.com/udondan/527c493cf19a370c9c01

Cheers,
Daniel

With oc_lineinfile.py I get an error, but not the same as you (tested on
1.8.2 and devel):

TASK: [calling testmodule]

Any modifications to Ansible core files?

Nope. I modified some files in the past to debug other problems but that all got reverted. To make sure I just deleted & re-installed Ansible through Homebrew (brew uninstall --force ansible && brew install ansible)

Btw, this is OS X 10.10.1 here and Python is 2.7.9.

Cheers,
Daniel

Giovanni,

may I ask how you integrated the plugin? That’s the key to reproduce the problem, as I just figured out.

Plugins which are placed in a plugin directory inside a role, run just fine. The problem occurs when the plugin is inside the plugins directory which was defined in the ansible.cfg @ action_plugins.

I created a reproducible example. I tested this on 3 different systems with different operating systems and got the same result everywhere. Tested on:

  • OS X 10.10.1 with Python 2.7.9
  • CentOS 7 with Python 2.7.5
  • Debian 7.5 with Python 2.7.3

You’ll find the code on Github: https://github.com/udondan/ansible_plugin_issue

Clone it:

$ git clone https://github.com/udondan/ansible_plugin_issue

Run it:

`
$ cd ansible_plugin_issue
$ ansible-playbook -i inventory.conf test.yml

PLAY [Testing plugins] ********************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [testrole | Run plugin A] ***********************************************
changed: [localhost]

TASK: [testrole | Run plugin B] ***********************************************
DEBUG: module called!
{“msg”: “this module requires key=value arguments ([‘<<INCLUDE_ANSIBLE_MODULE_ARGS>>’])”, “failed”: true}
`

The plugin file itself is at /the-plugin.py
There are two symlinks, one below the “testrole” as plugin_A, one below plugins/action as plugin_B. plugin_A runs just fine, plugin_B fails with the known error message. Since the plugins are symlinks, there’s no doubt they are identical. But just to make this clear, the problem is not caused because they are symlinks. I of course tested this with real files and also changed the module name in the documentation section, which really does not make any difference.

It appears to me like a general bug since I can reproduce it on various systems. Just wondering why nobody experienced this before. It’s not even a new problem, since I tested this back until Ansible 1.6.5.

Can you (or just anybody) confirm this works or not for you?

Cheers,
Daniel

action plugins are not the same as modules. You want to place your module in the location of ‘library’ instead of ‘action_plugins’.

Move ‘plugins/action’ to ‘library’ and you will see this start working.

There are a few implicit locations where ‘library’ is looked for, such as placing a directory named ‘library’ at the same level as your playbook, and placing the file inside of there. As you have determined, this also works in roles, since you have ‘plugin_A.py’ in a library directory in the root of your role.

Thanks Mark!

I think the source of my confusion is the documentation here. Can someone explain what exactly is the difference between a module and a plugin (especially an action plugin)? According to the docs, modules are reusable units of magic, which is not very helpful. :wink: Only in the Glossary I now found a description. Action plugins are completely missing in the docs, both in the Glossary and on the Developing Plugins page. I only learned about action plugins by discovering the action_plugins setting in the config and trial and error…

I also created several action plugins before which I don’t see how they work any different than the lineinfile module. (Apart from that you can use the AnsibleModule class in one and not in the other) Is it that plugins run locally and modules remotely?

Thanks,
Daniel

Mark? I meant Matt. Sorry! Let’s say it was autocorrection!