rolecule
is a simple tool to help you test your ansible roles by creating systemd enabled containers with either docker or podman, then converging them with ansible. We're basically treating containers as mini VMs.
Once converged, it will run a verifier to test it all. Currently, the only supported provisioner is goss, but others may be added at some point in the future.
This should speed up testing your roles if you're currently using local or remote virtual machines.
First, you need to create a simple rolecule.yml
file in either the root of your role or in the tests
directory, e.g.:
---
engine:
name: podman
provisioner:
name: ansible
verifier:
name: goss
instances:
- name: rockylinux-9.1
image: rockylinux-systemd:9.1
- name: ubuntu-22.04
image: ubuntu-systemd:22.04
Then, from the root of your role (e.g. sshd), run rolecule test
, e.g.:
» rolecule test
• creating container rolecule-sshd-rockylinux-9.1 with podman
• creating container rolecule-sshd-ubuntu-22.04 with podman
• converging container rolecule-sshd-rockylinux-9.1 with ansible
Using /etc/ansible/ansible.cfg as config file
PLAY [test] ********************************************************************
...
PLAY RECAP *********************************************************************
localhost : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
• converging container rolecule-sshd-ubuntu-22.04 with ansible
No config file found; using defaults
PLAY [test] ********************************************************************
...
PLAY RECAP *********************************************************************
localhost : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
• verifying container rolecule-sshd-rockylinux-9.1 with goss
............
Total Duration: 0.016s
Count: 12, Failed: 0, Skipped: 0
• verifying container rolecule-sshd-ubuntu-22.04 with goss
............
Total Duration: 0.015s
Count: 12, Failed: 0, Skipped: 0
• destroying container rolecule-sshd-rockylinux-9.1
• destroying container rolecule-sshd-ubuntu-22.04
• complete
» rolecule --help
rolecule uses docker or podman to test your
configuration management roles/recipes/modules in a systemd enabled container,
then tests them with a verifier (goss/testinfra).
Usage:
rolecule [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
converge Run your configuration management tool to converge the container(s)
create Create a new container(s) to test the role in
destroy Destroy everything
help Help about any command
list List the running containers for this role/module/recipe
shell Open a shell in a container
test Create the container(s), converge them, test them, then clean up
verify Verify your containers are configured how you expect
Flags:
-d, --debug enable debug output
-h, --help help for rolecule
Use "rolecule [command] --help" for more information about a command.
Create the containers:
» rolecule create
• creating container rolecule-sshd-rockylinux-9.1 with podman
• creating container rolecule-sshd-ubuntu-22.04 with podman
List all containers:
» rolecule list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9638f571210 localhost/rockylinux-systemd:9.1 /usr/sbin/init 21 minutes ago Up 21 minutes ago rolecule-sshd-rockylinux-9.1
0e07e4214fd5 localhost/ubuntu-systemd:22.04 21 minutes ago Up 21 minutes ago rolecule-sshd-ubuntu-22.04
Open a shell:
» rolecule shell -n rolecule-sshd-ubuntu-22.04
root@0e07e4214fd5:/src#
Destroy the containers:
» rolecule destroy
• destroying container rolecule-sshd-rockylinux-9.1
• destroying container rolecule-sshd-ubuntu-22.04
The default for the ansible provisioner is the equivalent to setting the following in the rolecule.yml
config file:
provisioner:
name: ansible
command: ansible-playbook
playbook: playbook.yml
args:
- --connection
- local
- --inventory
- localhost,
- tests/playbook.yml
extra_args: []
env:
ANSIBLE_ROLES_PATH: .
ANSIBLE_NOCOWS: True
If you want to add extra environment variables you can just add them to the env
map, e.g.:
provisioner:
name: ansible
env:
ANSIBLE_NOCOLOR: True
If you want to run a completely different ansible command, you can override the command and all the args with the command
and args
keys respectively, but if you just want to add other args like --diff
or --verbose
, add them to the extra_args
array, e.g.:
provisioner:
name: ansible
extra_args:
- --diff
- --verbose
If you have role dependencies in your meta/main.yml
file using local roles in the same location
as the current role, they will be mounted at /etc/ansible/roles
in the container so
ansible can find them.
These are instances of each test scenario, allowing you to test different ansible tags with specific test files.
A simple example for a single Ubuntu test would be:
instances:
- name: ubuntu-22.04
image: ubuntu-systemd:22.04
Something more elaborate:
instances:
- name: ubuntu-22.04
image: ubuntu-systemd:22.04
playbook: ubuntu/playbook.yml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- name: ubuntu-22.04-build
image: ubuntu-systemd:22.04
arch: amd64
playbook: ubuntu/playbook.yml
testfile: goss-build.yaml
tags:
- build
- name: rockylinux-9.1
image: rockylinux-systemd:9.1
- name: rockylinux-9.1-build
image: rockylinux-systemd:9.1
testfile: goss-build.yaml
tags:
- build
skip_tags:
- provision
Where the above will test two different scenarios for each of the Ubuntu and Rocky Linux containers.
If you do not specify the testfile in the instance config, it will use the one specified in the verifier config.
If you do not specify the playbook in the instance config, it will use the one specified in the provisioner config.
Testing multiple architectures is support, but untested as I don't currently have an easy way to test it, but should be as simple as something like:
instances:
- name: ubuntu-22.04-amd64
image: ubuntu-systemd:22.04
arch: amd64
- name: ubuntu-22.04-arm64
image: ubuntu-systemd:22.04
arch: arm64
If you don't specify the arch, it will use the current host's architecture
Please note that id you do want to test using a different architecture to the host your are running it on, you will need to have the relevant container image for that architecture.
The default goss configuration when you only specify the name, is equivalent to this:
verifier:
name: goss
testfile: goss.yaml
extra_args: []
This will execute:
goss --gossfile tests/goss.yaml validate
If you want to customise how goss validate is executed, you can change the gossfile and add extra arguments to the validate subcommand, e.g. with this in your rolecule.yml
:
verifier:
name: goss
testfile: goss-build.yaml
extra_args:
- --format
- tap
It will execute:
goss --gossfile tests/goss-build.yaml validate --format tap
How do I get this working on macOS?
You'll need to make sure you create a rootful podman machine with your home directory mounted for volume mounts to work, e.g.:
» podman machine init --now --rootful -v $HOME:$HOME
Docker Desktop should just work
How do I get this working on Windows?
You'll need to make sure you create a rootful podman machine, e.g.:
» podman machine init --now --rootful
Docker Desktop should just work
How do I create a suitable container image for this?
You can use the Dockerfile
files in the testing directory to build suitable images:
» podman build -t rockylinux-systemd:9.1 -f testing/ansible/rockylinux-9.1-systemd.Dockerfile .
» podman build -t ubuntu-systemd:22.04 -f testing/ansible/ubuntu-22.04-systemd.Dockerfile .
» podman build -t amazonlinux2-systemd:2 -f testing/ansible/amazonlinux2-systemd.Dockerfile .
or
» docker build -t rockylinux-systemd:9.1 -f testing/ansible/rockylinux-9.1-systemd.Dockerfile .
» docker build -t ubuntu-systemd:22.04 -f testing/ansible/ubuntu-22.04-systemd.Dockerfile .
» docker build -t amazonlinux2-systemd:2 -f testing/ansible/amazonlinux2-systemd.Dockerfile .
How do I install collections?
For now, I've been building in my collections in to the container images in the default location so they are discovered automatically by ansible.
Test with podman on MacTest docker on LinuxMake provisioner output unbufferedSupport installing role dependencies- Support installing ansible collections
- Support testinfra verifier
Support scenarios, making it possible to test a role with different tagsSupport using custom provisioner command/args/env vars from rolecule.ymlSupport using custom verifier command/args/env vars from rolecule.yml/%s- Implement
rolecule init
to generate a rolecule.yml file (use current directory structure to determine configuration management provisioner) Implementrolecule list
subcommand to list all running containersWrite some tests :/Document what is required for a container imageTest with docker on LinuxTest with docker desktop on MacTest with podman desktop on WindowsTest with docker desktop on WindowsAdd goreleaser config to release to Github ReleasesAdd Github actions workflow to build, test and release