Just three days back, I thought about writing a SMS notification module and bingo, I was able to send a pull request, same day. I submitted a module named ‘plivo’ which allows sending SMS notification using Plivo services. The playbook examples are hosted here: https://github.com/rohit01/ansible-plivo-example.
Writing an Ansible module, is pretty much a straight forward approach. Though ansible modules can be written in any language, I will stick to Python in this post. In Python, a module is generally a single file with 3 different parts:
- Documentation: This usually takes up the most number of lines
- Logic: The real programming logic to perform the task
- Ansible framework: Ansible provides some really useful classes and functions to help you in this process
Ansible is designed to read two global variables and generate documentation. These are:
Documentation: A multiline string literal and a valid YAML document. It contains the detailed description of module we see using the command
ansible-doc <module_name>or at docs.ansible.com.
Examples: A multiline string literal and a valid YAML document. It demonstrates the sample usage of module.
Logic is the programatic way to perform the task. It uses various resources provided by Ansible. These resources may include the arguments passed to module, ssh connection to host, cloud resources such as AWS, GAE, and many more. Ansible will connect to the host only if logic requires the same. For example, a notification module does not connect to the host for sending SMS, email, etc.
Ansible modules usually import a bunch of utilities to perform its task. The basic utilities are generally imported by all modules using the following import statement:
from ansible.module_utils.basic import *
Lets write a simple module
Module to return a configurable string and control success status:
-- coding: utf-8 --
Author: Rohit Gupta - @rohit01 <email@example.com>
Sample ansible module to demonstrate code structure.
—- Documentation Start —————————————————-
DOCUMENTATION = '''
version_added: "1.7" module: echo short_description: echo description: - This module returns/displays a configured string options: name: description: text message to print success: description: If false, the module will exit with failure. required: false default: yes choices: [ "yes", "no" ] notes: - This module does not connect to host. It is a dummy module required: true requirements:  author: Rohit Gupta - @rohit01 '''
EXAMPLES = ''' - name: "echo" echo: name="I executed successfully" success=yes '''
—- Logic Start ————————————————————
def main(): # Note: 'AnsibleModule' is an Ansible utility imported below module = AnsibleModule( argument_spec=dict( name=dict(required=True), success = dict(default=True, type='bool'), ), supports_check_mode=True ) success = module.params['success'] text = module.params['name'] if success: module.exit_json(text=text) else: module.fail_json(msg=text)
—- Import Ansible Utilities (Ansible Framework) —————————
from ansible.module_utils.basic import * main()
And the examples to use this module is also simple:
- echo: name="Hello World!" - echo: name="Success is Yes" success=yes - echo: name="Success is No" success=no
Write your own module
Now that you know some basics, why not write something on your own. For more details on developing modules, I highly recommend the following:
- Check some real module related to the one you are writing. Ansible modules are hosted here
- Visit the Ansible documentation on developing modules
- Find Ansible utilities you may like to re-use. You can find them here
Share what you want to write and feedback in comments. And as always, Thanks for reading :-)