How to Create Custom Ansible Wildfly Module – Part 1

Sharing is caring!

Introduction

As promised, I will bring the topic about creating ansible module for Wildfly management. Let’s call it Ansible Wildfly module. Take a note here, this is not about installing Wildfly on the target machine.

Wildfly is one of the most popular Java EE application server, and it is free and open source software. More about Wildfly, please visit their website.

Since I intend to make four custom Ansible modules for Wildfly management, then I will try to split into, unsurprisingly, four parts. In this part, I will cover only how to create and maintain Wildfly Server Group.

Server Group

A server group is set of server instances that will be managed and configured as one.¹

Wildfly itself has two different modes, which are standalone and domain mode. Yet server group only works in domain mode.

There are three ways, as far as I know, for maintaining server group.

  1. Configuration in domain.xml file. This way can be automated via Ansible, but too much pain
  2. Web management console. This is great for user to administer, but almost zero possibility if we want to automate.
  3. JBoss command-line-interface (CLI) as administration tools. This is a very suitable candidate for Ansible scripting.
Cheat Sheet

This how-to is running on Python 2.7, JDK 8, Wildfly 10.0.0 and using JBoss CLI management guide from this link.

Here is the syntax to execute jboss-cli in shell and we will translate it into python program.

Use Case

I want to automate Wildfly Server Group management using Ansible. So here is what the plugin should do:

  1. Create server group
  2. Start server group
  3. Stop server group
  4. Remove server group

Of course you can use Ansible built-in modules for managing the server group, which are shell and command module. However, my opinion would say the playbook is going to be clumsy, because you have to register output here and there. So, here are the steps!

Step by Step

Step 1 – Workspace Structure

Create file jcli_servergroup.py under library folder. If you are wondering why I put the file under library folder, please refer to previous post about folder structure. Then import ansible module utils and subprocess module.

Note: subprocess module is required for executing shell command

Step 2 – Create Function to Check Server Group Existence

This function will check if server group with specific name has already been created. If we want to execute from the shell, the syntax would be:

This syntax will return error code WFLYCTL0216 if the server group with the given name does not exist. Therefore we will use this error code in order to determine its existence.

Next is python part. First, write function isServerGroupAlreadyCreated then pass the cli command into python subprocess module.

Note:

  1. We have six dictionary keys, which are jboss_home, server_group_name, controller_host, controller_port, user and password. These keys will be defined in the main method.
  2. Whenever the result contains WFLYCTL0216, it is assumed that the server group with given name already created.
  3. Whenever the result contains WFLYPRT0053, it is assumed that the remote host cannot be reached.
Step 3 – Create Server Group

Now it is time to create server group. The syntax in the shell terminal would be:

And the now python part. Create new function and named it server_group_present and translate previous command into python code.

Note:

  1. We have additional dictionary keys, which are server_group_profile and socket_binding_group.
  2. The function first checks if the server group with the given name has already created. If it does, then nothing is created and set the hasChanged flag into False. Otherwise, it will create a server group then set the hasChanged into True.
  3. The same function is checking whether the domain controller existence. If not exist then the function will return an error.
Step 4 – Remove Server Group

If you have create functionality, of course it would make sense to have the opposite functionality, which is remove function. And the syntax for removing server group in the shell is:

Then map the command into python function, and named it server_group_absent.

Notes:

  1. There is no additional dictionary key for this function.
  2. The function checks whether the server group with the given name has already created. If it does, then delete the server group and change the hasChanged state into True. Otherwise, nothing is executed and change the hasChanged state into False.
  3. The same function is checking whether the domain controller existence. If not exist then the function will return an error.
Step 5 – Start and Stop Server Group

For starting and stopping server group, the steps are similar with previous step. So, create two python functions, server_group_start and server_group_stop.

Note:

  1. Both functions have no additional dictionary key
  2. As same as the other functions, before executing jboss-cli command they check the server availability and has already created or not.
Step 6 – Define Main Function

