Run, Ansible, Run! (Part 2/2)

In the first part of this mini series on Ansible Runner, we took a look at the command line interface. In this second part, we will have a look at the two remaining ways Ansible Runner can be used: the container image and the python library.

Ansible Runner is three things:

  1. a command line tool,
  2. a reference container image,
  3. a python library

Let’s quickly recap our metadata directory and its content:

├── env
│   ├── extravars
│   └── ssh_key
├── inventory
│   └── hosts
└── project
    └── forrest.yml

The extravars file contains:

debug_msg: "Run, Ansible, Run!"

The playbook forrest.yml:

- name: Run Ansible Run
  hosts: node1
  remote_user: ansible
  become: true
    - name: Output message
        msg: "{{ debug_msg }}"

The inventory file hosts:

node1 ansible_host=x.x.x.x

The SSH private key user ansible needs to connect to server node1 can be found in the file ssh_key.

Ansible Runner the container image

As we learnt from the documentation, Ansible Runner is not only a cli, but also a container image. This reference container image is purposefully light-weight and only contains the dependencies necessary to run ansible-runner itself. Inspecting it with Ansible Navigator reveals that it only includes ansible-core and no additional collections. It’s intended to be overridden. That means, it can be used to create our own execution environment, which is actually what ansible-builder does.
To use an execution environment for running our playbook, we just have to start the container image with podman, mount our metadata directory into the /runner folder inside the container, and provide the playbook to be run as an environment variable. Take care if you are running selinux in enforcing mode (as you should!). You then have to relabel the selinux context inside the container with :Z. Make sure as well, that there are no podman-settings in your env/settings file or the file is absent. When directly running an execution environment with podman, having these settings present would lead to the container trying to run the playbook inside a container again. This would fail because podman is not installed inside the execution environment.

With all this said, we can use the following command to run our playbook directly with podman in an execution environment:

$ podman run --rm -e RUNNER_PLAYBOOK=forrest.yml -v /home/ansible/techlab:/runner:Z default-ee:latest
Identity added: /runner/artifacts/245fd880-e6bf-4f8e-88f1-23551637cca8/ssh_key_data (Created for convenience ahead of techlab)

PLAY [Run Ansible Run] *********************************************************

TASK [Gathering Facts] *********************************************************
ok: [node1]

TASK [Output message] **********************************************************
ok: [node1] => {
"msg": "Run, Ansible, Run!"

PLAY RECAP *********************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

So we only need podman to be installed, an execution environment, and the folder structure with the data about our Ansible project.

Ansible Runner the Python library

As we know from the introduction, Ansible Runner is also a Python library. And because we are system engineers, we love fantasy literature, heavy metal music or at least Python…

So let’s write a simple Python script that uses our metadata directory and runs the playbook forrest.yml. If you have your podman settings in the env/settings file, the Ansible run is started inside the stated execution enviroment. If you don’t have such settings present, it’s run directly with ansible-playbook. This behaviour is similar to the ansible-runner cli.

$ cat

import ansible_runner

Make sure the script is executable and run it!

$ chmod +x
$ ./
Identity added: /home/ansible/techlab/artifacts/b6d4cae3-5da3-4eea-931a-8ecf18defdf6/ssh_key_data (Created for convenience ahead of techlab)

PLAY [Run Ansible Run] *********************************************************

TASK [Gathering Facts] *********************************************************
ok: [node1]

TASK [Output message] **********************************************************
ok: [node1] => {
"msg": "Run, Ansible, Run!"

PLAY RECAP *********************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0



Ansible Runner is three things combined, and this can be confusing. The current documentation is sparse on details, so getting started can be a bit of a bumpy ride. We don’t see too much advantages in using the ansible-runner command line interface at the moment. With ansible-playbook and ansible-navigator, there are already tried and tested tools available to do the job.

However, using Ansible Runner as an execution environment directly with podman and using the Python library to start Ansible provides nice tooling to create custom Ansible workflows. It will be interesting to see if new tools start developing around these possibilities.

If you’d like to dive in, have a look at our labs at

Kommentare sind geschlossen.