Ansible installation can be not so trivial…

Ansible 2.10 Installation on Mac OS X

Ansible 2.10 is there. What is Ansible? How to install it?

Laurent Prévost
Geek Culture

--

Photo by Alex Knight on Unsplash

Introduction

I am an Ansible user for several years now. I use it at home and at work for configuring various devices from computers to network devices. More or less, it manages all our infrastructure through Ansible.

In this article, I will give my understanding of the key concepts of Ansible. The ones that are important and matter for an overview of the tool.

After starting the installation, we will discover some tools. They can help you have a friendly working environment.

‼️ Disclaimer: The time passed since I originally wrote this article. The content should be less relevant for the installation part. It remains relevant for the key concepts 😇.

What is Ansible?

RedHat says: Ansible is an agentless solution that automates IT management.

Simple, agentless IT automation that anyone can use. Ansible is a universal language, unraveling the mystery of how work gets done. Turn tough tasks into repeatable playbooks. Roll out enterprise-wide protocols with the push of a button. — RedHat Ansible Website

Photo by Maximalfocus on Unsplash

It has been several years since I use Ansible in my professional and my private life. I use it to manage my home computers. I use it in my job to manage more or less everything to have “Infrastructure as Code”.

And what about the word itself? It is fun to see it relates to the sci-fi world. The word is a sci-fi invention.

An ansible is a category of fictional device or technology capable of near-instantaneous or superluminal communication. It can send and receive messages to and from a corresponding device over any distance or obstacle whatsoever with no delay, even between star systems. As a name for such a device, the word “ansible” first appeared in a 1966 novel by Ursula K. Le Guin. Since that time, the term has been broadly used in the works of numerous science fiction authors, across a variety of settings and continuities. — Wikipedia

In the next few sections, we will cover some of the most important concepts of Ansible. I do not pretend to be exhaustive nor accurate. This is my understanding and my pragmatic approach to these concepts.

Playbooks

A playbook lets you write a suite of tasks to configure and manage a host. We can do more or less everything from the network to the application configuration. And more important is the principle of idempotence.

Idempotence is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application. The concept of idempotence arises in a number of places in abstract algebra (in particular, in the theory of projectors and closure operators) and functional programming (in which it is connected to the property of referential transparency). — Wikipedia

Photo by Louis Smith on Unsplash

In Ansible, the idempotence characterizes the fact that any task can run twice or more. It will always produce the same result. For me, this is one of the core concepts of Ansible and the most important one to understand. You always rely on this principle when using Ansible. Most of the time, the Ansible modules put in place the idempotence. This will avoid you to have to take care of this.

Playbook Sample

Roles and tasks

Another concept in Ansible is the roles. A role is a way to write reusable tasks. Then, in a playbook, you can call a suite of roles and tasks in place of only tasks. It will let you the possibility to use the same roles in different contexts.

Role Directory Structure

A task in Ansible is the atomic element of what you can do to apply your configuration. There are a lot of different tasks available in Ansible. Examples are copy, file, and template. These core tasks manipulate files.

Role Sample

A role is a composition of one or more sequential tasks.

Inventory

Another important concept is the inventories. An inventory is a list of one or more host where you will apply a playbook. You can define static inventories or build dynamic inventories. It is the set of computers to configure through the run of the playbooks.

Inventory Sample

Module

A module in Ansible is a set of organised tasks. For example, you will find a module for AWS, Azure, and filesystem. There are plenty of modules supported by Ansible or its community. We can say this is more or less a way to organise the Python code in topics.

Collection

The Ansible documentation describes the collections as a mean to distribute content. The content can be roles, playbooks, modules, or plugins.

Collections are a distribution format for Ansible content that can include playbooks, roles, modules, and plugins. As modules move from the core Ansible repository into collections, the module documentation will move to the collections pages. — Ansible Documentation

For me, this is the novel way to package every extra content of Ansible that is not part of the Ansible core. This is a great evolution of Ansible bringing even more modularity to the tool.

Ansible Installation

But before writing my collection, I need first to install Ansible. At the time of writing this article, Ansible 2.10 was not available through homebrew. The release date was in August, and packages for homebrew can take a bit of time to be available.

To install Ansible, you need to run this command with homebrew.

brew install ansible

But, since version 2.10, it seems they have also reworked the core. Consider I am running under Mac OS X.

So I installed Ansible with pip, one of the Python package manager. First I need, to have a correct version of Python installed. I installed Python 3.8.5. For that, I use the asdf-vm cli tool. It manages various versions of development environments and languages.

To install Python 3.8.5, run the following commands (bold lines).

# Add the ASDF Python plugin to manage versions for this language
asdf plugin-add python
updating plugin repository...
remote: Enumerating objects: 59, done.
remote: Counting objects: 100% (59/59), done.
remote: Total 97 (delta 59), reused 59 (delta 59), pack-reused 38
Unpacking objects: 100% (97/97), done.
From https://github.com/asdf-vm/asdf-plugins
d736d70..e1bc152 master -> origin/master
HEAD is now at e1bc152 Merge pull request #286 from abatilo/patch-2
# Install the required Python version
asdf install python 3.8.5
python-build 3.8.5 /Users/<user>/.asdf/installs/python/3.8.5
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.8.5.tar.xz...
-> https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tar.xz
Installing Python-3.8.5...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.8.5 to /Users/<user>/.asdf/installs/python/3.8.5
# Make Python version as the global default version
asdf global python 3.8.5
# If everything works well, you should get the right version
# You may have to restart your terminal session

