This is the last post in the series on implementing the Deployment Pipeline pattern in DevOps. In previous articles, I explained what a Deployment Pipeline is, the benefits of using one, how to design a Deployment Pipeline for DevOps and lastly how to use Jenkins to implement this pipeline.
I would now like to take this a step further and explain how, from a practical point of view, to implement your Deployment Pipeline using Jenkins. The intention here is not to provide a manual or end-to-end guide on how to implement the pipeline, but rather to pave the way for that implementation. As Laozi says: “A journey of a thousand miles begins with a single step.”
The objective of this article is to build a skeleton for the Deployment Pipeline that will serve as a guide for its actual implementation. The specific implementation of each step of the pipeline will be unique to each project and will depend on the technology used. However, this article will provide a framework or working template.
Pipeline As Code with Jenkins
In our last post, we mentioned that we would be using Jenkins with certain plug-ins. Specifically, we will use the Blue Ocean plug-in to provide a visualisation of the pipeline.
In previous versions of Jenkins, we had to build our pipeline using the web interface, which involved creating Jobs manually and required additional effort in managing the pipeline.
The current trend is to treat all elements of the software development life cycle “as Code”, and defining the pipeline is no exception to this.
The main advantage of this is that we can store the definition of our pipeline in our version control server and treat it the same as any other code element (in terms of testing, quality, revisions, etc.).
To achieve this, Jenkins allows the pipeline to be implemented using a Jenkinsfile written in a specific scripting language.
Below is a very basic example of a Jenkinsfile that we can use to build our pipeline, and the one I used to define the pipeline in my previous articles:
This code is not complete, but it does illustrate how the pipeline is built. If you look at the code, you can see how each stage is defined and, within each stage, the steps executed.
The steps performed within each stage will be specific to each project and the technology used.
For example, in the Commit stage, the code could be compiled using Maven, Gradle or another build tool, unit testing could be run using an xUnit framework and code analysis could be performed using Kiuwan or Sonarqube.
Deployments to the different environments could be managed using Ansible or any other configuration management tool.
Finally, for acceptance testing, we could use Gherkin in conjunction with Cucumber and Selenium.
In short, what this pipeline provides, is a skeleton that supports the execution and visualisation of the specific value delivery processes, but the actual work must be performed in each of these steps.
This may seem complicated, but Jenkins incorporates a code generator for defining these steps based on what we want to do, which makes it much easier to use.
Before closing, I would like to set out some considerations for implementing a Deployment Pipeline in this way:
- It is important to start the pipeline in a red (failed) state, and to move forward step by step, always checking that we are not promoting something to production that we do not want. It is advisable to add a confirmation question before each deployment to prevent anything from moving uncontrolled into production. This is as simple as including the following statement in our Jenkinsfile:
- As I mentioned in my last post, once the pipeline has been set up, it is the job of the entire team to keep the pipeline in the correct state to ensure we have a direct route from delivery to production. If our pipeline spends too much time in a failed state, we are doing something wrong.
- DevSecOps. One definition of DevSecOps that I especially like is the one that states that DevSecOps is being able to take any element of the pipeline and demonstrate that security has been addressed at that point. Therefore, when implementing our pipeline, we must not forget to incorporate security mechanisms that provide assurances that the code we are delivering is secure.
- The template described in this article can be used for both traditional applications and container-based applications and architectures – simply configure the steps in each stage according to the selected technology.
In this post, I have briefly described how we can make use of the Pipeline as Code feature within Jenkins and benefit from the advantages it provides. I hope it has encouraged you to use Pipeline as Code.
If you have any further questions, please feel free to contact us without obligation.
Emiliano Sutil is a Project Manager at Xeridia