This article follows this one where I talk about verifying and testing your Ansible roles with molecule.
As I wrote in this first article, I also configured GitLab CI to automatically run molecule tests after each push to the repository. A good documentation to start with is the official GitLab CI/CD documentation.
Here is our .gitlab-ci.yml (latest version) used on our ansible repository hosting all our roles:
---
image: quay.io/ansible/molecule:latest
services:
- docker:dind
stages:
- tests
before_script:
- docker -v
- python -V
- ansible --version
- molecule --version
molecule-role-common:
stage: tests
tags:
- docker
variables:
DOCKER_HOST: "tcp://docker:2375"
PY_COLORS: 1
script:
- cd roles/common/
- molecule test
only:
changes:
- roles/common/**/*
molecule-role-monitoring-tools:
stage: tests
tags:
- docker
variables:
DOCKER_HOST: "tcp://docker:2375"
PY_COLORS: 1
script:
- cd roles/monitoring-tools/
- molecule test
only:
changes:
- roles/monitoring-tools/**/*
[…]
Our repository is hosted on gitlab.com and even if we can connect our own GitLab Runners to gitlab.com instance, we decided to use the provided gitlab.com's shared runners to get started quickly.
Those use Docker to run the jobs. So we instantiate the official molecule image (from Red Hat's registry):
image: quay.io/ansible/molecule:latest
And since molecule also needs to spawn Docker containers, we need to start another container: docker:dind (Docker in Docker). This is done with:
services:
- docker:dind
And by exporting the DOCKER_HOST
variable to the jobs, so that molecule will
be able to connect to the Docker daemon to manage its containers:
variables:
DOCKER_HOST: "tcp://docker:2375"
Then we define one stage, called tests:
stages:
- tests
Each jobs related to this stage will have the stage: tests
key in their
definition.
The before_script
block is here for debugging purpose (if the molecule tests
succeed locally bt fail on the runners, it may be because the tests are run
with a different version of molecule).
Last, we define as many jobs as we have roles to test with molecule. Here,
tags
is important since it is used by GitLab CI to select the runner the job
will be executed on. We need a runner with Docker, thus:
tags:
- docker
With script
keyword we specify each command the runner should run. Pretty
self-explanatory:
script:
- cd roles/monitoring-tools/
- molecule test
And only
adds kind of a condition to the job. We don't want to run all jobs
if, for instance, someone updates the README file. The job should run only if a
commit introduces a change to a file in the role itself. So we restrict the
execution to a change under the role's hierarchy only with:
only:
changes:
- roles/monitoring-tools/**/*
For instance, this pipeline, triggered by the commit afe5929c, has spawned only one job, the molecule-role-firewall test, since only the firewall role was modified. Whereas this commit (which impacted multiple roles) triggered 7 jobs (and yes, one has failed).
If a job fails, the commiter will receive a notification by e-mail with the commit and job ID. We can check the job's output on GitLab, to see why it has failed.
As an ending note, to test your .gitlab-ci.yml without pushing, you can install the gitlab-runner package and run it on your repository (you still need to commit your changes since `gitlab-runner will checkout the repository):
$ gitlab-runner exec docker <your job name>