Importing custom python library from ansible custom module

Hello all,

Is there a way to import a custom python library from an ansible custom module?

I am trying to create a custom module and need a specific python library. I have put my inifile.py file in the library folder of my playbook. My ansible custom module is in the same folder. However, when using the import command (from inifile import IniFile) in the custom module, it cannot find the pyhton library:

invalid output was: Traceback (most recent call last):
File “/home/olivier/.ansible/tmp/ansible-tmp-1437029018.2-53200658786921/file_ini_correct_options”, line 92, in
from inifile import IniFile
ImportError: No module named inifile

Any way to do that?

Regards,
Olivier

In a previous life I’ve had to do what you are attempting. Ansible will not automatically know to install dependencies like your custom library for you.That is up to you to handle. There are two ways I’ve gone about it resolving this:

  1. Install said libraries in your default python library path on each remote box.

  2. Copy/install your libraries to an alternate path location (could be one time could be an earlier task of the play) and use the environment argument on the task that uses your custom module to append said library path to PYTHONPATH.

Not knowing what is in your infile.py, you may want to consider embedding that library in the module if it’s a single library file that’s not too complex. I didn’t personally use this approach, though I considered it, in my own because the library files had other usage outside of my custom Ansible module and I didn’t want to play around keeping the code in sync.

Hope that helps.

Hi,

I didn’t give up at all. Far from it! I started working for Ansible.

Last I spoke to my former co-workers they are still using options 2 that I setup because they do not have the ability to install python libraries in the default library path.

Hi Tim,

Thank you very much for the update. It helps a lot, thank you very much. Indeed, I have chosen your second option as it is easier to maintain and avoid any conflict with other systems. The inifile.py is too big to be included in the custom module but I would not do this as I wouldn’t be able to re-utilise it.

Here is how I did it:

In my playbook or role:

tasks:

  • name: Upload python module
    copy: src=library/inifile.py dest=/tmp/inifile.py

In my custom module:

import sys
sys.path.append(‘/tmp’)
from inifile import IniFile

And to answer your question, what I am trying to achieve here is an extension to the ini_file module in Ansible. The current module doesn’t answer my needs such as:

  • setting easily a continious list of options such as:
  • whitelist.0 = item1
  • whitelist.1 = item2
  • whitelist.2 = item3- checking and replacing a list of options (such as [“ower”, “owne”]) by one option name (“owner”)
  • Dealing with options that doesn’t have section (generally mean that this is default to all sections)
  • Dealing with empty name section () and comments - this one I am less sure about but I know that the ConfigParser cannot handle this.

Thank you again for your precious help.

Regards,

Olivier

I’m glad you were able to work something out and I was helpful. A couple of quick added thoughts on this.

I wouldn’t recommend just dropping your library in to just /tmp to avoid a potential conflict with another job or process. Perhaps create a separate directory like the name of your project or playbook under tmp and store it there? I think create a specific directory helps avoid this.

I also wouldn’t recommend embedding a library path in your custom module for maintainability. It’s working for you now, but the thought of having to have that path line up in two different places make me uneasy. I used the environment arg and appended the path to our libraries to PYTHONPATH. Everything is in one place: the playbook. A var to hold the path (you can use Ansible facts to really create a unique path that won’t get tread on), the path create, the copy, the environment setting. Change it in one place and the change probates thru.

Just some food for thought.

Hi Tim,

Very good point. I will definitely change it accordingly. Thank you again.

Regards,
Olivier

Yes, using bare /tmp is also a security risk (as anyone with access to the machine can put something in /tmp. Imagine if someone puts their own version of os.py in there, for instance). A subdirectory with proper mode bits set works. A subdirectory in a non-world-writable location is even better.

-Toshio