In the main function, we collect all the dictionary keys that has been used in the previous steps. We have already eight keys. Those keys will be used as an argument specification in AnsibleModule instance.

In addition, we need to define state for this Ansible Wildfly module. If you look at the use case, we need four states. So here are the states:

  • present: server group is created
  • absent: server group is removed
  • start: start server group
  • stop: stop server group

Now we are ready to define the main function:

Step 7 – Finalized the jcli_servergroup.py

The last step for jcli_servergroup.py is to tell python what is the main method.

Step 8 – play.yml

After defining all those functions, we are ready to execute the playbook.

Just make sure you have Wildfly up and running in domain mode. Then run the playbook by typing executing ansible playbook command.

After executing that statement, you will get similar outputs:

ansible
Ansible Playbook
Wildfly Management Console
Wildfly Management Console

Conclusion

That’s it. Now you can automate Wildfly server group management by using ansible playbook. The next blog, to manage server creation in Wildfly. Hopefully, I can post it sooner than later. Any question or feedback, I’ll see you in comment.

Author: ru rocker

I have been a professional software developer since 2004. Java, Python, NodeJS, and Go-lang are my favorite programming languages. I also have an interest in DevOps. I hold professional certifications: SCJP, SCWCD, PSM 1, AWS Solution Architect Associate, and AWS Solution Architect Professional.

4 thoughts on “How to Create Custom Ansible Wildfly Module – Part 1”

  1. I tried to reproduce what you indicate in the step by step, but it gives me the following error … I am new in python 🙁 ,
    sorry
    appreciate your help!!!

    TASK [Server group] **********************************************************************************************************************************
    task path: /root/poc02/play.yml:4
    The full traceback is:
    Traceback (most recent call last):
    File “/usr/lib/python2.7/dist-packages/ansible/executor/task_executor.py”, line 138, in run
    res = self._execute()
    File “/usr/lib/python2.7/dist-packages/ansible/executor/task_executor.py”, line 558, in _execute
    result = self._handler.run(task_vars=variables)
    File “/usr/lib/python2.7/dist-packages/ansible/plugins/action/normal.py”, line 46, in run
    result = merge_hash(result, self._execute_module(task_vars=task_vars, wrap_async=wrap_async))
    File “/usr/lib/python2.7/dist-packages/ansible/plugins/action/__init__.py”, line 694, in _execute_module
    (module_style, shebang, module_data, module_path) = self._configure_module(module_name=module_name, module_args=module_args, task_vars=task_vars)
    File “/usr/lib/python2.7/dist-packages/ansible/plugins/action/__init__.py”, line 165, in _configure_module
    environment=final_environment)
    File “/usr/lib/python2.7/dist-packages/ansible/executor/module_common.py”, line 910, in modify_module
    environment=environment)
    File “/usr/lib/python2.7/dist-packages/ansible/executor/module_common.py”, line 702, in _find_module_utils
    recursive_finder(module_name, b_module_data, py_module_names, py_module_cache, zf)
    File “/usr/lib/python2.7/dist-packages/ansible/executor/module_common.py”, line 467, in recursive_finder
    tree = ast.parse(data)
    File “/usr/lib/python2.7/ast.py”, line 37, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
    File “”, line 8
        cmd = data[‘jboss_home’] + ‘/bin/jboss-cli.sh’
    ^
    SyntaxError: invalid syntax

    fatal: [wildfly01]: FAILED! => {
    “msg”: “Unexpected failure during module execution.”,
    “stdout”: “”
    }
    to retry, use: –limit @/root/poc02/play.retry

  2. Hi 🙂
    Thanks a lot for the good work and explainations 🙂
    I’m starting with python with that.

    I begin working on it and add some user cases.
    For example for server-creation i adds system-properties and jvm heap-sizes features to fill my needs.
    I want to check in ‘present’ that definitions are the same than thoses defined in yml file, but work still in progress.

    Please let me know if you want I send it to you 🙂
    Regards,
    Cédric

Leave a Reply

Your email address will not be published. Required fields are marked *