Developing Ansible Strategy Modules — Example, Review | by ChungEun Choi | Oct, 2024

In this post, I will explain how to control an Ansible playbook using a custom strategy module, implemented with FastAPI, and share the results of applying it to dev environment. Additionally, I will discuss the limitations of the strategy module and how I plan to improve it moving forward.

The playbook used in the example includes a pause (Ansible action). At this point, we will test control by using the custom strategy module to issue Pause or Stop commands.

The example playbook performs the following tasks:

Steps to Execute the Example Application

1. Run the Example Application via Quick Star
To execute the example application, please refer to the README.md in the following repository: Quick start — Project and Guide Link

2. Invoke the /playbook/run Endpoint with the Following Parameters
We use Swagger UI to easily call endpoints. You can access it at localhost:8080/docs.

The following request will be used to specify the locations of the playbook and inventory for the Ansible playbook execution:

{
"playbook": [
"./example/playbook/playbook.yml"
],
"inventory": "./example/playbook/inventory.ini",
"passwords": {}
}

3. Check Response Data and Ansible Output
The response will contain message, result, and executor_id. The key value to focus on is the executor_id, which will be used to control the playbook execution in next steps.

The Ansible execution output is written to the file ./ansible_results.log, where you can find details of the operation.

4. Request /playbook/pause/{executor_id}
Use the executor_id to pause the playbook execution by calling this endpoint.

When the pause action is triggered, the output log will show that the playbook has paused after the task Sleep for 30 seconds.

Upon restarting, the playbook will resume from the next task.

5. Request /playbook/pause/{executor_id}
Stopping the playbook will print a message and provide additional task results.

Benefits after Implementation

The biggest advantage is that we were able to control the complex workflows (Playbook) we needed in a variety of ways. The variety in flow control here refers to providing an API using Python objects, which allowed us to collaborate with web developers and develop a GUI-based service, significantly improving the convenience for users of the platform.

Compared to the previous control structure, much more granular task control became possible. For example, previously we could only control 12 plays, but now we can control up to 198 tasks. Additionally, we were able to collect new data generated by the users. This new data includes details like the time the action was executed and the task that was the target of the action.

With this data, users can now receive audit logs of executions, and they can plan and expand on additional business logic for certain actions (e.g., skipping the current task and executing the next one).

Drawbacks after Implementation

Limitation 1: Ongoing Maintenance

The custom strategy module is not included in the standard Ansible project. This means that our team has to manage it directly, and we need to continuously monitor changes in Ansible-core, specifically the StrategyBase class and the LinearStrategyModule. This could lead to ongoing maintenance costs.

Limitation 2: Enforced Microservices Architecture
As mentioned earlier, the original platform was developed based on Go. This platform included various features (such as deployment node management) and the execution of infrastructure deployment (via Ansible-playbook commands). To achieve finer control, this functionality had to be separated into a Python-based service.

This separation introduced a new challenge — how to efficiently integrate the divided services in a seamless manner.