Ansible 3.0 and beyond, a collections primer

The new project organization for Ansible can be somewhat confusing, here's a guide!

ยท

6 min read

Ansible Logo

Background

Ansible is a configuration management (CM) tool used to make changes to remote hosts in an idempotent manner. It's a tool that I use on a daily basis and quite frankly is one of my favorite pieces of software. Ansible is extensible, has a fantastic community and is quite easy to get acquainted with for new users.

This article is aimed at those who may be using Ansible but don't follow the in's and out's of the project at-large.

Recently, there has been a shift in the way Ansible was released. Originally Ansible would ship with all modules to perform tasks in its installation package. That presented a whole host (๐Ÿ˜) of issues for the Ansible team. These challenges (maintainability, size of the package, scalability, etc.) for the Ansible Team are being addressed by the changes. If you are curious about the underlying reasons, and wish to get a better understanding of what is happening, the team has outlined their methodology in a blog post.

The change will cause some confusion and mild heartburn (mostly around changing to the FQCN, Fully-Qualified Collection Name format in playbooks or commands). One might upgrade to a version that moved to this format and suddenly playbooks no longer function (see the Troubleshooting section for what I mean).

So this post is meant to be a guide on what is changing for those of us who work day-to-day in the tool. Let's get started!

Updating to the new version, along with installation changes

To move to the new version, and you are currently running Ansible 2.9, you will need to uninstall Ansible first.

As of this writing, on CentOS 8 yum (or now dnf) will install 2.9.18-2 from the epel repository. This also goes for the Ubuntu PPA. As a result, I would recommend sticking to the pip installation rather than via a package manager:

$ pip3 install ansible=3.0.0

If you need to use multiple versions of Ansible on the same machine, please use python virtual environments or use a docker container.

Ansible-base versus Ansible-core?

As of today, the package is ansible-base. However, please note this is changing to ansible-core in the very short term (with the upcoming release of version 2.11). As the changes march on, expect to use ansible-core and think of the the package as containing only the 'core' modules in Ansible either way.

Personally, I find it "easier" (though it will not be technically correct) to just think of this as a rename operation for the package as part of the migration.

Collections

Collections are a new type of categorization for modules utilizing namespaces. As alluded to above, Ansible used to include all of its modules in the package. This is no longer going to be the case using the ansible-core/ansible-base packages. If you install the ansible pip3 package, there are some modules included from the Community (more on that later).

Before

Let's take a look at the format of using a module in a playbook before upgrading to the new FQCN system:

- name: Print hostname of remote system
  hostname:
    name: "{{ inventory_hostname }}"

The above code will use the hostname module. It will print the Ansible fact (a variable), inventory_hostname.

After

The new method will change to:

- name: Print hostname of remote system
  ansible.builtin.hostname:
    name: "{{ inventory_hostname }}"

Notice the new format? We've added ansible.builtin. to the hostname module. The change corresponds to the new builtin modules that will ship with ansible-core (or ansible-base for the time being).

Optionally, with builtin modules, you do not need to specify the FQCN value (the ansible.builtin. portion) either on the command-line, in a play or in a playbook.

However, I highly recommended that you do so anyway to maintain clean code for others as they may not be familiar with this slight difference - especially beginners. You will see that these are referenced in official documentation with the FQCN, so the Ansible team recognizes this fact.

Package / Module Installation locations

  • If you've installed Ansible 2.9 via a package manager (e.g., yum) or via the Python Package Manager (pip3), module locations for the package manager and pip3 are found in /usr/lib/python3.6/site-packages/ansible/modules/

  • With the new installation of 3.0, via the pip3 installation, are located in /usr/local/lib/python3.6/site-packages/ansible

TIP: ansible --version will always show you the location of these directories.

Why does ansible --version display 2.10+?

ansible --version will return the version of ansible-core/ansible-base, not the version of the Ansible package.

You can see this in action by running the command pip3 list ansible:

# ansible-base
$ pip3 list ansible
Package      Version
------------ -------
ansible-base 2.10.7

or

# ansible-core
$ pip3 list ansible
Package      Version
------------ --------
ansible-core 2.11.0b4

What is now built-in?

A list of built-in modules can be found here.

If you've only installed the ansible-base/ansible-core package via pip3, you will need to install additional collections using the new command:

ansible-galaxy collection install my_namespace.my_collection

So, to install the Chocolatey namespace and collection, one would use the following command:

ansible-galaxy collection install chocolatey.chocolatey

The default installed directory for collections installed via the command above are located at ~/.ansible/collections or /usr/share/ansible/collections.

What about the ansible package?

If you've installed the ansible package via pip3, there are a quite a few community modules included! This is supposed to be the "new" semi-inclusive Ansible package but still allows the Ansible Team the ability to break modules up into more manageable pieces for maintainability (instead of say, one big git repository with 1000s of issues).

If you have the ansible pip3 package, you will see the following:

# ansible with community packages as well as the base package
$ pip3 list ansible
Package      Version
------------ -------
ansible      3.2.0
ansible-base 2.10.7

There are a list of redirections that Ansible performs for several modules here.

For more information see here for how module utilities are developed.

Again -- if you ever have doubts about the installed modules included on your installation, I advise looking to the paths above in the package location heading.

Of course if you have a custom-developed collection, you would use the ansible-galaxy command above to install this collection via a URL or tarball. As a reminder this command is my_namespace.my_collection, substituting as appropriate.

ansible-galaxy collection install my_namespace.my_collection

Keeping up with Ansible

Ansible is moving with a fast cadence. I highly recommend subscribing to the Bullhorn. You can do so here. This newsletter is fantastic.

Feel free to keep up to date via other methods (such as mailing lists or IRC) here.

Troubleshooting

If you have already upgraded but now run into an error like ImportError: cannot import name 'AnsibleCollectionLoader'

This is because your play or playbook is more than likely referencing the old 'short-name' format and not using the FQCN in your playbook or play.

Closing

This entire process is a shift. But it is a necessary one. I hope this has helped you understand the underlying changes!

Thank you for reading! ๐Ÿ“š