== 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 : 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 https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#running-from-source === 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 / and if trying to access content such as a role, the directory structure would be //roles/ and the playbook syntax would be ..
- 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...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 https://github.com/ansible/ansible/pull/59170