Tutorial
Sep 24, 2021 If you are running Ansible Running the devel branch from a clone and want to use Python 3 with your source checkout, run your command via python3. For example: For example: $ source./hacking/env-setup $ python3 $( which ansible ) localhost -m ping $ python3 $( which ansible-playbook ) sample-playbook.yml.
Part of the Series: How To Write Ansible Playbooks# this addes the path endpoints that allow ansible work be run from a # virtualenv when ansible-runner calls ansible. Setting the path is not # necessary if ansible is installed in system python. Path = '/home/sprygada/Workspaces/ansible/bin:/home/sprygada/.virtualenvs/ansible/bin:' path += os.environ.get('PATH', ') # setup various environment vars to be set prior to starting the ansible # executable. Python API pre 2.0 ¶. It’s pretty simple: import ansible.runner runner = ansible.runner.Runner ( modulename='ping', moduleargs=', pattern='web.', forks=10 ) datastructure = runner.run The run method returns results per host, grouped by whether they could be contacted or not. Return types are module specific, as expressed in the About.
Ansible is a modern configuration management tool that doesn’t require the use of an agent software on remote nodes, using only SSH and Python to communicate and execute commands on managed servers. This series will walk you through the main Ansible features that you can use to write playbooks for server automation. At the end, we’ll see a practical example of how to create a playbook to automate setting up a remote Nginx web server and deploy a static HTML website to it.
Playbooks use the YAML format to define one or more plays. A play is a set of ordered tasks that are arranged in a way to automate a process, such as setting up a web server or deploying an application to production.
In a playbook file, plays are defined as a YAML list. A typical play starts off by determining which hosts are the target of that particular setup. This is done with the hosts
directive.
Setting the hosts
directive to all
is a common choice because you can limit the targets of a play at execution time by running the ansible-playbook
command with the -l
parameter. That allows you to run the same playbook on different servers or groups without the need to change the playbook file every time.
Start by creating a new directory on your home folder where you can save your practice playbooks. First, make sure you’re in your Ubuntu user’s home directory. From there, create a directory named ansible-practice
and then navigate into that directory with the cd
command:
If you followed all prerequisites, you should already have a working inventory file. You can copy that file into your new ansible-practice
directory now. For instance, if you created your test inventory file in an ansible
directory in your home folder, you could copy the file to the new directory with:
Next, create a new playbook file:
The following playbook defines a play targeting all
hosts from a given inventory. It contains a single task to print a debug message.
Note: We’ll learn more about tasks in the next section of this series.
Add the following content to your playbook-01.yml
file:
Save and close the file when you’re done. If you’re using nano
, you can do that by typing CTRL+X
, then Y
and ENTER
to confirm.
To try this playbook on the server(s) that you set up in your inventory file, run ansible-playbook
with the same connection arguments you used when running a connection test within the introduction of this series. Here, we’ll be using an inventory file named inventory
and the sammy user to connect to the remote server, but be sure to change these details to align with your own inventory file and administrative user:
You’ll see output like this:
Ansible Runner Python Programming
You might have noticed that even though you have defined only one task within your playbook, two tasks were listed in the play output. At the beginning of each play, Ansible executes by default an additional task that gathers information — referred to as facts — about the remote nodes. Because facts can be used on playbooks to better customize the behavior of tasks, the fact-gathering task must happen before any other tasks are executed.
We’ll learn more about Ansible facts in a later section of this series.
SUMMARY
At this moment, Ansible would fail to run on most remote hosts that do only have python3 installed by default, like Fedora 27 or newer, unless the user exclicitely adds the ansible_python_interpreter=python3
inside the inventory.
This is a real issue because it assumes that the user already knows which is the default ansible interpreter on that host, which may not be something he knows or even controls. Think about dynamic inventories or playbooks that would upgrade a host from a version that had python2 to one that that has python3.
ISSUE TYPE
- Feature Idea
COMPONENT NAME
core
ADDITIONAL INFORMATION
This issue was aggravated by the recommandation made https://www.python.org/dev/peps/pep-0394/ which indirectly made newer distributions which ship with python3 by default to not create a symlink from python
to python3
, even when there was no python2 installed.
As it seems highly unlikely to be able to update the PEP with new recomandations, we should look into findina solution for ansible, one that does not cripple the UX and avoids the need to tune ansible_python_interpreter variable for each host. This should happen under the hood by detecting a missing interpreter and falling back to python3 one (caching may be desired too).
Related links
Ansible Runner Python Code
- https://github.com/python/peps/pull/630 - Last merged change to PEP-0394 (April 2018)
- https://github.com/python/peps/pull/785 - Request to update PEP-0394
- https://bugzilla.redhat.com/show_bug.cgi?id=1630882 - Request to add python symlink to Fedora
- https://wiki.ubuntu.com/Python/3 - Ubuntu not creating the symlink because of PEP-0394