How to develop and run collection locally

I am pretty new to Ansible and hope to use it to automate deployment on hardware that my company manages.

I have created a collection for us to bundle all of our roles into, as it seems this is the modern way to use Ansible. I have tested them using Molecule and everything is working well, except for testing systemd services. Rather than try to find some workaround for getting systemd to work in Docker, I have been trying to test against some cheap EC2 instances.

The friction I am having now, though, is the development loop:

  • Install my collection
  • Test / Run Playbook using role from collection
  • Inevitably find some issue
  • Fix Issue or add debug task
  • Install collection again – to pick up changes
  • Test / Run playbook again

This is working, but the fact that I have to force-install my collection every time I want to test my role is frustrating.

Am I missing some setup trick or tool that makes this development loop simpler? Ideally, I could just make changes in my collection and then test without installing it again.

I will likely resort to using make to streamline this loop, but I figured I would ask here first if there is something I can try that is native to ansible.

3 Likes

I’m doing this for roles but I expect something like it would work for collections?

I have ansible-galaxy install roles into galaxy/roles but for development I symlink roles/role_name to the local git repo for that role so when I run the playbook it always uses the latest local version of the role.

I’ve even got a very simple update.sh Bash script in the roles directory I can run to update all the symlinked roles:

#!/usr/bin/env bash

dirs=$(ls | grep -v ${0})
for d in ${dirs};
do
  if [[ -d ${d} ]]
  then
    cd ${d} || exit
    git pull || exit
    cd - || exit
  fi
done
3 Likes

Hi,

Molecule should let you use ec2 instances.

Also, similar to how @chris does, I happen to live test / debug my roles from source without having to commit / push / reinstall on every modification when I need to run tests directly on intended targets, often to diff with current configuration as it’s easier in most cases.

What I do is either work on local path I previously installed role with ansible-galaxy, then when I am done, just rsync modifications to role repo, or work directly in repo, changing role install paths using ANSIBLE_ROLES_PATH envvar. Using a symlink would be a close one :slight_smile:.

2 Likes

I have all the collections I work on checked out in a ansible_collections directory structure that’s both part of my work directory (where all my git projects are checked out) and my ANSIBLE_COLLECTIONS_PATH. Basically what is described here: How to test a collection PR — Ansible Documentation

This allows me to directly use the collections I am working on in ansible-core without having to install them.

It does mean though that I have to manually take care of the collection’s dependencies. For the collections I work on this isn’t a problem, most don’t have dependencies at all, or these are also collections I (sometimes) work on, so I have them checked out anyway. Of course you can also install some of the dependencies manually with ansible-galaxy collection install somewhere else.

One alternative to the above is to check out the collection foo.bar to in a directory collections/ansible_collections/foo/bar relative to your playbook directory. Then you can modify the collection and directly use them in your playbooks. (You could of course also keep that collection in this directory structure in the same git repo as your playbooks. Whether that makes sense depends on your situation…)

4 Likes

Oh! Somehow I missed that EC2 plugin for Molecule. I will definitely check this out. Thanks for mentioning it!

I was following the Using Docker Containers guide, and because it just did everything in playbooks, I didn’t think to check out what plugins were available.

1 Like

This is great and makes sense. I am going to give it a shot!

One alternative to the above is to check out the collection foo.bar to in a directory collections/ansible_collections/foo/bar` relative to your playbook directory. Then you can modify the collection and directly use them in your playbooks. (You could of course also keep that collection in this directory structure in the same git repo as your playbooks. Whether that makes sense depends on your situation…)

This is roughly what I am doing now; I think I was missing the ANSIBLE_COLLECTIONS_PATH part.