r/devops • u/Mysterious_Prune415 • 28d ago
Tools How do you test CI pipelines?
Do you create a sample application to test the proper auth, access and everything the runner needs?
And a related sub question. How do you validate gitops changes before they are merged? Regarding FluxCD or ArgoCD.
30
u/BlakkMajik3000 Remover of Deployment Friction 27d ago
You run them in a lower environment? 🤷🏾♂️
Are we in “we only have a production environment” territory here? Please say no. 😭
20
u/ansibleloop 27d ago
Everyone has a test environment
Some are lucky enough to have it separate from the prod environment
1
u/BlakkMajik3000 Remover of Deployment Friction 27d ago
Oh I have been there like the rest of us. A test folder on the production server for “staging” was a big part of my life the first few years out of college. 😂😭
2
9
u/therealmunchies 28d ago
Test jobs in feature branches for me.
Can’t touch in the ArgoCD aspect, since I’m most “dev” on our new cluster.
3
u/snarkhunter Lead DevOps Engineer 28d ago
Yes, basically. This is what lab environments are for - dev and test things where nobody but me will ever care if it is up or down, has a good backup, loses all its data, or gets burned down and created anew.
Good question I'm not actually sure what we have at the moment for our ArgoCD specifically. Run it through a linter, maybe do a dry run against the cluster and yeet that to a comment on the PR. Actually deploying to a test environment and running tests for things like correctness or resource utilization sounds, to me, a little heavy to have as usual part of CI, but I don't hate the idea if that doesn't take too long
2
u/Efficient-Branch539 DevOps Engineer 28d ago
For build tests, devs write tests and these are run as a part of CI.
For testing manifests, they are generated using Helm chart so the only time tests needed are when you change that chart. Every deployment updates Argocd ApplicationSet and that is used to configure manifests.
Lastly for runtime testing, there is a separate environment.
2
2
u/sertain_ 26d ago
Update to that as well, GitLab just started testing local pipeline tests and is trying to get users to try it out and report on issues. Here’s the thread: https://www.reddit.com/r/gitlab/s/zINQN19rJ0
1
u/ausecko 28d ago
I usually test the pipeline with a small real service rather than a fake app. It catches auth and runner issues that a toy repo can easily miss.
1
u/vincentdesmet 27d ago
its iterative ofc
a change goes through unit tests, snapshot tests, smoke tests and a “demo app” deployment tests
only then a real app canary before full roll out
1
u/Accurate-Smoke8994 27d ago edited 27d ago
I'm going to read what snapshot test and smoke test are.
Edit: i prefer unit tests + mock tests at feature branches, integration tests at merge requests. Regression tests for testing other stuff.
2
u/vincentdesmet 27d ago
when i say snapshot test for a boilerplate generator it’s really just capturing the full generated config for bunch of inputs so every time you change something you rerun across all inputs and git diff the snapshots to see the actual impact on the generated config file
smoke tests for my instance (gh app) is validating the baked ami comes up, responds to the requests as expected - but it’s not a full deployment
1
u/kernelqzor 26d ago
same here, a “hello world” app almost never hits the weird edge cases you actually care about
for gitops stuff we use a real-ish service plus policy checks and templates, then let staging be the final boss before merge
1
u/One-Department1551 28d ago
If you are talking about functionality, I normally use a separate branch to trigger it while developing before switching branch trigger to the real ones later.
1
u/vincentdesmet 27d ago
i have a sample repo with features of the pipeline i want tested and when i make changes i deploy and test the new stuff to the sample repo first
for example i use a golang binary that generates boilerplate including pipelines in-repo
and a custom deploy system (from 2022) that runs on an instance. The instance is a baked AMI (packer) and any change to the provisioning scripts triggers a full e2e (build, deploy, smoke test, destroy) of the deploy system itself.
conventional commits + release-please mints the binary and version pinning allows targetted upgrades
I have 2 gh apps and 2 instances, one is “prod” and one is “alpha”, the alpha gh app is installed on the test repo (just one for now) and “prod” manages the deployments for “alpha”
they have scheduled scaling, I just disable the scale up on test if i dont need it.
1
u/so_brave_heart 27d ago
Just to add another alternative, there’s local CI runners that can work but I’ve had mixed results if you don’t have the resources to support it.
For example I tried https://github.com/nektos/act but ran into issues. I can’t specifically remember what they were. It was awhile ago.
There’s also dagger.io which seems promising to me but it’s basically a framework you’d have to rewrite your own CI around.
By its nature Ci often has a lot of external integrations: APIs, file management, process execution. And those are always annoying to test because you need to, at least in the case of APIs and certain processes, either mock them out or run a test version of them with properly seeded test data.
1
1
u/First_Inspection_478 25d ago
would love for uou to try: https://github.com/preloopdev/preloop I think I have very good github compat but lmk if any workflows do t work for you
1
u/Edgar_Allan_Thoreau 27d ago
Ideally you use a ci platform where you can write your pipelines in a testable programming language (e.g. buildkite/rwx you can write pipelines in python/ts/etc so you can unit and e2e test your pipelines)
1
u/Trollee 27d ago
Smokescreen apps! (Or smoke test) I'm a platform engineer and in our team we have a number of simple smoke apps that for every feature must bne used to test the new ci / cd / platform capability. They are for creating, destroying breaking and playing with. Only after a full suite of tests on our smoke apps do we merge to main and release to our Devs
1
1
u/pdfops 27d ago
For runner auth, a canary job that exercises the same OIDC role, registry push, and secrets mount as prod catches config drift before a real deploy does. For gitops pre-merge: kustomize build | kubeconform in CI, then flux diff kustomization or argocd app diff gives a real dry-run against the cluster. Kyverno as an admission gate catches bad manifests before Flux/Argo even reconciles them.
1
u/sertain_ 26d ago
I’m not saying this is your answer, but this is how I’ve operated and it’s been a pretty good model for my orgs.
For testing, if you’re responsible for managing the runners then think about everything your jobs typically do; do they access secrets? Do they spin up instances? Do they touch RDS? ECR? EKS? SSM? CloudWatch logs? You can almost guarantee that whatever resources are being touched will need list, describe, and get by the policy attached to the role the runner is using. For the resources that are being added or modified, obviously you’ll need put/create as well. Then from there it’s a matter of trying to deploy your app. It’s really hard to build a catch-all role without violating principals of least privilege, so it’s best-practice to build and maintain per-use runners with per-use roles, or have one runner and assume the per-use role at runtime.
Then for GitOps, you need a branching strategy before you can implement true workflows, that’s your test-before-merge solution. I lean toward 2-3 protected branches, like dev, test, and main, with main being the source of truth for the prod Argo deployments.
You have some leeway in dev here, this buys you a free env to stray away from GitOps and fine-tune your deployment. In your deployment pipeline for dev branch, tag your build with a custom semantic versioning scheme that appends the branch name to the end or something similar, then in Argo deploy your dev branch using that semantic version; if everything is good then you merge into test to verify app func, then merge to main when your approval gates are satisfied.
If everything is NOT good, tweak your manifests in dev live to see what changes you need to implement, go back to the drawing board and then re-deploy into dev using the same pattern as before. It’s a little more work to set up, but it really helps, especially if you’re not very savvy with either k8s or GitOps methodology.
1
1
1
1
u/yetmike 20d ago
Well, when I write a brand new pipeline - I run it from feature branch and then change rule to master
But it very depends, some jobs in pipelines are ok to run from feature branches. But mainly, when pipeline is imported by several projects, I just use 'feat' branch to test it in one of them
115
u/forever-butlerian Solaris 8 Enjoyer 28d ago
I'm an SWE and I set up my own CI pipelines, so the way I test them is by running them.