Add DRY CI post
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
if ! has nix_direnv_version || ! nix_direnv_version 2.1.1; then
|
||||
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.1.1/direnvrc" "sha256-b6qJ4r34rbE23yWjMqbmu3ia2z4b2wIlZUksBke/ol0="
|
||||
fi
|
||||
use flake
|
||||
@@ -1,3 +1,5 @@
|
||||
public/*
|
||||
.*.swp
|
||||
.hugo_build.lock
|
||||
None
|
||||
.direnv
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
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.
|
||||
@@ -11,6 +11,9 @@ tags:
|
||||
series:
|
||||
- Ansible CI
|
||||
---
|
||||
|
||||
{{< series "Ansible CI" >}}
|
||||
|
||||
At work I have been doing CI for nearly 10 years, now. Having been working at Red Hat for
|
||||
the past 6 of those, some of the CI work that I do is available in open source contributions
|
||||
up on Git Hub. I plan to make a series of posts about that work, so I am going to start
|
||||
|
||||
Generated
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1659877975,
|
||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1665296151,
|
||||
"narHash": "sha256-uOB0oxqxN9K7XGF1hcnY+PQnlQJ+3bP2vCn/+Ru/bbc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "14ccaaedd95a488dd7ae142757884d8e125b3363",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
description = "A basic flake with a shell";
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system: let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
nativeBuildInputs = [
|
||||
pkgs.bashInteractive
|
||||
pkgs.hugo
|
||||
];
|
||||
buildInputs = [ ];
|
||||
};
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user