Here is my first post about modules. In that post I built what I’d call a legacy module, something to include in a basic playbook to prove a concept worked. Ansible has moved on and is now pushing content collections. This post will detail moving my module to a content collection.

Content Collections

Ansible content collections, as I understand them, are a way to group custom functionality into something that is unique. The problem with modules is the names could overlap, with content collections they cannot. Content collections also add roles and plugins, so you can collapse a bunch of different ansible functionality into one area to include.

Again, Ansible documentation is really good about laying out the framework for building a content collection. I’m not going to repeat this so go read that if you need the primer for a content collection.

My content collection

First step was to initialize a collection with a namespace. Not sure if Ansible has registered namespaces, but I’m sure if you tried to use a random company it’d fail. For my purposes, I’ll use my github ID

ansible-galaxy collection init jrmann1999.tacacs

Once this is setup, you’ll get a tree full of folders/files you could use if you wish. For my purposes in this article I’m only going to use the modules.

.
jrmann1999/
    tacacs/
        docs/
        plugins/
            modules/
            README
        roles/
        galaxy.yaml
        README

There are again some standards around documentation that should go into docs, especially if you ever plan on publishing this to galaxy. I will not be, so I’m leaving it blank.

You can also choose to delete folders you’re not using (roles in my case) however I’m leaving it in case I do want to develop a role.

All I had to do to get my module into the content collection, was to copy my python modules into the modules folder within plugins

.
jrmann1999/
    tacacs/
        plugins/
            modules/
                tacplus_authenticate.py
                tacplus_authorize.py

Once this was done, I can already build my content collection.

ansible-galaxy collection build jrmann1999/tacacs

This will produce a .tar.gz file wherever you ran the command. From there you can install into your playbook directory (or generic ansible path)

ansible-galaxy collection install file.tar.gz

Then the playbook is altered to use the collection file OLD playbook with legacy modules:

---
- name: Test collection import
  hosts: localhost
  gather_facts: False
  vars_files:
    - "credentials.yml"
  tasks:
    - name: Authentication Test
      tacplus_authenticate:
        tac_username: 'USER'
        tac_password: "{{ credentials.password }}"
        tac_server: 'IP'
        tac_secret: "{{ credentials.tacsecret }}"
      register: testout
      no_log: True

    - name: Dump output
      debug:
        msg: '{{ testout }}'

    - name: Authorization Test (show version)
      tacplus_authorize:
        tac_username: 'USER'
        tac_server: 'IP'
        tac_secret: "{{ credentials.tacsecret }}"
        tac_command: 'show version'
      register: testout

    - name: Dump output
      debug:
        msg: '{{ testout }}'

NEW playbook with content collection:

---
- name: Test collection import
  hosts: localhost
  gather_facts: False
  vars_files:
    - "credentials.yml"
  tasks:
    - name: Authentication Test
      jrmann1999.tacacs.tacplus_authenticate:
        tac_username: 'USER'
        tac_password: "{{ credentials.password }}"
        tac_server: 'IP'
        tac_secret: "{{ credentials.tacsecret }}"
      register: testout
      no_log: True

    - name: Dump output
      debug:
        msg: '{{ testout }}'

    - name: Authorization Test (show version)
      jrmann1999.tacacs.tacplus_authorize:
        tac_username: 'USER'
        tac_server: 'IP'
        tac_secret: "{{ credentials.tacsecret }}"
        tac_command: 'show version'
      register: testout

    - name: Dump output
      debug:
        msg: '{{ testout }}'

And that’s it. Obviously content collections are more powerful, but at it’s basic it’s pretty simple to migrate.

What’s next

Specific to my use-case, I plan on extending my collection to allow me to add a network device to Cisco ISE, and change it’s “role” within ISE to test various tacacs authentication/authorization policies. This will involve using the ISE API (or other ansible collection) to add my node, test, and then remove my mode. I might write up an entry specific to that use case, but this is where the ansible-module entries likely end.

As usual, this blog post is mostly for my own notes, but hope it’s helpful to someone else.