python -V
Python 3.8.5# I also upgrade pip when I install Python
pip install --upgrade pip
Collecting pip
Downloading pip-20.2.3-py2.py3-none-any.whl (1.5 MB)
|████████████████████████████████| 1.5 MB 2.7 MB/s
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 20.1.1
Uninstalling pip-20.1.1:
Successfully uninstalled pip-20.1.1
Successfully installed pip-20.2.3

Now we can install Ansible 2.10 with the following commands (bold lines).

# Install Ansible base (new since 2.10)
pip install ansible-base
Processing ./Library/Caches/pip/wheels/55/b6/74/6bf7a932107b1e032a4d33c41433ebf56620ad1f3cc2068f8e/ansible_base-2.10.1-py3-none-any.whl
Collecting jinja2
Using cached Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
Collecting packaging
Using cached packaging-20.4-py2.py3-none-any.whl (37 kB)
Processing ./Library/Caches/pip/wheels/13/90/db/290ab3a34f2ef0b5a0f89235dc2d40fea83e77de84ed2dc05c/PyYAML-5.3.1-cp38-cp38-macosx_10_15_x86_64.whl
Collecting cryptography
Using cached cryptography-3.1-cp35-abi3-macosx_10_10_x86_64.whl (1.8 MB)
Collecting MarkupSafe>=0.23
Using cached MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl (16 kB)
Collecting pyparsing>=2.0.2
Using cached pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
Collecting six
Using cached six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting cffi!=1.11.3,>=1.8
Using cached cffi-1.14.2-cp38-cp38-macosx_10_9_x86_64.whl (176 kB)
Collecting pycparser
Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Installing collected packages: MarkupSafe, jinja2, pyparsing, six, packaging, PyYAML, pycparser, cffi, cryptography, ansible-base
Successfully installed MarkupSafe-1.1.1 PyYAML-5.3.1 ansible-base-2.10.1 cffi-1.14.2 cryptography-3.1 jinja2-2.11.2 packaging-20.4 pycparser-2.20 pyparsing-2.4.7 six-1.15.0
# Make sure Ansible is in your path
asdf reshim python
# Check the installed version and correct Python version
❯ ansible --version
ansible 2.10.1
config file = /Users/<user>/.ansible/ansible.cfg
configured module search path = ['/Users/<user>/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /Users/<user>/.asdf/installs/python/3.8.5/lib/python3.8/site-packages/ansible
executable location = /Users/<user>/.asdf/installs/python/3.8.5/bin/ansible
python version = 3.8.5 (default, Sep 20 2020, 11:09:32) [Clang 11.0.3 (clang-1103.0.32.59)]

At this stage, you have a base install of Ansible which contains only the core elements. The test playbook and the configuration file. It forced me to install extra Ansible collection.

My Ansible Configuration File

Create a file test.yaml to verify your Ansible installation. The file must contain the following content.

Test Playbook

The run of the playbook produces an error. The error was due because of the following configuration in my Ansible config file.

stdout_callback = yaml
bin_ansible_callbacks = True

And the error.

# The playbook command
ansible-playbook test-playbook.yaml
...
ERROR! Invalid callback for stdout specified: yaml

To fix this issue, I had to install the community.general collection.

To install the collection, I did the following commands. I got an error as the collections folder did not exist.

# Tried to list the installed collections
ansible-galaxy collection list
[WARNING]: — the configured path /Users/<user>/.ansible/collections does not exist.
....
ERROR! — None of the provided paths were usable. Please specify a valid path with — collections-path

I created the folder and then I installed the collection.

# Create the directory
mkdir /Users/<user>/.ansible/collections
# List installed collections
ansible-galaxy collection list
# None installed, empty stdout# Install the collection
ansible-galaxy collection install community.general
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'community.general:1.1.0' to '/Users/<user>/.ansible/collections/ansible_collections/community/general'
Downloading https://galaxy.ansible.com/download/community-general-1.1.0.tar.gz to /Users/<user>/.ansible/tmp/ansible-local-90875hlzn08qq/tmpwt8d2kpe
community.general (1.1.0) was installed successfully
...
google.cloud (1.0.0) was installed successfully
...
ansible.posix (1.1.1) was installed successfully
...
ansible.netcommon (1.2.1) was installed successfully
...
community.kubernetes (1.0.0) was installed successfully

Finally, I could run the test playbook.

# Run the test playbook
ansible-playbook test-playbook.yaml
PLAY [localhost] ********************************************************************TASK [debug] ********************************************************************
ok: [localhost] =>
msg: Hello World!
PLAY RECAP ********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Conclusion

We have a working Ansible setup where we can run playbooks and other Ansible commands. From this point, we can start the automation of everything we want (if module and plugins exist).

We are also ready to dig deeper into Ansible and write some modules by ourselves. In a future article, I will cover how to write a module for Ansible.

References

The official Ansible website contains many resources. It contains also all the documentation of the modules. There are also the links to Ansible Tower (commercial product) and the counterpart AWX.

Homebrew is the preferred packaged manager on Mac OS X. It works well, and the community is active.

The ultimate version manager for your programming languages and other cli tools.

--

--