---
title: "DRY CI"
date: 2022-10-10T15:32:19-05:00
draft: false
tags:
- ci
- continuous integration
- ansible
- software engineering
- technology
series:
- Ansible CI
---

{{< series "Ansible CI" >}}

So I have talked before about [what CI actually means](/posts/what-is-ci/). That post was, admittedly,
rather dry and academic. I think it's important to sometimes make the distinction between what is just
regular automation and what is strictly CI. When there is automation but no CI it is still very easy
for errors to slip into a supposedly stable code base, as not every commit is tested before it is
merged to the main. However, with the complexity of modern software, it is pragmatically impossible to
separate these two concerns, as CI without automation quickly overwhelms any manual system.

To that point, I have long had a fascination with [Ansible](https://www.ansible.com), which I encountered
early in my experience with CI. Ansible is more suited to Continuous Deployment than specifically to
Continuous Integration, but if you give someone CD tools when they are fascinated by CI, you are going to
end up with a strange assortment of mashups.

## CD for your CI

Ansible, as configuration management software, is great at deploying software and services. I don't want
to try and convince anyone to switch from their favorite system to Ansible, that's not what I'm about.
But, maybe, there are some things I've learned and done with Ansible that you can use either in your
own Ansible journey or in your own configuration management and continuous deployment tools.

Naturally, CD sits after any sort of test and, most commonly, after CI. If a build system is relatively
mature and can produce well tested code with a high confidence, it is a great candidate for Continuous
Deployment. Some tools perform this natively (such as Kubernetes). Others can be used to perform deployments
for generalized code. However, either way, you have code deploying code.

So how can you be sure your code is doing what you expect?

## CI for your CD/Configuration

Well, you test it in CI, of course! That's right, if you are unfamiliar with writing good Ansbile, there are
testing tools that exist specifically to test Ansible code. There are two main tools for this:

* [Ansible Test](https://www.ansible.com/blog/introduction-to-ansible-test) exists to specifically test
  things like modules and plugins to Ansible to ensure that they are behaving as expected
* [Molecule](https://molecule.readthedocs.io/en/latest/index.html) exists to specifically test playbooks,
  roles, and the YAML side of Ansible code

So the automated tools exist to run automated CI for Ansible code. The question becomes, how do we configure
our CI system to find and execute these tests on each merge? My answers will focus primarily on
[Github Actions](https://github.com/actions/), as that is where I execute the tests for my own Ansible
collections, but a similar technique can be leveraged in most other modern CI executors.

### First Version

The first times I wrote CI scripts for my Ansible code using Molecule there were not yet Collections available,
so each role existed to be tested on its own. Whenever a change to my CI process arose, or an update to a
version was available, I would need to update 30+ separate repositories. This was obviously unweildy, so the
first step towards sanity was moving to collection once those were available in Ansible 2.9. Now, I only had
one repository to manage.

However, I had 3 different places tests needed to be defined. I would need to write a test, first, in the
`roles/my_role/molecule/scenario_name` folder. This was the actual Molecule test definition. I would then
need to add the new scenario name, folder, and job to my `tox.ini` file, which I used to manage the Python
package installation for Ansible, Molecule, pytest, testinfra, yamllint, and more. Tox was a natural place
to manage all of these, but it meant a second place to add the test definition. And, thirdly, I had to update
my Github Actions workflow file and tell it to execute the particular tox target.

In the next post I will write about how I tamed the beast before it got out of hand.
