VCF Automation Blog

from Stefan Schnell

Ansible is an automation and orchestration tool for configuration and administration. It offers command execution for software distribution and configuration management. Aria Automation offers an integration with Ansible in its infrastructure connections. In his great blog post about VCF Automation and Ansible Integration Dale Hassinger explains how to set up and connect Ansible. This blog post shows how to emulate an Ansible module in a development process of a local environment.

Ansible Module Emulation
for a Simplified Development


To develop an Ansible module, an Ansible installation is required. This makes the development process somewhat more complex. But with this tiny emulation of the AnsibleModule class we are able to develop and test independently of an Ansible installation. Of course, this does not replace a (final) test on an Ansible platform, but it does provide a first useful impression in an environment created with little effort.

The following source code is equivalent to the example in the Ansible documentation. The class for the emulation, with the minimum necessary methods, is delimited by comment lines. The constructor contains the parameters which are transferred to the Ansible module. The rest of the class code is a copy from the original.

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
@author Stefan Schnell <mail@stefan-schnell.de>
@license MIT
@version 0.2.0
"""

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

# from ansible.module_utils.basic import AnsibleModule

# Begin of the AnsibleModule simulation --------------------------------

import json
import sys

class AnsibleModule(object):

    def __init__(self, argument_spec, supports_check_mode=False):
        self.argument_spec = argument_spec
        self.supports_check_mode = supports_check_mode
        # Simulates check mode: ansible-playbook foo.yml --check
        # self.check_mode = True
        self.check_mode = False
        # Parameters that are passed to the module
        self.params = {
            "name": "Stefan",
            "new": True
        }

    def jsonify(self, data):
        return json.dumps(data)

    def _return_formatted(self, kwargs):
        print('\n%s' % self.jsonify(kwargs))

    def exit_json(self, **kwargs):
        self._return_formatted(kwargs)
        sys.exit(0)

    def fail_json(self, msg, **kwargs):
        kwargs['failed'] = True
        kwargs['msg'] = msg
        self._return_formatted(kwargs)
        sys.exit(1)

# End of AnsibleModule simulation --------------------------------------

def run_module():

    # Define parameters which can pass to the module
    module_args = dict(
        name = dict(type = 'str', required = True),
        new = dict(type = 'bool', required = False, default = False)
    )

    # Define the result dictionary
    result = dict(
        changed = False,
        original_message = '',
        message = ''
    )

    # The AnsibleModule object will be the abstraction working with Ansible
    module = AnsibleModule(
        argument_spec = module_args,
        supports_check_mode = True
    )

    # If the module is only in check mode, no changes are made in the
    # environment and it returns the current status with no modifications
    if module.check_mode and not module.supports_check_mode:
        module.exit_json(
            skipped = True,
            msg = "Module does not support check mode"
        )

    if not module.check_mode:

        # Manipulate or modify as needed, insert your code here
        result['original_message'] = module.params['name']
        result['message'] = 'goodbye'

        # Set changed if the module has made any modifications
        if module.params['new']:
            result['changed'] = True

    # If an exception occurs during the execution of a module
    if module.params['name'] == 'fail me':
        module.fail_json(msg = 'You requested this to fail', **result)

    # If the module execution was successful
    module.exit_json(**result)

def main():
    run_module()

# Main
if __name__ == '__main__':
    main()

The Ansible code is explained in detail in the documentation. A simple Python installation is required to run this code and no other packages are required.

Conclusion

As shown, an Ansible module can be executed without an Ansible platform with little effort. This gives us some freedom in development. Of course, this is not a substitute, but a valuable extension approach.