Pipeline - Create a Parameterized Pipeline using Template

Article ID:230611087
3 minute readKnowledge base

Issue

  • I want to create Parameterized Pipeline jobs using Templates

Environment

Resolution

In this article, we are going to explain how to create Parameterized Pipeline Jobs using CloudBees Pipeline Templates Plugin.

A Pipeline template is a Job Template that uses the Groovy template for Pipeline transformer. This transformer is divided in 2 sections:

  • General job definition: The Groovy template that describe the XML configuration of the pipeline job (i.e. job description, actions, triggers and properties).

  • Pipeline definition: The Groovy script defining the pipeline

example pipeline template
Each section can be configured with Groovy Sandboxing. See Script Security for more details.

General Job Definition

Build Parameters need to be defined in the General Job Definition. That is how Jenkins knows that the build is parameterized. The job definition should look like this:

<flow-definition>
<actions/>
<description/>
<keepDependencies>false</keepDependencies>
<properties>
    <hudson.model.ParametersDefinitionProperty>
        <parameterDefinitions>
            ...
            //Add parameters here
            ...
        </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
</properties>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition">
    <sandbox>false</sandbox>
</definition>
<triggers/>
</flow-definition>

Pipeline Script Definition

The parameters values are handled in the Pipeline script. The following snippets gives an idea on how to use parameters in Pipeline Jobs using CloudBees Templates using different methods:

When using sh step, the Double quotes are important. Otherwise the parameter value cannot be resolved. NOTE: We recommend any method that does not requires approval from an Jenkins Administrator
  • Parameters are accessible as Groovy variables of the same name.

      node {
              //Dislay the parameter value of the parameter named "myparam"
              println myparam
              sh "echo '${myparam}'"
      }
  • Since version 2.18 of the Pipeline Groovy, Parameters are accessible via the groovy variable params in the pipeline script:

      node {
              //Dislay the parameter value of the parameter named "myparam"
              println "${params.myparam}"
    
              //Dislay the name/value of all parameters
              for(entry in params) {
                  println entry.key
                  println entry.value
              }
      }
  • Parameters values are directly accessible by Parameter key using the methods getProperty and env.getEnvironment() (This requires script approval from an Administrator):

      node {
              /**
                * Use getBinding/getProperty:
                * -Check if a parameter exists by key (returns true even though the value is empty '')
                * -Display a build parameter by key
               *
                * With older versions of Pipeline: `getBinding().hasVariable("myparam")`
               */
              if (env.getEnvironment().containsKey('myparam')) {
                  println getProperty("myparam")
              }
      }
  • Parameters are accessible via the currentBuild variable (This requires script approval from an Administrator):

      import hudson.model.ParameterValue;
      import hudson.model.ParametersAction;
      node {
              /**
                * Use currentBuild to:
                * -Retrieve the build parameters
                * -Display all the build parameters
               */
              def myBuildParams = currentBuild.rawBuild.getAction(ParametersAction.class)
              for(ParameterValue p in myBuildParams) {
                  println p.name
                  println p.value
              }
      }
  • For Template Attribute of type Heterogeneous component of ParameterDefinition, parameters values are accessible via the getProperty:

      import hudson.model.ParameterValue;
      import hudson.model.ParametersAction;
      node {
    
              //Display the value of a parameter defined as an attribute
              println myParam.name
              //Display the defaultValue of a parameter defined as an attribute
              println myParam.defaultValue
              //Display the value of a parameter defined as an attribute
              println getProperty(myParam.name)
      }

Control

Three type of users comes into account when creating templates for parameterized jobs:

  • The User that defines the Template

  • The User that creates the Job based on the template

  • The User that triggers the Job

In most cases, there are different solutions to one requirement. Whether one solution or another is suitable often depends on how much control you want to give to the users that create the Jobs.

Examples

Example: Simple Parameterized Pipeline

In this example:

  • We need to create a bunch of pipeline jobs that deploy an application to a specific environment

  • We want the users that build the job to be able to choose the environment

1) General job definition:

<flow-definition>
<actions/>
<description/>
<keepDependencies>false</keepDependencies>
<properties>
    <hudson.model.ParametersDefinitionProperty>
        <parameterDefinitions>
            <hudson.model.ChoiceParameterDefinition>
                <name>DeployEnvironment</name>
                <description>Choose the Deploy Environment</description>
                <choices class="java.util.Arrays\$ArrayList">
                    <a class="string-array">
                        <string>DEV</string>
                        <string>TEST</string>
                        <string>QA</string>
                        <string>PROD</string>
                    </a>
                </choices>
            </hudson.model.ChoiceParameterDefinition>
        </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
</properties>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition">
    <sandbox>false</sandbox>
</definition>
<triggers/>
</flow-definition>

2) Pipeline definition:

node {

  stage 'Deploy'
  sh "echo 'Deploying to ${DeployEnvironment.toLowerCase()}.example.com'"

}

3) Build the Job:

Example: Parameterized Pipeline with Parameters as Template Attributes

In this example:

  • We need to create a bunch of pipeline jobs that deploy an application to a specific environment

  • We want the users that build the job to be able to choose the environment

  • We want the users that create the job to provide the location of each environment

1) Auxiliary for Environment:

We create an Auxiliary Template that represents an Environment:

  • The name of the Environment (DEV, TEST, ..) which will also be the parameter name

  • The hostname

2) Template Attribute:

3) General job definition:

<flow-definition>
<actions/>
<description/>
<keepDependencies>false</keepDependencies>
<properties>
    <% if(deployEnvironments) { %>
    <hudson.model.ParametersDefinitionProperty>
        <parameterDefinitions>
            <hudson.model.ChoiceParameterDefinition>
                <name>DeployEnvironment</name>
                <description>Choose the Deploy Environment</description>
                <choices class="java.util.Arrays\$ArrayList">
                    <a class="string-array">
                    <% deployEnvironments.each { %>
                        <string>${it.name}</string>
                    <% } %>
                    </a>
                </choices>
            </hudson.model.ChoiceParameterDefinition>
        </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
    <% } %>
</properties>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition">
    <sandbox>false</sandbox>
</definition>
<triggers/>
</flow-definition>

4) Pipeline definition:

//The environment location is configured in the job
def deployToMap = [:]
deployEnvironments.each {
    deployToMap.put(it.name, it.hostname)
}

node {
  stage 'Deploy'
  println "Deploying to ${deployToMap[DeployEnvironment]}"
}

5) Create/Configure the Job:

We can provide any environment

6) Build the job: