Search code examples
jenkinsjenkins-pipeline

Jenkins pipeline template


We have several Java projects. Each project has its own delivery pipeline.

All pipelines have the following steps in common (simplified):

  • Build project
  • Release project
  • Deploy to test environment
  • Deploy to production environment

The project pipelines only differ in project specific properties such as service names or the IP addresses of test and production environment.

The questions are: How could we avoid the boilerplate that all projects have in common? Does Jenkins "Pipeline as code" provide something like pipeline templates?

I could imagine that a template would save a lot of redundant code/steps in our project pipelines. Therefore it would be much easier to setup a new project, maintain the pipeline, keep the pipeline in sync...


Solution

  • An approach that works well for us is to put parts of the pipeline (those that all projects have in common) or even the whole pipeline into a Jenkins shared library.

    Example

    The following script (template.groovy) is defined as global variable in a Jenkins shared library. The method creates a new declarative pipeline (it also works for scripted pipeline syntax). All project specific properties are provided via the templateParams map.

    /**
     * Defines a pipeline template (as a sample with one job parameter 
     * that should be common for all pipelines)
     */
    def createMyStandardDeclarativePipeline(Map templateParams) {   
    
        pipeline {
            agent any
            parameters {
                string(name: 'myInput', description: 'Some pipeline parameters')
            }
            stages {
                stage('Stage one') {
                    steps {
                        script {
                            echo "Parameter from template creation: " + templateParams.someParam
                        }
                    }
                }
                stage('Stage two') {
                    steps {
                        script {
                            echo "Job input parameter: " + params.myInput
                        }
                    }
                }
            }
        }
    }
    

    Using this global variable, the following line creates a pipeline from our template:

    template.createMyStandardDeclarativePipeline(someParam: 'myParam')
    

    Conclusion

    This concept makes it easy to define pipeline templates and reuse them in several projects.

    Applied on the example given in the question, you can create a delivery pipeline for a project with a simple one-liner:

    template.createMyStandardDeclarativePipeline(serviceName: 'myService', 
                                            testEnv: '192.168.99.104', 
                                            productionEnv: '192.168.99.105')
    

    Update (30-09-2017): Declaring a pipeline block in a shared library is now officially supported with Declarative Pipelines version 1.2 . See: https://jenkins.io/doc/book/pipeline/shared-libraries/#defining-declarative-pipelines


    Update (06-10-2017): An extended example can now be found here: https://jenkins.io/blog/2017/10/02/pipeline-templates-with-shared-libraries/