74 lines
4.1 KiB
Markdown
74 lines
4.1 KiB
Markdown
---
|
|||
|
|
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.
|