Back in 2015 we started using Ansible at Swapps. I created a small Django application that could interface with Ansible directly, and used that to manage our infrastructure at higher level.

Back then, Ansible was in version 1.9. Ansible is written in python, so I just used the modules and started the playbooks directly. However Ansible 2.0 came out, and all of the internal API got a major revamp. Everything we had was stuck at Ansible 1.9 until we refactored the code to run on Ansible 2, which was a major change.

I was thinking on creating something that didn’t depend on the internal API structure, so we could avoid this issue in the future. After all, if we invested the resources to update to Ansible 2, it would not be good to have to do it for the next version too. Eventually, I found Ansible Runner, and everything just made sense.

Ansible Runner is, as its name implies, a tool to run Ansible. It does not care about your Ansible version, it just runs your project if you pass it a correctly structured folder. And it gets better: You can use it from the shell, but you can use it directly on Python too.

Back the, while learning about Ansible Runner, I found the official tool for which it was created: AWX. That didn’t exist back when I created our own project to give Ansible a web interface. It receives a lot of love and is constantly updated. It is a very active project.

We tried using AWX for our needs, however it lacks some features that we had added to our web interface, and while we intend to send some contributions to the project to enable said functionalities, it can take some time for it to be able to replace our internal tool. Don’t misunderstand me, AWX is AMAZING, and better architected than our own solution. It is just a matter of it not fitting our needs at the moment.

Going back to Ansible Runner, we decided to update our internal tool to use it, so we could just forget about Ansible versions and push new cool features that we are thinking of.

What do you need to run Ansible Runner?

As you can see in the documentation, you need to structure your whole playbook around certain structure, so Ansible Runner can find and start the project accordingly.

Folder structure for Ansible Runner

You put your environment variables, your ssh_keys and information of that kind in the env folder, inside the project you put the playbook, etc. This may look like a lot at the beginning, but it is easy to setup it up automatically if you have the information in some kind of application.

Running with Ansible Runner

Starting your playbook now is pretty easy. You can just use the following command:

ansible-runner -p my_playbook.yml run /path/to/my/project

And that’s it. You will receive all of the output in the console, just like you do when running the playbook directly with ansible-playbook. But we can also run the same project from Python, which in our case was HUGE:

import ansible_runner
r = ansible_runner.run(private_data_dir='/tmp/demo', playbook='test.yml')
print("{}: {}".format(r.status, r.rc))
# successful: 0
for each_host_event in r.events:
    print(each_host_event['event'])
print("Final status:")
print(r.stats)

Quite easy, right? Ansible Runner performs all of the heavy lifting for you, and you don’t have to worry about the internals anymore. Also, you can hook some callbacks in case you want to do some extra things. In our case, our module changed from having around 300 lines (initialization of everything, parsing and organization, running and results) to just this:

ansible_runner.run(
        playbook="playbook.yml",
        private_data_dir=private_data_dir,
        event_handler=websocket_sender,
        finished_callback=build_saver,
    )

We send the feed we get from the runner via websockets, and we save the process after it is finished. It is quite easy to set up.

When to use Ansible Runner

If you are just starting out on Ansible, and you are wondering if you should create a web interface, Ansible Runner can help you to do so quite easily. However, make sure that your needs require so first. AWX will probably be a good fit for your needs. Or you could go with the paid version: Ansible Tower.

There are other cases where it could be interesting to use Ansible Runner instead of ansible-playbook. For example if your playbooks are all over your machine, and you are having issues understanding where are dependencies being loaded from.

Whatever be the case, Ansible is here to stay, and knowing what tools are available to you can widen your perspective when thinking about automation. That is, in the end, the final purpose for us all, right?


Comments