Main module execution¶
At this point in the module’s development, the module is largely complete. In this section, we’ll
cover one of the boilerplate methods that ships with all the modules; the
It is not necessary that you implement this function. We cover it here so that you are able to combine the knowledge of how the module executes, with where its execution actually begins.
The main function¶
In the module used for this tutorial, the
main function is defined at the bottom of the
The implementation of it is almost entirely boilerplate. Here it is.
def main(): spec = ArgumentSpec() module = AnsibleModule( argument_spec=spec.argument_spec, supports_check_mode=spec.supports_check_mode ) if not HAS_F5SDK: module.fail_json(msg="The python f5-sdk module is required") try: client = F5Client(**module.params) mm = ModuleManager(module=module, client=client) results = mm.exec_module() cleanup_tokens(client) module.exit_json(**results) except F5ModuleError as ex: cleanup_tokens(client) module.fail_json(msg=str(ex))
The operation of this function is as follows.
ArgumentSpec and the
AnsibleModule classes are initialized. You have seen both
of these in the past, so you should know their purpose.
ArgumentSpecdefines what the module can do
ArgumentSpecto validate user input
Next, a series of validations are made on the available libraries used in this module. The series above only includes one check, but others can be added as necessary. See the section later in this document that discusses under what circumstances you would want to do this.
Next is the main
try...except block. This exception handling is in place to catch all of the
known F5 generated errors. It very specifically does not catch the general Python
class. This is done this way because module developers want bugs reported that are not known to
them already. Handling
Exception though, would prevent those bugs from raising.
The internals of the
try block include the instantiation of the
F5Client object. This
object will be used later for all communication with the F5 product.
F5Client class is instantiated, a connection is not immediately made to the
remote F5 product. This is intentional, because some modules (like
bigip_wait) require that this does not
ModuleManager class is also instantiated here and is given the
as well as the
F5Client object. These will be necessary later when the manager is busy
Execution of the manager is next using the
exec_module method call. The return value of this
call is what will be returned to the user.
Before that return can take place, however, a function is called to clean up the authentication tokens on the F5 device.
cleanup_tokens method is not put in the
ModuleManager because the manager
can fail in a variety of places due to
F5ModuleException’s being raised by error checking
code. This function must be run after manager execution.
Finally, the module cleanly exits with the
exit_json method if everything has gone well.
If failure occurred at any time, the
except block is invoked and a cleanup of authentication
tokens is done. The failing module reports back to Ansible with the
fail_json method of
When to change the main function¶
The only time it would be necessary to change the
main function is if you included other
module dependencies that needed to be checked for at runtime.
Note the two lines above, shown here.
if not HAS_F5SDK: module.fail_json(msg="The python f5-sdk module is required")
This series of conditionals would need to be changed if you were, for example, to include the
netaddr module in your work. Any dependencies of the module need to be checked for here
(and fail the module if they are not found) to ensure that the module runs correctly.
The final two lines in your module inform Python to execute the module’s code if the script itself is executable.
if __name__ == '__main__': main()
Because of how Ansible works, when the
main function contacts the remote device (or runs
locally), it is not called if you import the module.
You would import the module if you were using it outside of Ansible, or in some sort of test environment where you do not want the module to actually run.
This concludes the entirety of the core module development tutorial. If you followed along and copied code correctly, you should have a functioning module.
In the remaining sections, we’ll cover the business of testing: a requirement for F5 module development.