Ansible Collections Guide
Contents
terminology
- galaxy
- https://galaxy.ansible.co,
- AH
- see Automation Hub
- Automation Hub
- https://cloud.redhat.com private galaxy instance for Red Hat customers.
- plugins
- ansible plugins, which can be callbacks, filters, tests, inventory, strategy AND modules
- v1 role
- a bundled format of plugins, variables, templates, files, and task files
- collection
- a bundled format of plugins and "collection roles"
- collection role
- similar to v1 roles except that they can NOT contain plugins
- FQCN
- Fully Qualified Collection Name. Takes the format <namespace>.<name>.<pluginname>
- namespace
- For roles on galaxy.ansible.com, this was 1:1 mapping with the github login that owned a role's github repository. For collections, this is more synthetic and has to be requested and associated to a specific login but still serves the same purpose of grouping logical collections and or defining ownership.
- collection keyword
- A syntactical feature in ansible plays that defines what collection FQNs to search through when looking for unqualified plugin names.
- artifact
- the tarballed version of a collection that is published to galaxy or automation hub and is distributed for installs
- mazer
- https://github.com/ansible/mazer
FAQ
When will ansible-doc support collections?
plugins already work when you use FQCN, ' listing' is planned for after when ansible-galaxy is able to list installed collections For collection specific docs .. those are yet to be defined. The only thing currently known is the 'readme' for AH/galaxy display
the stack
ansible
Ansible 2.8 and 2.9 both contain pluginloader support for collections. 2.8's implementation is a tech-preview, and 2.9 will be fully supported.
https://releases.ansible.com/ansible/rpm/preview/
https://github.com/ansible/ansible/tree/stable-2.8
mazer & ansible-galaxy cli
Mazer was the experimental tool to build, publish, and consume collections...
pip install https://github.com/ansible/mazer
We have now ported those functionalities to a subcommand of ansible-galaxy and this will be the standard going forward ...
https://groups.google.com/forum/#!topic/ansible-devel/ChNFHsCTpno
molecule
Molecule is a role developer kit of sorts and does not currently understand collections, but we're hoping to change that in the future.
https://molecule.readthedocs.io/en/stable/
https://github.com/ansible/molecule
galaxy
create a collection
directory structure
The complete specification for the directories within a collection is https://github.com/bcoca/collection
An important aspect of collections are that they are namespaced. Therefore, you must consider them in terms of a series of subdirectories such as <namespace>/<name> and if trying to access content such as a role, the directory structure would be <namespace>/<name>/roles/<rolename> and the playbook syntax would be <namespace>.<name>.<rolename>
- hosts: el7host connection: local gather_facts: False roles: - foo.bar.bang
debugging
Check the stat syscalls via strace to see all the various places the pluginloader is looking for the collections ...
(venv) [jtanner@jtw530 AP-collection_FAQ]$ strace -fftv -e stat -o strace.out ansible-playbook -i inventory site.yml (venv) [jtanner@jtw530 AP-collection_FAQ]$ cat strace* | fgrep ansible_collection | awk '{print $2}' | sort -u stat("/data/workspace.issues/AP-collection_FAQ/collections/ansible_collections", stat("/data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/foo", stat("/data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/foo/bar", stat("/data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/foo/bar/__init__.py", stat("/data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/foo/bar.py", stat("/data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/foo/__init__.py", stat("/data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/foo.py", stat("/home/jtanner/.ansible/collections/ansible_collections/foo", stat("/home/jtanner/.ansible/collections/ansible_collections/foo/bar", stat("/home/jtanner/.ansible/collections/ansible_collections/foo/bar/__init__.py", stat("/home/jtanner/.ansible/collections/ansible_collections/foo/bar.py", stat("/home/jtanner/.ansible/collections/ansible_collections/foo/__init__.py", stat("/home/jtanner/.ansible/collections/ansible_collections/foo.py", stat("/usr/share/ansible/collections/ansible_collections/foo", stat("/usr/share/ansible/collections/ansible_collections/foo/bar", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/plugins", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/plugins/__init__.py", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/plugins.py", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles/bang", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles/bang/defaults", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles/bang/handlers", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles/bang/meta", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles/bang/tasks", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles/bang/tasks/main.yml", stat("/usr/share/ansible/collections/ansible_collections/foo/bar/roles/bang/vars",
play adjacent
(venv) [jtanner@jtw530 AP-collection_FAQ]$ pwd /home/jtanner/workspace/issues/AP-collection_FAQ (venv) [jtanner@jtw530 AP-collection_FAQ]$ ls site.yml site.yml (venv) [jtanner@jtw530 AP-collection_FAQ]$ tree collections/ collections/ └── ansible_collections └── foo └── bar └── roles └── bang └── tasks └── main.yml
homedir
(venv) [jtanner@jtw530 AP-collection_FAQ]$ tree ~/.ansible /home/jtanner/.ansible └── collections └── ansible_collections └── foo └── bar └── roles └── bang └── tasks └── main.yml
global
(venv) [jtanner@jtw530 AP-collection_FAQ]$ tree /usr/share/ansible /usr/share/ansible └── collections └── ansible_collections └── foo └── bar └── roles └── bang └── tasks └── main.yml
module utils
If a module needs to import a module util from the same or another collection, it needs to use the following import sytax/format ...
from ansible_collections.<namespace>.<name>.plugins.module_utils.vmware import XYZ
build and publish collections
FIXME - change mazer references to ansible-galaxy
- build - compile an "artifact" [tarball] of the collection.
- publish - send the "artifact" to galaxy.ansible.com and share it to the community.
Before mazer will allow you to build a collection, a galaxy.yml file has to be created at the root of the collection.
(venv) [jtanner@jtw530 collection1]$ pwd /home/jtanner/workspace/issues/AP-collection_FAQ/collections/ansible_collections/jctanner/collection1 (venv) [jtanner@jtw530 collection1]$ cat galaxy.yml namespace: jctanner name: collection1 version: 0.0.1 license: Apache-2.0
License values should come from https://spdx.org/licenses/ as mazer will validate the entry during build.
(venv) [jtanner@jtw530 collection1]$ mazer build Building collection: /data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/jctanner/collection1 Created artifact: /data/workspace.issues/AP-collection_FAQ/collections/ansible_collections/jctanner/collection1/releases/jctanner-collection1-0.0.1.tar.gz (venv) [jtanner@jtw530 collection1]$ tar tvf releases/jctanner-collection1-0.0.1.tar.gz tar: Removing leading `/' from member names drwxrwxr-x jtanner/jtanner 0 2019-05-06 16:37 / -rw-rw-r-- jtanner/jtanner 73 2019-05-06 16:37 galaxy.yml drwxrwxr-x jtanner/jtanner 0 2019-05-06 16:23 roles/role_a/ drwxrwxr-x jtanner/jtanner 0 2019-05-06 16:23 roles/role_a/tasks/ -rw-rw-r-- jtanner/jtanner 26 2019-05-06 16:23 roles/role_a/tasks/main.yml -rw-rw-r-- jtanner/jtanner 1092 2019-05-06 16:37 FILES.json -rw-rw-r-- jtanner/jtanner 717 2019-05-06 16:37 MANIFEST.json
docs
https://galaxy.ansible.com/docs/contributing/creating_collections.html
https://docs.ansible.com/ansible/devel/collections_tech_preview.html