Presented by
Zackary Lowery
on October 24th, 2023 at
Leading EDJE.
Available online at https://presentations.xcjs.com/
Press your space bar or swipe to navigate down and then forward. ยป
...or How to Write a Bad CI/CD Pipeline and Improve it Iteratively
This presentation is a spiritual follow-up to Ansible: Putting IaC in Your CI/CD.
Ansible is a state-management based IaC solution for host configuration.
A list of network-accessible hosts.
Unit of software or configuration state.
โฌ
โฌ
Assign reusable roles to selected hosts.
351MP |
![]() |
AERO15 |
|
K8S_[0-4] |
![]() |
Lakka |
![]() |
MDEV |
|
MDEV2 |
|
NAS |
|
PlexBox |
|
Runner |
|
UDEV3 |
|
USERV |
|
XCJS |
|
Z390 |
|
โ | ๐ซ |
|
|
โ | ๐ซ |
|
|
โ | ๐ซ |
|
|
โ | ๐ซ |
|
|
153 roles as of writing multiplied by
flowchart LR A[Start] --> B{Next OS?}; B -- Yes --> C[
Create VM]; B -- No --> D[End]; C --> E[
Provision VM]; E --> F{
Next Role?}; F -- Yes --> G[
VM Applies Role]; F -- No --> H[
Destroy VM]; G --> F; H --> B;
...or just over 27 hours.
...to fail.
๐ญ
โ ๏ธ If it's important, back it up! โ ๏ธ
changes
directive
${role} Test:
stage: Test
rules:
- if: '$CI_COMMIT_BRANCH == "testing"'
changes:
- roles/.common/tasks/*.yml
- roles/${role}/tasks/*.yml
- test/generate-tests.sh
- .gitlab-ci.yml
- Vagrantfile
flowchart LR A[Start] --> B{Next Role?}; B -- Yes --> C{
Next VM?}; B -- No --> D[End]; C -- Yes --> E[
Create VM]; C -- No --> B; E --> G[
Provision VM]; G --> H[
VM Applies Role]; H --> I[
Destroy VM]; I --> B{
Next Role?};
${role}/Ubuntu 20.04:
stage: Test
rules:
- if: '$CI_COMMIT_BRANCH == "testing"'
changes:
- roles/.common/tasks/*.yml
- roles/${role}/tasks/main.yml
- roles/${role}/tasks/linux.yml
- roles/${role}/tasks/ubuntu_20.04.yml
- test/templates/ubuntu_20.04/.gitlab-ci.part.yml
- test/templates/ubuntu_20.04/blacklist.yml
- test/templates/ubuntu_20.04/site-test.yml
- test/generate-tests.sh
- .gitlab-ci.yml
- Vagrantfile
flowchart LR A[Start] --> B{Role Changed?}; B -- Yes --> C{
Next OS?}; B -- No --> J[End]; C -- Yes --> D[
Prepare VM Disk]; C -- No --> B; D --> E[
Provision VM]; E --> F[
Start VM]; F --> G[
Apply Role]; G --> H[
Destroy VM]; H --> C;
flowchart LR A[Start] --> B{Next OS?}; B -- Yes --> C[
Create VM]; B -- No --> D[Start Testing]; C --> E[
Provision VM]; E --> F[
VM Disk Snapshot]; F --> G[
Halt VM]; G --> B;
flowchart LR A[Start] --> B{Role Changed?}; B -- Yes --> C[
Restore Disk Snapshot]; B -- No --> G[End] C --> E[
Apply Role]; E --> F[
Halt VM]; D -- Yes --> C; D -- No --> B; F --> D{
Next OS?};
./test/generate-tests.sh
supportedOperatingSystems=(
"ubuntu_18.04"
"ubuntu_20.04"
"ubuntu_22.04"
"windows_10"
"windows_11"
)
for path in roles/*/; do # Whitespace-safe
role=$(basename "${path}")
done
for os in "${supportedOperatingSystems[@]}"
do
templateDir="test/templates/${os}/"
...
done
I could directly iterate the template directories, but I wanted the option to easily sunset formerly supported operating systems.
if [ -f "${path}/tasks/${os}.yml" ]
&& ! containsElement "${role}" "${roleBlacklist[@]}"; then
...
endif
envsubst
)
echo "Role ${role} supports ${os} and will be added to CI/CD."
gitlabRoleCi=$(envsubst '$role'
< "test/templates/${os}/.gitlab-ci.part.yml")
echo "${gitlabRoleCi}" >> ".gitlab-ci-roles.yml"
.gitlab-ci.part.yml templates include
rules:changes
directives:
- if: '$CI_COMMIT_BRANCH == "testing"'
changes:
- roles/.common/tasks/*.yml
- roles/${role}/tasks/main.yml
- roles/${role}/tasks/linux.yml
- roles/${role}/tasks/ubuntu_18.04.yml
- test/templates/ubuntu_18.04/.gitlab-ci.part.yml
- test/templates/ubuntu_18.04/blacklist.yml
- test/templates/ubuntu_18.04/playbook-test.yml
- test/generate-tests.sh
- .gitlab-ci.yml
- Vagrantfile
Generate Tests:
stage: Test Setup
artifacts:
name: gitlab-ci-roles
expire_in: 1 week
paths:
- .gitlab-ci-roles-ubuntu_18.04.yml
- .gitlab-ci-roles-ubuntu_20.04.yml
- .gitlab-ci-roles-ubuntu_22.04.yml
- .gitlab-ci-roles-windows_10.yml
- .gitlab-ci-roles-windows_11.yml
- .vagrant/
{$role}/{$os} Test:
Stage: Test
needs:
- pipeline: $PARENT_PIPELINE_ID
job: Generate Tests
shellcheck
allows us to fail early!
Lint Test Generation:
stage: Lint
tags:
- linux
- shell
- shellcheck
script:
- shellcheck test/generate-tests.sh
Alternatives to shell scripting are becoming more common for more complex pipelines.
vagrant box update
Questions? Suggestions? Rude Insults?
Return to the rest of the presentations.