Background: As a systems engineer for a company specializing in solutions for remote temperature monitoring using 100% wire-free sensors, my goal was to seamlessly implement DevOps best practices within the organization. Prior to doing so, the developers used their own tools for some part of automation, but it became a problem without standardization. For me, the choice was unquestionable: Jenkins is the way! As teams already actively used Kubernetes for almost all of the workloads, our goal was to combine these two powerful solutions.
Goals: Make developer’s lives easier by automating everything. Standardize and make common pipelines for similar projects.
"Jenkins is simple, reliable and — at the same time — complex. It’s a very flexible tool with the power to integrate with whatever you need. It’s the Swiss Army knife for DevOps."
Solution & Results: We started by deploying Jenkins as a standalone server on AWS outside of the Kubernetes cluster. The configuration was super easy with Ansible and Configuration-as-a-Code plugin. Everything is described in human-readable YAML format, and any changes — if required — can be done very quickly.
The idea was to reuse cluster capacity for workloads. We started using the Kubernetes plugin to connect it to the cluster and run workers as pods there. From this point of view, it was also a cost-effective solution: we would no longer be required to spin-up additional instances for those using Jenkins, which are not always loaded.
To simplify pipeline configurations and increase the flexibility for developers, we decided to use Declarative Pipelines with Multi-branch configurations. This allows us to build and test each commit stored in the git repository of each project. However, this did not completely meet all of our needs. We chose to use the Jenkins Shared Library, which helped us to — how people say — "kill two hares with one shot." By doing so, we were able to:
Significantly extend the functionality of pipelines by creating our own modules
Standardize the solutions (like security scanners) and apply them to multiple projects without re-configuring pipelines.
A shared library also gives us the ability to control the versioning of pipelines and different configurations for each project. Since we have 20+ projects, automation has made a tremendous difference. Jenkins Shared Library is simply the best way to extend the functionality of Jenkins core with pretty good integration. And if we didn’t have the Kubernetes plugin, we would be unable to reuse K8s resources and wasted instances for half of the time. Of course, I would be remiss in not pointing out that Jenkins Configuration-as-a-Code (JCasC) is already an excellent start to automate Jenkins with the simple file.
In general, we received a powerful, controllable CI/CD solution with a shared library as a single source of needed functionality. The solution is flexible in configuration and easy to use.
My mission to automate DevOps paid off. We now have:
a Jenkins Shared Library as a standardized solution for multiple projects
simplified development processes for different teams
flexible and easy to use declarative pipelines for everybody